CVE-2019-14837: Use of Hard-coded Credentials (CWE-798)
value: A flaw was found in keycloack before version 8.0.0. The owner of 'placeholder.org' domain can setup mail server on this domain and knowing only name of a client can reset password and then log in. For example, for client name 'test' the email address will be 'service-account-test@placeholder.org'.
CWE description: The product contains hard-coded credentials, such as a password or cryptographic key.
CVSS v3 base score: 9.1
Published: 2020-01-07T17:15Z
Repository: https://github.com/keycloak/keycloak
Language: JSON
Files changed: examples/demo-template/testrealm.json, services/src/main/java/org/keycloak/services/managers/ClientManager.java, testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json, testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
Commit date: 2019-11-15 15:08:29 +0100
Commit message: KEYCLOAK-10780 Stop creating placeholder e-mails for service accounts (#228)

Diff: diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json
index 7b9db36b1f..00fb4075bf 100755
--- a/examples/demo-template/testrealm.json
+++ b/examples/demo-template/testrealm.json
@@ -74,11 +74,10 @@
             }
         },
         {
             "username" : "service-account-product-sa-client",
             "enabled": true,
-            "email" : "service-account-product-sa-client@placeholder.org",
             "serviceAccountClientId": "product-sa-client",
             "realmRoles": [ "user" ]
         }
     ],
     "roles" : {
diff --git a/services/src/main/java/org/keycloak/services/managers/ClientManager.java b/services/src/main/java/org/keycloak/services/managers/ClientManager.java
index b78aaeec5c..61a7dfe61b 100644
--- a/services/src/main/java/org/keycloak/services/managers/ClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ClientManager.java
@@ -162,11 +162,10 @@ public class ClientManager {
             logger.debugf("Creating service account user '%s'", username);
 
             // Don't use federation for service account user
             UserModel user = realmManager.getSession().userLocalStorage().addUser(client.getRealm(), username);
             user.setEnabled(true);
-            user.setEmail(username + "@placeholder.org");
             user.setServiceAccountClientLink(client.getId());
         }
 
         // Add protocol mappers to retrieve clientId in access token
         if (client.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER) == null) {
@@ -203,11 +202,10 @@ public class ClientManager {
 
         UserModel serviceAccountUser = realmManager.getSession().users().getServiceAccount(client);
         if (serviceAccountUser != null) {
             String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + newClientId;
             serviceAccountUser.setUsername(username);
-            serviceAccountUser.setEmail(username + "@placeholder.org");
         }
     }
 
     @JsonPropertyOrder({"realm", "realm-public-key", "bearer-only", "auth-server-url", "ssl-required",
             "resource", "public-client", "verify-token-audience", "credentials",
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json
index 83019c909f..0c42512c08 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json
@@ -109,11 +109,10 @@
       }
     },
     {
       "username": "service-account-photoz-restful-api",
       "enabled": true,
-      "email": "service-account-photoz-restful-api@placeholder.org",
       "serviceAccountClientId": "photoz-restful-api",
       "clientRoles": {
         "photoz-restful-api" : ["uma_protection"]
       }
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
index 0c48fa6294..905f29c075 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
@@ -229,10 +229,12 @@ public class ClientTest extends AbstractAdminTest {
         String id = ApiUtil.getCreatedId(response);
         getCleanup().addClientUuid(id);
         response.close();
         UserRepresentation userRep = realm.clients().get(id).getServiceAccountUser();
         assertEquals("service-account-serviceclient", userRep.getUsername());
+        // KEYCLOAK-11197 service accounts are no longer created with a placeholder e-mail.
+        assertNull(userRep.getEmail());
     }
 
     // KEYCLOAK-3421
     @Test
     public void createClientWithFragments() {

Vulnerable code:             "email" : "service-account-product-sa-client@placeholder.org",
            user.setEmail(username + "@placeholder.org");
            serviceAccountUser.setEmail(username + "@placeholder.org");
      "email": "service-account-photoz-restful-api@placeholder.org",
Fixed code:         // KEYCLOAK-11197 service accounts are no longer created with a placeholder e-mail.
        assertNull(userRep.getEmail());