{
  "id": "security/oauth2-jwt-issuer-mismatch-allows-token-forgery",
  "signature": "OAuth2 JWT issuer mismatch allows token forgery",
  "signature_zh": "OAuth2 JWT签发者不匹配允许令牌伪造",
  "regex": "OAuth2 JWT issuer mismatch: token was issued by a different identity provider",
  "domain": "security",
  "category": "auth_error",
  "subcategory": null,
  "root_cause": "When a JWT token's 'iss' (issuer) claim does not match the expected identity provider, the token could be forged by an attacker using a different issuer, bypassing authentication if the validation is not enforced.",
  "root_cause_type": "generic",
  "root_cause_zh": "当JWT令牌的'iss'（签发者）声明与预期的身份提供者不匹配时，攻击者可以使用不同的签发者伪造令牌，如果未强制执行验证，则会绕过身份验证。",
  "versions": [
    {
      "version": "JWT",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Spring Security 5.7+",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Keycloak 22.0.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Auth0 2024.01",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "",
      "why_fails": "Relying solely on signature validation is insufficient because an attacker can sign a token with a different issuer's key if the public key is obtained from an untrusted source.",
      "fail_rate": 0.7,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "Ignoring the issuer claim entirely and only validating the audience (aud) claim allows tokens from any issuer to be accepted.",
      "fail_rate": 0.8,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "Using a hardcoded issuer value in code without checking the token's actual issuer is bypassed if the token's iss is different.",
      "fail_rate": 0.6,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Validate the 'iss' claim against a whitelist of trusted issuers. Example in Java with Spring Security: JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); converter.setJwtGrantedAuthoritiesConverter(jwt -> { if (!trustedIssuers.contains(jwt.getIssuer())) throw new AuthenticationException(); ... });",
      "success_rate": 0.95,
      "how": "Validate the 'iss' claim against a whitelist of trusted issuers. Example in Java with Spring Security: JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); converter.setJwtGrantedAuthoritiesConverter(jwt -> { if (!trustedIssuers.contains(jwt.getIssuer())) throw new AuthenticationException(); ... });",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use OpenID Connect Discovery to fetch the issuer's configuration and validate against it dynamically. Example: jwks_uri from .well-known/openid-configuration.",
      "success_rate": 0.9,
      "how": "Use OpenID Connect Discovery to fetch the issuer's configuration and validate against it dynamically. Example: jwks_uri from .well-known/openid-configuration.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Ensure the JWT library enforces issuer validation (e.g., in jose-jwt library: JwtConsumer.builder().setExpectedIssuer('https://my-idp.com').build()).",
      "success_rate": 0.85,
      "how": "Ensure the JWT library enforces issuer validation (e.g., in jose-jwt library: JwtConsumer.builder().setExpectedIssuer('https://my-idp.com').build()).",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Validate the 'iss' claim against a whitelist of trusted issuers. Example in Java with Spring Security: JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); converter.setJwtGrantedAuthoritiesConverter(jwt -> { if (!trustedIssuers.contains(jwt.getIssuer())) throw new AuthenticationException(); ... });",
    "Use OpenID Connect Discovery to fetch the issuer's configuration and validate against it dynamically. Example: jwks_uri from .well-known/openid-configuration.",
    "Ensure the JWT library enforces issuer validation (e.g., in jose-jwt library: JwtConsumer.builder().setExpectedIssuer('https://my-idp.com').build())."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1",
  "official_doc_section": null,
  "error_code": "OAUTH2_JWT_ISSUER_MISMATCH",
  "verification_tier": "ai_generated",
  "confidence": 0.84,
  "fix_success_rate": 0.9,
  "resolvable": "true",
  "first_seen": "2024-03-05",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}