CVE-2022-39309: Exposure of Resource to Wrong Sphere (CWE-668)
value: GoCD is a continuous delivery server. GoCD helps you automate and streamline the build-test-release cycle for continuous delivery of your product. GoCD versions prior to 21.1.0 leak the symmetric key used to encrypt/decrypt any secure variables/secrets in GoCD configuration to authenticated agents. A malicious/compromised agent may then expose that key from memory, and potentially allow an attacker the ability to decrypt secrets intended for other agents/environments if they also are able to obtain access to encrypted configuration values from the GoCD server. This issue is fixed in GoCD version 21.1.0. There are currently no known workarounds.
CWE description: The product exposes a resource to the wrong control sphere, providing unintended actors with inappropriate access to the resource.
CVSS v3 base score: 6.5
Published: 2022-10-14T20:15Z
Repository: https://github.com/gocd/gocd
Language: Java
Files changed: api/api-server-maintenance-mode-v1/src/test/groovy/com/thoughtworks/go/apiv1/servermaintenancemode/representers/MaintenanceModeInfoRepresenterTest.groovy, common/src/test/java/com/thoughtworks/go/config/materials/perforce/P4MaterialTest.java, common/src/test/java/com/thoughtworks/go/config/materials/tfs/TfsMaterialTest.java, common/src/test/java/com/thoughtworks/go/domain/materials/DummyMaterial.java, common/src/test/java/com/thoughtworks/go/domain/materials/svn/SvnMaterialTest.java, common/src/test/java/com/thoughtworks/go/server/service/MagicalMaterialAndMaterialConfigConversionTest.java, domain/src/main/java/com/thoughtworks/go/config/materials/Materials.java, domain/src/main/java/com/thoughtworks/go/config/materials/ScmMaterial.java, domain/src/main/java/com/thoughtworks/go/config/materials/git/GitMaterial.java, domain/src/main/java/com/thoughtworks/go/config/materials/mercurial/HgMaterial.java, domain/src/main/java/com/thoughtworks/go/config/materials/perforce/P4Material.java, domain/src/main/java/com/thoughtworks/go/config/materials/svn/SvnMaterial.java, domain/src/main/java/com/thoughtworks/go/config/materials/tfs/TfsMaterial.java, domain/src/main/java/com/thoughtworks/go/domain/materials/TestingMaterial.java, domain/src/main/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialInstance.java, domain/src/test/java/com/thoughtworks/go/helper/MaterialsMother.java, server/src/test-fast/java/com/thoughtworks/go/server/service/MaterialServiceTest.java, server/src/test-integration/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialPersistenceTest.java
Commit date: 2020-12-10 11:27:35 +0530
Commit message: SCMMaterial changes #000

* SCMMaterial unlike SCMMaterialConfig objects are used for polling,
  they do not need to encrypt the password. Hence removing the
  encryptedPassword attribute.

Diff: diff --git a/api/api-server-maintenance-mode-v1/src/test/groovy/com/thoughtworks/go/apiv1/servermaintenancemode/representers/MaintenanceModeInfoRepresenterTest.groovy b/api/api-server-maintenance-mode-v1/src/test/groovy/com/thoughtworks/go/apiv1/servermaintenancemode/representers/MaintenanceModeInfoRepresenterTest.groovy
index 3d8e153fb97..02572157360 100644
--- a/api/api-server-maintenance-mode-v1/src/test/groovy/com/thoughtworks/go/apiv1/servermaintenancemode/representers/MaintenanceModeInfoRepresenterTest.groovy
+++ b/api/api-server-maintenance-mode-v1/src/test/groovy/com/thoughtworks/go/apiv1/servermaintenancemode/representers/MaintenanceModeInfoRepresenterTest.groovy
@@ -132,11 +132,11 @@ class MaintenanceModeInfoRepresenterTest {
                 "invert_filter"     : false,
                 "name"              : null,
                 "auto_update"       : true,
                 "check_externals"   : true,
                 "username"          : "user",
-                "encrypted_password": svnMaterial.encryptedPassword
+                "encrypted_password": svnMaterial.config().getEncryptedPassword()
               ],
               "mdu_start_time": "1970-01-01T08:20:00Z"
             ]
           ],
           building_jobs                : [
diff --git a/common/src/test/java/com/thoughtworks/go/config/materials/perforce/P4MaterialTest.java b/common/src/test/java/com/thoughtworks/go/config/materials/perforce/P4MaterialTest.java
index bbacc5758bb..88702625b7a 100644
--- a/common/src/test/java/com/thoughtworks/go/config/materials/perforce/P4MaterialTest.java
+++ b/common/src/test/java/com/thoughtworks/go/config/materials/perforce/P4MaterialTest.java
@@ -95,35 +95,10 @@ public class P4MaterialTest extends P4MaterialTestBase {
         p4.setUsername("user");
         p4.setPassword("loser");
         assertThat(p4.toString()).doesNotContain("loser");
     }
 
-    @Test
-    void shouldEncryptP4Password() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");
-
-        P4Material p4Material = new P4Material("example.com:1818", "view", mockGoCipher);
-        p4Material.setPassword("password");
-        p4Material.ensureEncrypted();
-
-        assertThat(p4Material.getEncryptedPassword()).isEqualTo("encrypted");
-        assertThat(p4Material.getPassword()).isNull();
-    }
-
-    @Test
-    void shouldDecryptP4Password() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");
-
-        P4Material p4Material = new P4Material("example.com:1818", "view", mockGoCipher);
-        ReflectionUtil.setField(p4Material, "encryptedPassword", "encrypted");
-        p4Material.getPassword();
-
-        assertThat(p4Material.getPassword()).isEqualTo("password");
-    }
-
     @Test
     void shouldReturnEqualsEvenIfPasswordsAreDifferent() throws Exception {
         P4Material material = MaterialsMother.p4Material();
         material.setPassword("password");
 
diff --git a/common/src/test/java/com/thoughtworks/go/config/materials/tfs/TfsMaterialTest.java b/common/src/test/java/com/thoughtworks/go/config/materials/tfs/TfsMaterialTest.java
index 6afa1fe52c4..20a0b5f7fc6 100644
--- a/common/src/test/java/com/thoughtworks/go/config/materials/tfs/TfsMaterialTest.java
+++ b/common/src/test/java/com/thoughtworks/go/config/materials/tfs/TfsMaterialTest.java
@@ -66,12 +66,12 @@ public class TfsMaterialTest {
     private final String TFS_SECOND_PROJECT = "$/second_project";
 
     @BeforeEach
     void setUp() {
         GoCipher goCipher = mock(GoCipher.class);
-        tfsMaterialFirstCollectionFirstProject = new TfsMaterial(goCipher, new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_FIRST_PROJECT);
-        tfsMaterialFirstCollectionSecondProject = new TfsMaterial(goCipher, new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_SECOND_PROJECT);
+        tfsMaterialFirstCollectionFirstProject = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_FIRST_PROJECT);
+        tfsMaterialFirstCollectionSecondProject = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_SECOND_PROJECT);
     }
 
     @Test
     void shouldShowLatestModification() throws IOException {
         File dir = temporaryFolder.newFolder("tfs-dir");
@@ -102,115 +102,63 @@ public class TfsMaterialTest {
         verify(tfsCommand).modificationsSince(dir, new StringRevision("5"));
     }
 
     @Test
     void shouldInjectAllRelevantAttributesInSqlCriteriaMap() {
-        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
+        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
         assertThat(tfsMaterial.getSqlCriteria()).isEqualTo(m(
                 SQL_CRITERIA_TYPE, (Object) "TfsMaterial",
                 "url", "my-url",
                 "username", "loser",
                 "projectPath", "/dev/null", "domain", DOMAIN));
     }
 
     @Test
     void shouldInjectAllRelevantAttributesInAttributeMap() {
-        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
+        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
         assertThat(tfsMaterial.getAttributesForXml()).isEqualTo(m(
                 AbstractMaterial.SQL_CRITERIA_TYPE, (Object) "TfsMaterial",
                 "url", "my-url",
                 "username", "loser",
                 "projectPath", "/dev/null", "domain", DOMAIN));
     }
 
     @Test
     void shouldReturnUrlForCommandLine_asUrl_IfSet() {
-        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
+        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
         );
         assertThat(tfsMaterial.getUrl()).isEqualTo("http://foo:bar@my-url.com");
 
-        tfsMaterial = new TfsMaterial(new GoCipher(), null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
+        tfsMaterial = new TfsMaterial(null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
         assertThat(tfsMaterial.getUrl()).isNull();
     }
 
     @Test
     void shouldReturnUrlForCommandLine_asLocation_IfSet() {
-        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
+        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
         );
         assertThat(tfsMaterial.getLocation()).isEqualTo("http://foo:******@my-url.com");
 
-        tfsMaterial = new TfsMaterial(new GoCipher(), null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
+        tfsMaterial = new TfsMaterial(null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
         assertThat(tfsMaterial.getLocation()).isNull();
     }
 
-    @Test
-    void shouldEncryptTfsPasswordAndMarkPasswordAsNull() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");
-
-        TfsMaterial tfsMaterial = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
-        tfsMaterial.ensureEncrypted();
-
-        assertThat(tfsMaterial.getPassword()).isNull();
-        assertThat(tfsMaterial.getEncryptedPassword()).isEqualTo("encrypted");
-    }
-
-    @Test
-    void shouldDecryptTfsPassword() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");
-
-        TfsMaterial tfsMaterial = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, null, "");
-
-        ReflectionUtil.setField(tfsMaterial, "encryptedPassword", "encrypted");
-
-        tfsMaterial.ensureEncrypted();
-        assertThat(tfsMaterial.getPassword()).isEqualTo("password");
-    }
-
     @Test
     void shouldNotDecryptPasswordIfPasswordIsNotNull() throws Exception {
         GoCipher mockGoCipher = mock(GoCipher.class);
         when(mockGoCipher.encrypt("password")).thenReturn("encrypted");
         when(mockGoCipher.decrypt("encrypted")).thenReturn("password");
 
-        TfsMaterial material = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
+        TfsMaterial material = new TfsMaterial(new UrlArgument("/foo"), "username", DOMAIN, "password", "");
         material.ensureEncrypted();
         when(mockGoCipher.encrypt("new_password")).thenReturn("new_encrypted");
         material.setPassword("new_password");
         when(mockGoCipher.decrypt("new_encrypted")).thenReturn("new_password");
 
         assertThat(material.getPassword()).isEqualTo("new_password");
     }
 
-    @Test
-    void shouldErrorOutIfDecryptionFails() throws CryptoException {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        String fakeCipherText = "fake cipher text";
-        when(mockGoCipher.decrypt(fakeCipherText)).thenThrow(new CryptoException("exception"));
-        TfsMaterial material = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
-        ReflectionUtil.setField(material, "encryptedPassword", fakeCipherText);
-        try {
-            material.getPassword();
-            fail("Should have thrown up");
-        } catch (Exception e) {
-            assertThat(e.getMessage()).isEqualTo("Could not decrypt the password to get the real password");
-        }
-    }
-
-    @Test
-    void shouldErrorOutIfEncryptionFails() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.encrypt("password")).thenThrow(new CryptoException("exception"));
-        try {
-            new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
-            fail("Should have thrown up");
-        } catch (Exception e) {
-            assertThat(e.getMessage()).isEqualTo("Password encryption failed. Please verify your cipher key.");
-        }
-    }
-
     @Test
     void shouldBePasswordAware() {
         assertThat(PasswordAwareMaterial.class.isAssignableFrom(TfsMaterial.class)).isTrue();
     }
 
@@ -235,27 +183,27 @@ public class TfsMaterialTest {
         verify(tfsCommand, times(1)).checkConnection();
     }
 
     @Test
     void shouldGetLongDescriptionForMaterial() {
-        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
+        TfsMaterial material = new TfsMaterial(new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
         assertThat(material.getLongDescription()).isEqualTo("URL: http://url/, Username: user, Domain: domain, ProjectPath: $project/path/");
     }
 
     @Test
     void shouldCopyOverPasswordWhenConvertingToConfig() throws Exception {
-        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
+        TfsMaterial material = new TfsMaterial(new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
 
         TfsMaterialConfig config = (TfsMaterialConfig) material.config();
 
         assertThat(config.getPassword()).isEqualTo("password");
         assertThat(config.getEncryptedPassword()).isNotNull();
     }
 
     @Test
     void shouldGetAttributesWithSecureFields() {
-        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
+        TfsMaterial material = new TfsMaterial(new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
         Map<String, Object> attributes = material.getAttributes(true);
 
         assertThat(attributes.get("type")).isEqualTo("tfs");
         Map<String, Object> configuration = (Map<String, Object>) attributes.get("tfs-configuration");
         assertThat(configuration.get("url")).isEqualTo("http://username:password@tfsrepo.com");
@@ -265,11 +213,11 @@ public class TfsMaterialTest {
         assertThat(configuration.get("project-path")).isEqualTo("$project/path/");
     }
 
     @Test
     void shouldGetAttributesWithoutSecureFields() {
-        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
+        TfsMaterial material = new TfsMaterial(new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
         Map<String, Object> attributes = material.getAttributes(false);
 
         assertThat(attributes.get("type")).isEqualTo("tfs");
         Map<String, Object> configuration = (Map<String, Object>) attributes.get("tfs-configuration");
         assertThat(configuration.get("url")).isEqualTo("http://username:******@tfsrepo.com");
@@ -281,27 +229,27 @@ public class TfsMaterialTest {
 
     @Nested
     class passwordForCommandLine {
         @Test
         void shouldReturnPasswordAsConfigured_IfNotDefinedAsSecretParam() {
-            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "badger", null);
+            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "badger", null);
 
             assertThat(tfsMaterial.passwordForCommandLine()).isEqualTo("badger");
         }
 
         @Test
         void shouldReturnAResolvedPassword_IfPasswordDefinedAsSecretParam() {
-            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
+            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
 
             tfsMaterial.getSecretParams().findFirst("lookup_pass").ifPresent(secretParam -> secretParam.setValue("resolved_password"));
 
             assertThat(tfsMaterial.passwordForCommandLine()).isEqualTo("resolved_password");
         }
 
         @Test
         void shouldErrorOutWhenCalledOnAUnResolvedSecretParam_IfPasswordDefinedAsSecretParam() {
-            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
+            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
 
             assertThatCode(tfsMaterial::passwordForCommandLine)
                     .isInstanceOf(UnresolvedSecretParamException.class)
                     .hasMessageContaining("SecretParam 'lookup_pass' is used before it is resolved.");
         }
@@ -309,11 +257,11 @@ public class TfsMaterialTest {
 
     @Nested
     class setPassword {
         @Test
         void shouldParsePasswordString_IfDefinedAsSecretParam() {
-            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
+            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
 
             assertThat(tfsMaterial.getSecretParams())
                     .hasSize(1)
                     .contains(new SecretParam("secret_config_id", "lookup_pass"));
         }
@@ -337,11 +285,11 @@ public class TfsMaterialTest {
         assertThat(ctx.getProperty(TfsMaterial.GO_MATERIAL_DOMAIN)).isEqualTo(DOMAIN);
     }
 
     @Test
     void shouldOnlyPopulateDomainEnvVarIfPresent() {
-        TfsMaterial material = new TfsMaterial(mock(GoCipher.class), new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, "", PASSWORD, TFS_FIRST_PROJECT);
+        TfsMaterial material = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, "", PASSWORD, TFS_FIRST_PROJECT);
         EnvironmentVariableContext ctx = new EnvironmentVariableContext();
         final ArrayList<Modification> modifications = new ArrayList<>();
 
         modifications.add(new Modification("user2", "comment2", "email2", new Date(), "24"));
         modifications.add(new Modification("user1", "comment1", "email1", new Date(), "23"));
diff --git a/common/src/test/java/com/thoughtworks/go/domain/materials/DummyMaterial.java b/common/src/test/java/com/thoughtworks/go/domain/materials/DummyMaterial.java
index cfbd1ad3a9a..40447f503dc 100644
--- a/common/src/test/java/com/thoughtworks/go/domain/materials/DummyMaterial.java
+++ b/common/src/test/java/com/thoughtworks/go/domain/materials/DummyMaterial.java
@@ -16,11 +16,10 @@
 package com.thoughtworks.go.domain.materials;
 
 import com.thoughtworks.go.config.materials.ScmMaterial;
 import com.thoughtworks.go.config.materials.SubprocessExecutionContext;
 import com.thoughtworks.go.domain.MaterialInstance;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.command.ConsoleOutputStreamConsumer;
 import com.thoughtworks.go.util.command.UrlArgument;
 
 import java.io.File;
 import java.util.List;
@@ -33,11 +32,11 @@ import java.util.Map;
  */
 public final class DummyMaterial extends ScmMaterial {
     private String url;
 
     public DummyMaterial() {
-        super("DummyMaterial", new GoCipher());
+        super("DummyMaterial");
     }
 
     @Override
     public String getUrl() {
         return url;
diff --git a/common/src/test/java/com/thoughtworks/go/domain/materials/svn/SvnMaterialTest.java b/common/src/test/java/com/thoughtworks/go/domain/materials/svn/SvnMaterialTest.java
index e0b87ec4382..9346d4f7e56 100644
--- a/common/src/test/java/com/thoughtworks/go/domain/materials/svn/SvnMaterialTest.java
+++ b/common/src/test/java/com/thoughtworks/go/domain/materials/svn/SvnMaterialTest.java
@@ -326,34 +326,10 @@ public class SvnMaterialTest {
         SvnMaterial svnZooser = new SvnMaterial("foo.com", "loser", "zooser", true);
         assertThat(svnBoozer.hashCode()).isEqualTo(svnZooser.hashCode());
         assertThat(svnBoozer).isEqualTo(svnZooser);
     }
 
-    @Test
-    void shouldEncryptSvnPasswordAndMarkPasswordAsNull() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");
-
-        SvnMaterial material = new SvnMaterial("/foo", "username", "password", false, mockGoCipher);
-        material.ensureEncrypted();
-
-        assertThat(material.getPassword()).isNull();
-        assertThat(material.getEncryptedPassword()).isEqualTo("encrypted");
-    }
-
-    @Test
-    void shouldDecryptSvnPassword() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");
-
-        SvnMaterial material = new SvnMaterial("/foo", "username", null, false, mockGoCipher);
-        ReflectionUtil.setField(material, "encryptedPassword", "encrypted");
-
-        material.ensureEncrypted();
-        assertThat(material.getPassword()).isEqualTo("password");
-    }
-
     @Test
     void shouldNotDecryptSvnPasswordIfPasswordIsNotNull() throws Exception {
         GoCipher mockGoCipher = mock(GoCipher.class);
         when(mockGoCipher.encrypt("password")).thenReturn("encrypted");
         when(mockGoCipher.decrypt("encrypted")).thenReturn("password");
@@ -365,37 +341,10 @@ public class SvnMaterialTest {
         when(mockGoCipher.decrypt("new_encrypted")).thenReturn("new_password");
 
         assertThat(material.getPassword()).isEqualTo("new_password");
     }
 
-    @Test
-    void shouldErrorOutIfDecryptionFails() throws CryptoException {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        String fakeCipherText = "fake cipher text";
-        when(mockGoCipher.decrypt(fakeCipherText)).thenThrow(new CryptoException("exception"));
-        SvnMaterial material = new SvnMaterial("/foo", "username", null, false, mockGoCipher);
-        ReflectionUtil.setField(material, "encryptedPassword", fakeCipherText);
-        try {
-            material.getPassword();
-            fail("Should have thrown up");
-        } catch (Exception e) {
-            assertThat(e.getMessage()).isEqualTo("Could not decrypt the password to get the real password");
-        }
-    }
-
-    @Test
-    void shouldErrorOutIfEncryptionFails() throws Exception {
-        GoCipher mockGoCipher = mock(GoCipher.class);
-        when(mockGoCipher.encrypt("password")).thenThrow(new CryptoException("exception"));
-        try {
-            new SvnMaterial("/foo", "username", "password", false, mockGoCipher);
-            fail("Should have thrown up");
-        } catch (Exception e) {
-            assertThat(e.getMessage()).isEqualTo("Password encryption failed. Please verify your cipher key.");
-        }
-    }
-
     @Test
     void shouldGetLongDescriptionForMaterial() {
         SvnMaterial material = new SvnMaterial("http://url/", "user", "password", true, "folder");
         assertThat(material.getLongDescription()).isEqualTo("URL: http://url/, Username: user, CheckExternals: true");
     }
diff --git a/common/src/test/java/com/thoughtworks/go/server/service/MagicalMaterialAndMaterialConfigConversionTest.java b/common/src/test/java/com/thoughtworks/go/server/service/MagicalMaterialAndMaterialConfigConversionTest.java
index 50f8a694a1f..f460b6c110f 100644
--- a/common/src/test/java/com/thoughtworks/go/server/service/MagicalMaterialAndMaterialConfigConversionTest.java
+++ b/common/src/test/java/com/thoughtworks/go/server/service/MagicalMaterialAndMaterialConfigConversionTest.java
@@ -178,12 +178,11 @@ public class MagicalMaterialAndMaterialConfigConversionTest {
     }
 
     private void assertPasswordIsCorrect(Material material) {
         if (material instanceof PasswordAwareMaterial) {
             assertThat("Password setting is wrong for: " + material.getClass(), ((PasswordAwareMaterial) material).getPassword(), is("pass"));
-            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "password"), is(nullValue()));
-            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "encryptedPassword"), is(not(nullValue())));
+            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "password"), is("pass"));
         }
     }
 
     private void assertPasswordIsCorrect(MaterialConfig materialConfig) {
         if (materialConfig instanceof PasswordAwareMaterial) {
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/Materials.java b/domain/src/main/java/com/thoughtworks/go/config/materials/Materials.java
index 28978f17bb4..4f553650265 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/Materials.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/Materials.java
@@ -30,11 +30,10 @@ import com.thoughtworks.go.config.materials.tfs.TfsMaterial;
 import com.thoughtworks.go.config.materials.tfs.TfsMaterialConfig;
 import com.thoughtworks.go.domain.BaseCollection;
 import com.thoughtworks.go.domain.ConfigVisitor;
 import com.thoughtworks.go.domain.MaterialRevisions;
 import com.thoughtworks.go.domain.materials.*;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.ArtifactLogUtil;
 import com.thoughtworks.go.util.command.ConsoleOutputStreamConsumer;
 import com.thoughtworks.go.util.command.UrlArgument;
 import org.apache.commons.lang3.StringUtils;
 
@@ -203,11 +202,11 @@ public class Materials extends BaseCollection<Material> {
     public SvnMaterial getSvnMaterial() {
         return getExistingOrDefaultMaterial(new SvnMaterial("", "", "", false));
     }
 
     public TfsMaterial getTfsMaterial() {
-        return getExistingOrDefaultMaterial(new TfsMaterial(new GoCipher(), new UrlArgument(""), "", "", "", ""));
+        return getExistingOrDefaultMaterial(new TfsMaterial(new UrlArgument(""), "", "", "", ""));
     }
 
     public HgMaterial getHgMaterial() {
         return getExistingOrDefaultMaterial(new HgMaterial("", null));
     }
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/ScmMaterial.java b/domain/src/main/java/com/thoughtworks/go/config/materials/ScmMaterial.java
index 8a088a2a198..cb9561a44c5 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/ScmMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/ScmMaterial.java
@@ -19,12 +19,10 @@ import com.thoughtworks.go.config.CaseInsensitiveString;
 import com.thoughtworks.go.config.PipelineConfig;
 import com.thoughtworks.go.config.SecretParamAware;
 import com.thoughtworks.go.config.SecretParams;
 import com.thoughtworks.go.domain.MaterialRevision;
 import com.thoughtworks.go.domain.materials.*;
-import com.thoughtworks.go.security.CryptoException;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.command.EnvironmentVariableContext;
 import com.thoughtworks.go.util.command.InMemoryStreamConsumer;
 import com.thoughtworks.go.util.command.ProcessOutputStreamConsumer;
 import com.thoughtworks.go.util.command.UrlArgument;
 import org.apache.commons.lang3.StringUtils;
@@ -32,13 +30,11 @@ import org.apache.commons.lang3.StringUtils;
 import javax.annotation.PostConstruct;
 import java.io.File;
 import java.util.Map;
 import java.util.Optional;
 
-import static com.thoughtworks.go.util.ExceptionUtils.bomb;
 import static com.thoughtworks.go.util.command.EnvironmentVariableContext.escapeEnvironmentVariable;
-import static org.apache.commons.lang3.StringUtils.isBlank;
 
 
 /**
  * @understands a source control repository and its configuration
  */
@@ -46,24 +42,21 @@ public abstract class ScmMaterial extends AbstractMaterial implements SecretPara
 
     public static final String GO_REVISION = "GO_REVISION";
     public static final String GO_TO_REVISION = "GO_TO_REVISION";
     public static final String GO_FROM_REVISION = "GO_FROM_REVISION";
     public static final String GO_MATERIAL_URL = "GO_MATERIAL_URL";
-    protected final GoCipher goCipher;
 
     protected Filter filter;
     protected String folder;
     protected boolean autoUpdate = true;
     protected boolean invertFilter = false;
     protected String userName;
     protected String password;
-    protected String encryptedPassword;
     protected SecretParams secretParamsForPassword;
 
-    public ScmMaterial(String typeName, GoCipher goCipher) {
+    public ScmMaterial(String typeName) {
         super(typeName);
-        this.goCipher = goCipher;
     }
 
     @Override
     protected void appendPipelineUniqueCriteria(Map<String, Object> basicCriteria) {
         basicCriteria.put("dest", folder);
@@ -119,30 +112,16 @@ public abstract class ScmMaterial extends AbstractMaterial implements SecretPara
     public final void setPassword(String password) {
         resetPassword(password);
     }
 
     private void resetPassword(String passwordToSet) {
-        if (StringUtils.isBlank(passwordToSet)) {
-            encryptedPassword = null;
-        }
         setPasswordIfNotBlank(passwordToSet);
     }
 
     private void setPasswordIfNotBlank(String password) {
         this.password = StringUtils.stripToNull(password);
         this.secretParamsForPassword = SecretParams.parse(password);
-        this.encryptedPassword = StringUtils.stripToNull(encryptedPassword);
-
-        if (this.password == null) {
-            return;
-        }
-        try {
-            this.encryptedPassword = this.goCipher.encrypt(password);
-        } catch (Exception e) {
-            bomb("Password encryption failed. Please verify your cipher key.", e);
-        }
-        this.password = null;
     }
 
     @PostConstruct
     public void ensureEncrypted() {
         this.userName = StringUtils.stripToNull(this.userName);
@@ -151,20 +130,12 @@ public abstract class ScmMaterial extends AbstractMaterial implements SecretPara
 
     public void setUserName(String userName) {
         this.userName = userName;
     }
 
-    public final void setEncryptedPassword(String encryptedPassword) {
-        this.encryptedPassword = encryptedPassword;
-    }
-
-    public final String getEncryptedPassword() {
-        return encryptedPassword;
-    }
-
     public String getPassword() {
-        return currentPassword();
+        return password;
     }
 
     public String passwordForCommandLine() {
         return secretParamsForPassword == null || secretParamsForPassword.isEmpty() ? getPassword() : secretParamsForPassword.substitute(getPassword());
     }
@@ -177,18 +148,10 @@ public abstract class ScmMaterial extends AbstractMaterial implements SecretPara
     @Override
     public SecretParams getSecretParams() {
         return secretParamsForPassword;
     }
 
-    public final String currentPassword() {
-        try {
-            return isBlank(encryptedPassword) ? null : this.goCipher.decrypt(encryptedPassword);
-        } catch (CryptoException e) {
-            throw new RuntimeException("Could not decrypt the password to get the real password", e);
-        }
-    }
-
     public abstract boolean isCheckExternals();
 
     public abstract String getUrl();
 
     public abstract String urlForCommandLine();
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/git/GitMaterial.java b/domain/src/main/java/com/thoughtworks/go/config/materials/git/GitMaterial.java
index b8d1f4a5f39..0bad03716d5 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/git/GitMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/git/GitMaterial.java
@@ -23,11 +23,10 @@ import com.thoughtworks.go.domain.MaterialInstance;
 import com.thoughtworks.go.domain.materials.*;
 import com.thoughtworks.go.domain.materials.git.GitCommand;
 import com.thoughtworks.go.domain.materials.git.GitMaterialInstance;
 import com.thoughtworks.go.domain.materials.git.GitVersion;
 import com.thoughtworks.go.domain.materials.svn.MaterialUrl;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.server.transaction.TransactionSynchronizationManager;
 import com.thoughtworks.go.util.GoConstants;
 import com.thoughtworks.go.util.command.*;
 import org.apache.commons.io.FileUtils;
 import org.apache.http.client.utils.URIBuilder;
@@ -63,11 +62,11 @@ public class GitMaterial extends ScmMaterial implements PasswordAwareMaterial {
     private String refSpecOrBranch = GitMaterialConfig.DEFAULT_BRANCH;
     private boolean shallowClone = false;
     private String submoduleFolder;
 
     public GitMaterial(String url) {
-        super(TYPE, new GoCipher());
+        super(TYPE);
         this.url = new UrlArgument(url);
     }
 
     public GitMaterial(String url, boolean shallowClone) {
         this(url, null, null, shallowClone);
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/mercurial/HgMaterial.java b/domain/src/main/java/com/thoughtworks/go/config/materials/mercurial/HgMaterial.java
index 191cb382cc2..5ea7abd8162 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/mercurial/HgMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/mercurial/HgMaterial.java
@@ -24,11 +24,10 @@ import com.thoughtworks.go.domain.MaterialInstance;
 import com.thoughtworks.go.domain.materials.*;
 import com.thoughtworks.go.domain.materials.mercurial.HgCommand;
 import com.thoughtworks.go.domain.materials.mercurial.HgMaterialInstance;
 import com.thoughtworks.go.domain.materials.mercurial.HgVersion;
 import com.thoughtworks.go.domain.materials.svn.MaterialUrl;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.GoConstants;
 import com.thoughtworks.go.util.command.*;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
@@ -66,11 +65,11 @@ public class HgMaterial extends ScmMaterial implements PasswordAwareMaterial {
 
     private final String HG_DEFAULT_BRANCH = "default";
     private String branch;
 
     private HgMaterial() {
-        super(TYPE, new GoCipher());
+        super(TYPE);
     }
 
     public HgMaterial(String url, String folder) {
         this();
         this.url = new HgUrlArgument(url);
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/perforce/P4Material.java b/domain/src/main/java/com/thoughtworks/go/config/materials/perforce/P4Material.java
index d39efb315e0..12c2f98d83d 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/perforce/P4Material.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/perforce/P4Material.java
@@ -56,46 +56,38 @@ public class P4Material extends ScmMaterial implements PasswordEncrypter, Passwo
 
     // Database stuff
     //TODO: use iBatis to set the type for us, and we can get rid of this field.
     public static final String TYPE = "P4Material";
 
-    private P4Material(GoCipher goCipher) {
-        super(TYPE, goCipher);
+    private P4Material() {
+        super(TYPE);
     }
 
-    public P4Material(String serverAndPort, String view, GoCipher goCipher) {
-        this(goCipher);
+    public P4Material(String serverAndPort, String view) {
+        this();
         bombIfNull(serverAndPort, "null serverAndPort");
         this.serverAndPort = serverAndPort;
         setView(view);
     }
 
-    public P4Material(String serverAndPort, String view) {
-        this(serverAndPort, view, new GoCipher());
-    }
-
-    public P4Material(String url, String view, String userName) {
-        this(url, view);
+    public P4Material(String serverAndPort, String view, String userName) {
+        this(serverAndPort, view);
         this.userName = userName;
     }
 
-    public P4Material(String url, String view, String userName, String folder) {
-        this(url, view, userName, folder, new GoCipher());
-    }
-
     public P4Material(P4MaterialConfig config) {
-        this(config.getUrl(), config.getView(), config.getUserName(), config.getFolder(), config.getGoCipher());
+        this(config.getUrl(), config.getView(), config.getUserName(), config.getFolder());
         this.name = config.getName();
         this.autoUpdate = config.getAutoUpdate();
         this.filter = config.rawFilter();
         this.invertFilter = config.getInvertFilter();
         setPassword(config.getPassword());
         this.useTickets = config.getUseTickets();
     }
 
-    private P4Material(String serverAndPort, String view, String userName, String folder, GoCipher goCipher) {
-        this(goCipher);
+    public P4Material(String serverAndPort, String view, String userName, String folder) {
+        this();
         bombIfNull(serverAndPort, "null serverAndPort");
         this.serverAndPort = serverAndPort;
         setView(view);
         this.userName = userName;
         this.folder = folder;
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/svn/SvnMaterial.java b/domain/src/main/java/com/thoughtworks/go/config/materials/svn/SvnMaterial.java
index 7bfe67109bf..f7d1742afe0 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/svn/SvnMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/svn/SvnMaterial.java
@@ -51,14 +51,10 @@ public class SvnMaterial extends ScmMaterial implements PasswordEncrypter, Passw
     private boolean checkExternals;
     private transient Subversion svnLazyLoaded;
 
     public static final String TYPE = "SvnMaterial";
 
-    private SvnMaterial(GoCipher goCipher) {
-        super("SvnMaterial", goCipher);
-    }
-
     public SvnMaterial(String url, String userName, String password, boolean checkExternals) {
         this(url, userName, password, checkExternals, new GoCipher());
     }
 
     public SvnMaterial(Subversion svn) {
@@ -79,11 +75,11 @@ public class SvnMaterial extends ScmMaterial implements PasswordEncrypter, Passw
         this.folder = config.getFolder();
         this.name = config.getName();
     }
 
     public SvnMaterial(String url, String userName, String password, boolean checkExternals, GoCipher goCipher) {
-        super("SvnMaterial", goCipher);
+        super("SvnMaterial");
         bombIfNull(url, "null url");
         setUrl(url);
         this.userName = userName;
         setPassword(password);
         this.checkExternals = checkExternals;
diff --git a/domain/src/main/java/com/thoughtworks/go/config/materials/tfs/TfsMaterial.java b/domain/src/main/java/com/thoughtworks/go/config/materials/tfs/TfsMaterial.java
index b4fd30fba3e..71fee366f85 100644
--- a/domain/src/main/java/com/thoughtworks/go/config/materials/tfs/TfsMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/config/materials/tfs/TfsMaterial.java
@@ -23,11 +23,10 @@ import com.thoughtworks.go.config.materials.SubprocessExecutionContext;
 import com.thoughtworks.go.domain.MaterialInstance;
 import com.thoughtworks.go.domain.materials.*;
 import com.thoughtworks.go.domain.materials.tfs.TfsCommand;
 import com.thoughtworks.go.domain.materials.tfs.TfsCommandFactory;
 import com.thoughtworks.go.domain.materials.tfs.TfsMaterialInstance;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.GoConstants;
 import com.thoughtworks.go.util.command.ConsoleOutputStreamConsumer;
 import com.thoughtworks.go.util.command.EnvironmentVariableContext;
 import com.thoughtworks.go.util.command.UrlArgument;
 import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -52,25 +51,25 @@ public class TfsMaterial extends ScmMaterial implements PasswordAwareMaterial, P
 
     private UrlArgument url;
     private String domain = "";
     private String projectPath;
 
-    public TfsMaterial(GoCipher goCipher) {
-        super(TYPE, goCipher);
+    public TfsMaterial() {
+        super(TYPE);
     }
 
-    public TfsMaterial(GoCipher goCipher, UrlArgument url, String userName, String domain, String password, String projectPath) {
-        this(goCipher);
+    public TfsMaterial(UrlArgument url, String userName, String domain, String password, String projectPath) {
+        this();
         this.url = url;
         this.userName = userName;
         this.domain = domain;
         setPassword(password);
         this.projectPath = projectPath;
     }
 
     public TfsMaterial(TfsMaterialConfig config) {
-        this(config.getGoCipher(), new UrlArgument(config.getUrl()), config.getUserName(), config.getDomain(), config.getPassword(), config.getProjectPath());
+        this(new UrlArgument(config.getUrl()), config.getUserName(), config.getDomain(), config.getPassword(), config.getProjectPath());
         this.autoUpdate = config.getAutoUpdate();
         this.filter = config.rawFilter();
         this.invertFilter = config.getInvertFilter();
         this.folder = config.getFolder();
         this.name = config.getName();
diff --git a/domain/src/main/java/com/thoughtworks/go/domain/materials/TestingMaterial.java b/domain/src/main/java/com/thoughtworks/go/domain/materials/TestingMaterial.java
index a317ba3b2f6..20520759b7d 100644
--- a/domain/src/main/java/com/thoughtworks/go/domain/materials/TestingMaterial.java
+++ b/domain/src/main/java/com/thoughtworks/go/domain/materials/TestingMaterial.java
@@ -16,11 +16,10 @@
 package com.thoughtworks.go.domain.materials;
 
 import com.thoughtworks.go.config.materials.ScmMaterial;
 import com.thoughtworks.go.config.materials.SubprocessExecutionContext;
 import com.thoughtworks.go.domain.MaterialInstance;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.command.ConsoleOutputStreamConsumer;
 import com.thoughtworks.go.util.command.UrlArgument;
 import org.joda.time.DateTime;
 
 import java.io.File;
@@ -38,11 +37,11 @@ public class TestingMaterial extends ScmMaterial {
     public static final String TYPE = "TestingMaterial";
 
     private String url;
 
     public TestingMaterial() {
-        super(TYPE, new GoCipher());
+        super(TYPE);
     }
 
     public TestingMaterial(TestingMaterialConfig config) {
         this();
         this.url = config.getUrl();
diff --git a/domain/src/main/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialInstance.java b/domain/src/main/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialInstance.java
index 449c29789d4..a1e316b11f2 100644
--- a/domain/src/main/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialInstance.java
+++ b/domain/src/main/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialInstance.java
@@ -15,11 +15,10 @@
  */
 package com.thoughtworks.go.domain.materials.tfs;
 import com.thoughtworks.go.config.materials.tfs.TfsMaterial;
 import com.thoughtworks.go.domain.MaterialInstance;
 import com.thoughtworks.go.domain.materials.Material;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.command.UrlArgument;
 
 public class TfsMaterialInstance extends MaterialInstance {
 
     private TfsMaterialInstance() {
@@ -29,11 +28,11 @@ public class TfsMaterialInstance extends MaterialInstance {
     public TfsMaterialInstance(String url, String userName, String domain, String projectPath, final String flyweightName) {
         super(url, userName, null, null, null, null, null, null, flyweightName, null, projectPath, domain, null);
     }
 
     @Override public Material toOldMaterial(String name, String folder, String password) {
-        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument(url), username, domain, password, projectPath);
+        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument(url), username, domain, password, projectPath);
         tfsMaterial.setFolder(folder);
         setName(name,tfsMaterial);
         return tfsMaterial;
     }
 }
diff --git a/domain/src/test/java/com/thoughtworks/go/helper/MaterialsMother.java b/domain/src/test/java/com/thoughtworks/go/helper/MaterialsMother.java
index 6e9ccb01c81..c589e30aa0f 100644
--- a/domain/src/test/java/com/thoughtworks/go/helper/MaterialsMother.java
+++ b/domain/src/test/java/com/thoughtworks/go/helper/MaterialsMother.java
@@ -27,11 +27,10 @@ import com.thoughtworks.go.domain.config.Configuration;
 import com.thoughtworks.go.domain.config.ConfigurationProperty;
 import com.thoughtworks.go.domain.materials.Material;
 import com.thoughtworks.go.domain.packagerepository.*;
 import com.thoughtworks.go.domain.scm.SCM;
 import com.thoughtworks.go.domain.scm.SCMMother;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.util.command.UrlArgument;
 
 import java.util.Arrays;
 import java.util.List;
 
@@ -173,11 +172,11 @@ public class MaterialsMother {
         material.setUseTickets(useTickets);
         return material;
     }
 
     public static TfsMaterial tfsMaterial(String url) {
-        return new TfsMaterial(new GoCipher(), new UrlArgument(url), "username", "domain", "password", "project-path");
+        return new TfsMaterial(new UrlArgument(url), "username", "domain", "password", "project-path");
     }
 
     public static SvnMaterial svnMaterial(String svnUrl, String folder) {
         return svnMaterial(svnUrl, folder, "user", "pass", true, "*.doc");
     }
diff --git a/server/src/test-fast/java/com/thoughtworks/go/server/service/MaterialServiceTest.java b/server/src/test-fast/java/com/thoughtworks/go/server/service/MaterialServiceTest.java
index 4f03afd49a8..46536dc0741 100644
--- a/server/src/test-fast/java/com/thoughtworks/go/server/service/MaterialServiceTest.java
+++ b/server/src/test-fast/java/com/thoughtworks/go/server/service/MaterialServiceTest.java
@@ -47,11 +47,10 @@ import com.thoughtworks.go.plugin.access.scm.SCMPropertyConfiguration;
 import com.thoughtworks.go.plugin.access.scm.material.MaterialPollResult;
 import com.thoughtworks.go.plugin.access.scm.revision.SCMRevision;
 import com.thoughtworks.go.plugin.api.material.packagerepository.PackageConfiguration;
 import com.thoughtworks.go.plugin.api.material.packagerepository.PackageRevision;
 import com.thoughtworks.go.plugin.api.material.packagerepository.RepositoryConfiguration;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.server.dao.FeedModifier;
 import com.thoughtworks.go.server.domain.Username;
 import com.thoughtworks.go.server.persistence.MaterialRepository;
 import com.thoughtworks.go.server.service.materials.GitPoller;
 import com.thoughtworks.go.server.service.materials.MaterialPoller;
@@ -198,11 +197,11 @@ public class MaterialServiceTest {
             return (List<Modification>) MODIFICATIONS;
         }
     }, HgMaterial.class);
 
     @DataPoint
-    public static RequestDataPoints TFS_LATEST_MODIFICATIONS = new RequestDataPoints(new TfsMaterial(mock(GoCipher.class)) {
+    public static RequestDataPoints TFS_LATEST_MODIFICATIONS = new RequestDataPoints(new TfsMaterial() {
         @Override
         public List<Modification> latestModification(File baseDir, SubprocessExecutionContext execCtx) {
             return (List<Modification>) MODIFICATIONS;
         }
 
diff --git a/server/src/test-integration/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialPersistenceTest.java b/server/src/test-integration/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialPersistenceTest.java
index 9a53d2d3735..d657a3f288c 100644
--- a/server/src/test-integration/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialPersistenceTest.java
+++ b/server/src/test-integration/java/com/thoughtworks/go/domain/materials/tfs/TfsMaterialPersistenceTest.java
@@ -17,11 +17,10 @@ package com.thoughtworks.go.domain.materials.tfs;
 
 import com.thoughtworks.go.config.CaseInsensitiveString;
 import com.thoughtworks.go.config.materials.tfs.TfsMaterial;
 import com.thoughtworks.go.domain.MaterialInstance;
 import com.thoughtworks.go.domain.materials.Material;
-import com.thoughtworks.go.security.GoCipher;
 import com.thoughtworks.go.server.cache.GoCache;
 import com.thoughtworks.go.server.dao.DatabaseAccessHelper;
 import com.thoughtworks.go.server.persistence.MaterialRepository;
 import com.thoughtworks.go.util.GoConfigFileHelper;
 import com.thoughtworks.go.util.command.UrlArgument;
@@ -62,32 +61,32 @@ public class TfsMaterialPersistenceTest {
         configHelper.onTearDown();
     }
 
     @Test
     public void shouldBeAbleToConvertAMaterialInstanceObjectToTfsMaterialObject() {
-        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "password", "/dev/null");
+        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "password", "/dev/null");
         tfsCfg.setFolder("folder");
         tfsCfg.setName(new CaseInsensitiveString("materialName"));
         MaterialInstance tfsInstance = materialRepository.findOrCreateFrom(tfsCfg);
 
         Material material = tfsInstance.toOldMaterial("materialName", "folder", "password");
         assertThat(material, is(tfsCfg));
     }
 
     @Test
     public void shouldFindOldMaterial() {
-        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
+        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
         MaterialInstance tfsInstance1 = materialRepository.findOrCreateFrom(tfsCfg);
         goCache.clear();
         MaterialInstance tfsInstance2 = materialRepository.findOrCreateFrom(tfsCfg);
 
         assertThat(tfsInstance1, is(tfsInstance2));
     }
 
     @Test
     public void shouldSaveMaterialInstance() throws Exception {
-        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
+        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
         MaterialInstance materialInstance = materialRepository.findOrCreateFrom(tfsCfg);
         assertThat(materialRepository.findMaterialInstance(tfsCfg), is(materialInstance));
     }
 
 }

Vulnerable code:                 "encrypted_password": svnMaterial.encryptedPassword
    @Test
    void shouldEncryptP4Password() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");

        P4Material p4Material = new P4Material("example.com:1818", "view", mockGoCipher);
        p4Material.setPassword("password");
        p4Material.ensureEncrypted();

        assertThat(p4Material.getEncryptedPassword()).isEqualTo("encrypted");
        assertThat(p4Material.getPassword()).isNull();
    }

    @Test
    void shouldDecryptP4Password() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");

        P4Material p4Material = new P4Material("example.com:1818", "view", mockGoCipher);
        ReflectionUtil.setField(p4Material, "encryptedPassword", "encrypted");
        p4Material.getPassword();

        assertThat(p4Material.getPassword()).isEqualTo("password");
    }

        tfsMaterialFirstCollectionFirstProject = new TfsMaterial(goCipher, new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_FIRST_PROJECT);
        tfsMaterialFirstCollectionSecondProject = new TfsMaterial(goCipher, new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_SECOND_PROJECT);
        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
        tfsMaterial = new TfsMaterial(new GoCipher(), null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
        tfsMaterial = new TfsMaterial(new GoCipher(), null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
    @Test
    void shouldEncryptTfsPasswordAndMarkPasswordAsNull() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");

        TfsMaterial tfsMaterial = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
        tfsMaterial.ensureEncrypted();

        assertThat(tfsMaterial.getPassword()).isNull();
        assertThat(tfsMaterial.getEncryptedPassword()).isEqualTo("encrypted");
    }

    @Test
    void shouldDecryptTfsPassword() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");

        TfsMaterial tfsMaterial = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, null, "");

        ReflectionUtil.setField(tfsMaterial, "encryptedPassword", "encrypted");

        tfsMaterial.ensureEncrypted();
        assertThat(tfsMaterial.getPassword()).isEqualTo("password");
    }

        TfsMaterial material = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
    @Test
    void shouldErrorOutIfDecryptionFails() throws CryptoException {
        GoCipher mockGoCipher = mock(GoCipher.class);
        String fakeCipherText = "fake cipher text";
        when(mockGoCipher.decrypt(fakeCipherText)).thenThrow(new CryptoException("exception"));
        TfsMaterial material = new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
        ReflectionUtil.setField(material, "encryptedPassword", fakeCipherText);
        try {
            material.getPassword();
            fail("Should have thrown up");
        } catch (Exception e) {
            assertThat(e.getMessage()).isEqualTo("Could not decrypt the password to get the real password");
        }
    }

    @Test
    void shouldErrorOutIfEncryptionFails() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.encrypt("password")).thenThrow(new CryptoException("exception"));
        try {
            new TfsMaterial(mockGoCipher, new UrlArgument("/foo"), "username", DOMAIN, "password", "");
            fail("Should have thrown up");
        } catch (Exception e) {
            assertThat(e.getMessage()).isEqualTo("Password encryption failed. Please verify your cipher key.");
        }
    }

        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new GoCipher(), new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "badger", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
        TfsMaterial material = new TfsMaterial(mock(GoCipher.class), new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, "", PASSWORD, TFS_FIRST_PROJECT);
import com.thoughtworks.go.security.GoCipher;
        super("DummyMaterial", new GoCipher());
    @Test
    void shouldEncryptSvnPasswordAndMarkPasswordAsNull() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.encrypt("password")).thenReturn("encrypted");

        SvnMaterial material = new SvnMaterial("/foo", "username", "password", false, mockGoCipher);
        material.ensureEncrypted();

        assertThat(material.getPassword()).isNull();
        assertThat(material.getEncryptedPassword()).isEqualTo("encrypted");
    }

    @Test
    void shouldDecryptSvnPassword() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.decrypt("encrypted")).thenReturn("password");

        SvnMaterial material = new SvnMaterial("/foo", "username", null, false, mockGoCipher);
        ReflectionUtil.setField(material, "encryptedPassword", "encrypted");

        material.ensureEncrypted();
        assertThat(material.getPassword()).isEqualTo("password");
    }

    @Test
    void shouldErrorOutIfDecryptionFails() throws CryptoException {
        GoCipher mockGoCipher = mock(GoCipher.class);
        String fakeCipherText = "fake cipher text";
        when(mockGoCipher.decrypt(fakeCipherText)).thenThrow(new CryptoException("exception"));
        SvnMaterial material = new SvnMaterial("/foo", "username", null, false, mockGoCipher);
        ReflectionUtil.setField(material, "encryptedPassword", fakeCipherText);
        try {
            material.getPassword();
            fail("Should have thrown up");
        } catch (Exception e) {
            assertThat(e.getMessage()).isEqualTo("Could not decrypt the password to get the real password");
        }
    }

    @Test
    void shouldErrorOutIfEncryptionFails() throws Exception {
        GoCipher mockGoCipher = mock(GoCipher.class);
        when(mockGoCipher.encrypt("password")).thenThrow(new CryptoException("exception"));
        try {
            new SvnMaterial("/foo", "username", "password", false, mockGoCipher);
            fail("Should have thrown up");
        } catch (Exception e) {
            assertThat(e.getMessage()).isEqualTo("Password encryption failed. Please verify your cipher key.");
        }
    }

            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "password"), is(nullValue()));
            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "encryptedPassword"), is(not(nullValue())));
import com.thoughtworks.go.security.GoCipher;
        return getExistingOrDefaultMaterial(new TfsMaterial(new GoCipher(), new UrlArgument(""), "", "", "", ""));
import com.thoughtworks.go.security.CryptoException;
import com.thoughtworks.go.security.GoCipher;
import static com.thoughtworks.go.util.ExceptionUtils.bomb;
import static org.apache.commons.lang3.StringUtils.isBlank;
    protected final GoCipher goCipher;
    protected String encryptedPassword;
    public ScmMaterial(String typeName, GoCipher goCipher) {
        this.goCipher = goCipher;
        if (StringUtils.isBlank(passwordToSet)) {
            encryptedPassword = null;
        }
        this.encryptedPassword = StringUtils.stripToNull(encryptedPassword);

        if (this.password == null) {
            return;
        }
        try {
            this.encryptedPassword = this.goCipher.encrypt(password);
        } catch (Exception e) {
            bomb("Password encryption failed. Please verify your cipher key.", e);
        }
        this.password = null;
    public final void setEncryptedPassword(String encryptedPassword) {
        this.encryptedPassword = encryptedPassword;
    }

    public final String getEncryptedPassword() {
        return encryptedPassword;
    }

        return currentPassword();
    public final String currentPassword() {
        try {
            return isBlank(encryptedPassword) ? null : this.goCipher.decrypt(encryptedPassword);
        } catch (CryptoException e) {
            throw new RuntimeException("Could not decrypt the password to get the real password", e);
        }
    }

import com.thoughtworks.go.security.GoCipher;
        super(TYPE, new GoCipher());
import com.thoughtworks.go.security.GoCipher;
        super(TYPE, new GoCipher());
    private P4Material(GoCipher goCipher) {
        super(TYPE, goCipher);
    public P4Material(String serverAndPort, String view, GoCipher goCipher) {
        this(goCipher);
    public P4Material(String serverAndPort, String view) {
        this(serverAndPort, view, new GoCipher());
    }

    public P4Material(String url, String view, String userName) {
        this(url, view);
    public P4Material(String url, String view, String userName, String folder) {
        this(url, view, userName, folder, new GoCipher());
    }

        this(config.getUrl(), config.getView(), config.getUserName(), config.getFolder(), config.getGoCipher());
    private P4Material(String serverAndPort, String view, String userName, String folder, GoCipher goCipher) {
        this(goCipher);
    private SvnMaterial(GoCipher goCipher) {
        super("SvnMaterial", goCipher);
    }

        super("SvnMaterial", goCipher);
import com.thoughtworks.go.security.GoCipher;
    public TfsMaterial(GoCipher goCipher) {
        super(TYPE, goCipher);
    public TfsMaterial(GoCipher goCipher, UrlArgument url, String userName, String domain, String password, String projectPath) {
        this(goCipher);
        this(config.getGoCipher(), new UrlArgument(config.getUrl()), config.getUserName(), config.getDomain(), config.getPassword(), config.getProjectPath());
import com.thoughtworks.go.security.GoCipher;
        super(TYPE, new GoCipher());
import com.thoughtworks.go.security.GoCipher;
        TfsMaterial tfsMaterial = new TfsMaterial(new GoCipher(), new UrlArgument(url), username, domain, password, projectPath);
import com.thoughtworks.go.security.GoCipher;
        return new TfsMaterial(new GoCipher(), new UrlArgument(url), "username", "domain", "password", "project-path");
import com.thoughtworks.go.security.GoCipher;
    public static RequestDataPoints TFS_LATEST_MODIFICATIONS = new RequestDataPoints(new TfsMaterial(mock(GoCipher.class)) {
import com.thoughtworks.go.security.GoCipher;
        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "password", "/dev/null");
        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
        TfsMaterial tfsCfg = new TfsMaterial(new GoCipher(), new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
Fixed code:                 "encrypted_password": svnMaterial.config().getEncryptedPassword()
        tfsMaterialFirstCollectionFirstProject = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_FIRST_PROJECT);
        tfsMaterialFirstCollectionSecondProject = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, DOMAIN, PASSWORD, TFS_SECOND_PROJECT);
        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("my-url"), "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
        tfsMaterial = new TfsMaterial(null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("http://foo:bar@my-url.com"), "loser", DOMAIN, "foo_bar_baz", "/dev/null"
        tfsMaterial = new TfsMaterial(null, "loser", DOMAIN, "foo_bar_baz", "/dev/null");
        TfsMaterial material = new TfsMaterial(new UrlArgument("/foo"), "username", DOMAIN, "password", "");
        TfsMaterial material = new TfsMaterial(new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new UrlArgument("http://url/"), "user", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
        TfsMaterial material = new TfsMaterial(new UrlArgument("http://username:password@tfsrepo.com"), "username", "domain", "password", "$project/path/");
            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "badger", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
            TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument("some-url"), null, null, "{{SECRET:[secret_config_id][lookup_pass]}}", null);
        TfsMaterial material = new TfsMaterial(new UrlArgument(TFS_FIRST_COLLECTION_URL), USERNAME, "", PASSWORD, TFS_FIRST_PROJECT);
        super("DummyMaterial");
            assertThat("Password setting is wrong for: " + material.getClass(), ReflectionUtil.getField(material, "password"), is("pass"));
        return getExistingOrDefaultMaterial(new TfsMaterial(new UrlArgument(""), "", "", "", ""));
    public ScmMaterial(String typeName) {
        return password;
        super(TYPE);
        super(TYPE);
    private P4Material() {
        super(TYPE);
    public P4Material(String serverAndPort, String view) {
        this();
    public P4Material(String serverAndPort, String view, String userName) {
        this(serverAndPort, view);
        this(config.getUrl(), config.getView(), config.getUserName(), config.getFolder());
    public P4Material(String serverAndPort, String view, String userName, String folder) {
        this();
        super("SvnMaterial");
    public TfsMaterial() {
        super(TYPE);
    public TfsMaterial(UrlArgument url, String userName, String domain, String password, String projectPath) {
        this();
        this(new UrlArgument(config.getUrl()), config.getUserName(), config.getDomain(), config.getPassword(), config.getProjectPath());
        super(TYPE);
        TfsMaterial tfsMaterial = new TfsMaterial(new UrlArgument(url), username, domain, password, projectPath);
        return new TfsMaterial(new UrlArgument(url), "username", "domain", "password", "project-path");
    public static RequestDataPoints TFS_LATEST_MODIFICATIONS = new RequestDataPoints(new TfsMaterial() {
        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "password", "/dev/null");
        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");
        TfsMaterial tfsCfg = new TfsMaterial(new UrlArgument("url"), "loser", "CORPORATE", "foo_bar_baz", "/dev/null");