CVE-2018-1262
Description
Cloud Foundry Foundation UAA, versions 4.12.X and 4.13.X, introduced a feature which could allow privilege escalation across identity zones for clients performing offline validation. A zone administrator could configure their zone to issue tokens which impersonate another zone, granting up to admin privileges in the impersonated zone for clients performing offline token validation.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Cloud Foundry UAA 4.12.x and 4.13.x allow zone administrators to escalate privileges across identity zones via forged tokens during offline validation.
Vulnerability
Cloud Foundry UAA versions 4.12.x and 4.13.x introduced a feature that enables privilege escalation across identity zones for clients performing offline token validation [1][2]. A zone administrator can configure their identity zone to issue tokens that impersonate another zone. This occurs because the zone configuration allows setting a custom issuer without requiring a matching signing key, which permits the administrator to mint tokens that appear to originate from a different zone [3][4].
Exploitation
An attacker who is a zone administrator (i.e., has the ability to configure an identity zone) can exploit this vulnerability by setting a custom issuer value that matches the target zone's issuer. If the zone administrator also controls or can set a signing key for their own zone, they can forge tokens that will be accepted by resource servers performing offline token validation without verifying the token's origin correctly [2][3][4]. The attacker does not need user interaction or elevated privileges in the target zone initially.
Impact
Successful exploitation allows the attacker to obtain tokens that impersonate any identity zone, potentially granting up to admin-level privileges in the impersonated zone for clients performing offline token validation. This can lead to unauthorized access to resources, privilege escalation, and full compromise of the targeted identity zone's data and management functions [2].
Mitigation
The vulnerability is fixed in the UAA releases following 4.12.x and 4.13.x. The fix ensures that identity zone creation and updates enforce that a zone must have its own signing key set before a custom issuer can be configured [3][4]. Organizations should upgrade to the latest patched version of UAA (e.g., 4.13.1 or later) as provided by Cloud Foundry Foundation. If immediate upgrade is not possible, consider restricting zone administrator privileges or using online token validation to mitigate the risk.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven | >= 4.12.0, < 4.12.2 | 4.12.2 |
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven | >= 4.13.0, < 4.13.4 | 4.13.4 |
Affected products
2- ghsa-coordsRange: >= 4.12.0, < 4.12.2
- Cloud Foundry/CloudFoundry UAAv5Range: 4.12.X and 4.13.X
Patches
214c745aa293bIdentity zone creation checks for signing key with issuer
2 files changed · +61 −4
server/src/main/java/org/cloudfoundry/identity/uaa/zone/GeneralIdentityZoneConfigurationValidator.java+5 −0 modified@@ -68,6 +68,11 @@ public IdentityZoneConfiguration validate(IdentityZone zone, IdentityZoneValidat } } } + if (!StringUtils.isEmpty(config.getIssuer())) { + if (tokenPolicy == null || StringUtils.isEmpty(tokenPolicy.getActiveKeyId())) { + throw new InvalidIdentityZoneConfigurationException("You cannot set issuer value unless you have set your own signing key for this identity zone."); + } + } } if(config.getBranding() != null && config.getBranding().getBanner() != null) {
uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java+56 −4 modified@@ -94,6 +94,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -1948,6 +1949,50 @@ public void updateZoneWithInvalidMfaConfig() throws Exception { updateZone(identityZone, HttpStatus.UNPROCESSABLE_ENTITY, adminToken); } + @Test + public void testCreateZone_withCustomIssuerAndSigningKeyWorks() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(new TokenPolicy()); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.CREATED, + adminToken, + identityZoneConfiguration + ); + } + + @Test + public void testCreateZone_withCustomIssuerAndNoTokenPolicyShouldFail() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(null); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.UNPROCESSABLE_ENTITY, + "You cannot set issuer value unless you have set your own signing key for this identity zone.", + adminToken, + identityZoneConfiguration + ); + } + + @Test + public void testCreateZone_withCustomIssuerAndNoActiveSigningKeyShouldFail() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(new TokenPolicy()); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.UNPROCESSABLE_ENTITY, + "You cannot set issuer value unless you have set your own signing key for this identity zone.", + adminToken, + identityZoneConfiguration + ); + } + private MfaProvider<GoogleMfaProviderConfig> createGoogleMfaProvider(String zoneId) throws Exception { MfaProvider<GoogleMfaProviderConfig> mfaProvider = new MfaProvider().setName(new RandomValueStringGenerator(5).generate()); MockHttpServletRequestBuilder createMfaRequest = post("/mfa-providers") @@ -1976,22 +2021,29 @@ private IdentityZone getIdentityZone(String id, HttpStatus expect, String token) } private IdentityZone createZone(String id, HttpStatus expect, String token, IdentityZoneConfiguration zoneConfiguration) throws Exception { + Map<String, String> keys = new HashMap<>(); + keys.put("kid", "key"); + zoneConfiguration.getTokenPolicy().setKeys(keys); + zoneConfiguration.getTokenPolicy().setActiveKeyId("kid"); + zoneConfiguration.getTokenPolicy().setKeys(keys); + + return createZone(id, expect, "" , token, zoneConfiguration); + } + + private IdentityZone createZone(String id, HttpStatus expect, String expectedContent, String token, IdentityZoneConfiguration zoneConfiguration) throws Exception { IdentityZone identityZone = getIdentityZone(id); identityZone.setConfig(zoneConfiguration); identityZone.getConfig().getSamlConfig().setPrivateKey(serviceProviderKey); identityZone.getConfig().getSamlConfig().setPrivateKeyPassword(serviceProviderKeyPassword); identityZone.getConfig().getSamlConfig().setCertificate(serviceProviderCertificate); - Map<String, String> keys = new HashMap<>(); - keys.put("kid", "key"); - identityZone.getConfig().getTokenPolicy().setKeys(keys); - identityZone.getConfig().getTokenPolicy().setActiveKeyId("kid"); MvcResult result = getMockMvc().perform( post("/identity-zones") .header("Authorization", "Bearer " + token) .contentType(APPLICATION_JSON) .content(JsonUtils.writeValueAsString(identityZone))) .andExpect(status().is(expect.value())) + .andExpect(content().string(containsString(expectedContent))) .andReturn(); if (expect.is2xxSuccessful()) {
dccd3962f969Identity zone creation checks for signing key with issuer
2 files changed · +61 −4
server/src/main/java/org/cloudfoundry/identity/uaa/zone/GeneralIdentityZoneConfigurationValidator.java+5 −0 modified@@ -68,6 +68,11 @@ public IdentityZoneConfiguration validate(IdentityZone zone, IdentityZoneValidat } } } + if (!StringUtils.isEmpty(config.getIssuer())) { + if (tokenPolicy == null || StringUtils.isEmpty(tokenPolicy.getActiveKeyId())) { + throw new InvalidIdentityZoneConfigurationException("You cannot set issuer value unless you have set your own signing key for this identity zone."); + } + } } if(config.getBranding() != null && config.getBranding().getBanner() != null) {
uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java+56 −4 modified@@ -94,6 +94,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -1948,6 +1949,50 @@ public void updateZoneWithInvalidMfaConfig() throws Exception { updateZone(identityZone, HttpStatus.UNPROCESSABLE_ENTITY, adminToken); } + @Test + public void testCreateZone_withCustomIssuerAndSigningKeyWorks() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(new TokenPolicy()); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.CREATED, + adminToken, + identityZoneConfiguration + ); + } + + @Test + public void testCreateZone_withCustomIssuerAndNoTokenPolicyShouldFail() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(null); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.UNPROCESSABLE_ENTITY, + "You cannot set issuer value unless you have set your own signing key for this identity zone.", + adminToken, + identityZoneConfiguration + ); + } + + @Test + public void testCreateZone_withCustomIssuerAndNoActiveSigningKeyShouldFail() throws Exception { + IdentityZoneConfiguration identityZoneConfiguration = new IdentityZoneConfiguration(); + identityZoneConfiguration.setIssuer("http://my-custom-issuer.com"); + identityZoneConfiguration.setTokenPolicy(new TokenPolicy()); + + createZone( + "should-not-exist" + new RandomValueStringGenerator(5).generate(), + HttpStatus.UNPROCESSABLE_ENTITY, + "You cannot set issuer value unless you have set your own signing key for this identity zone.", + adminToken, + identityZoneConfiguration + ); + } + private MfaProvider<GoogleMfaProviderConfig> createGoogleMfaProvider(String zoneId) throws Exception { MfaProvider<GoogleMfaProviderConfig> mfaProvider = new MfaProvider().setName(new RandomValueStringGenerator(5).generate()); MockHttpServletRequestBuilder createMfaRequest = post("/mfa-providers") @@ -1976,22 +2021,29 @@ private IdentityZone getIdentityZone(String id, HttpStatus expect, String token) } private IdentityZone createZone(String id, HttpStatus expect, String token, IdentityZoneConfiguration zoneConfiguration) throws Exception { + Map<String, String> keys = new HashMap<>(); + keys.put("kid", "key"); + zoneConfiguration.getTokenPolicy().setKeys(keys); + zoneConfiguration.getTokenPolicy().setActiveKeyId("kid"); + zoneConfiguration.getTokenPolicy().setKeys(keys); + + return createZone(id, expect, "" , token, zoneConfiguration); + } + + private IdentityZone createZone(String id, HttpStatus expect, String expectedContent, String token, IdentityZoneConfiguration zoneConfiguration) throws Exception { IdentityZone identityZone = getIdentityZone(id); identityZone.setConfig(zoneConfiguration); identityZone.getConfig().getSamlConfig().setPrivateKey(serviceProviderKey); identityZone.getConfig().getSamlConfig().setPrivateKeyPassword(serviceProviderKeyPassword); identityZone.getConfig().getSamlConfig().setCertificate(serviceProviderCertificate); - Map<String, String> keys = new HashMap<>(); - keys.put("kid", "key"); - identityZone.getConfig().getTokenPolicy().setKeys(keys); - identityZone.getConfig().getTokenPolicy().setActiveKeyId("kid"); MvcResult result = getMockMvc().perform( post("/identity-zones") .header("Authorization", "Bearer " + token) .contentType(APPLICATION_JSON) .content(JsonUtils.writeValueAsString(identityZone))) .andExpect(status().is(expect.value())) + .andExpect(content().string(containsString(expectedContent))) .andReturn(); if (expect.is2xxSuccessful()) {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-8v97-gv3g-32rfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-1262ghsaADVISORY
- github.com/cloudfoundry/uaa/commit/14c745aa293b8d3ce9cdd6bfbc6c0ef3f269b21ghsaWEB
- github.com/cloudfoundry/uaa/commit/dccd3962f969913996ee88f653fce3b108c0205ghsaWEB
- www.cloudfoundry.org/blog/cve-2018-1262ghsaWEB
- www.cloudfoundry.org/blog/cve-2018-1262/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.