GHSA-WXG7-W2V3-W38G

Vulnerability from github – Published: 2026-06-18 13:52 – Updated: 2026-06-18 13:52
VLAI
Summary
ZITADEL: Missing Token Lifecyle Validation (`exp` and `iat`) in JWT IdP Provider
Details

Summary

Two closely related token lifecycle validation vulnerabilities were discovered in ZITADEL's external JWT Identity Provider (IdP) implementation.

Specifically, within the validation pipeline:

  • Missing Expiration (exp) Enforcement: If an incoming JWT omits the exp claim entirely, the expiration block is silently skipped rather than rejected. The token is treated as valid forever.
  • Missing Issued-At (iat) Enforcement: ZITADEL enforces a 1-hour freshness window (maxAge) via the token's issue time. However, this safety check is guarded by a presence condition. If a token omits the iat claim, the freshness check is entirely bypassed, allowing arbitrarily old tokens to pass.

Per the OIDC Core 1.0 specification, identity token validation pipelines must strictly handle and enforce session expiration. ZITADEL's silent acceptance of tokens missing these temporal constraints compromises session integrity.

Impact

An attacker in possession of a token that lacks both exp and iat claims holds a permanent credential that will never expire and will always be deemed "fresh" by the system. Even without combining both flaws, the absence of an expiration constraint means a leaked token effectively turns into a skeleton key for that user session with no automatic revocation window.

Affected Versions

Systems running one of the following versions are affected:

  • 4.x: 4.0.0 through 4.15.1 (including RC versions)
  • 3.x: 3.0.0 through 3.4.11 (including RC versions)

Patches

The vulnerability has been addressed in the latest releases. ZITADEL now explicitly rejects tokens that lack an exp or iat claim.

Workarounds

The recommended solution is to update ZITADEL to a patched version.

If an immediate upgrade is not feasible, ensure at the Identity Provider level that the external IdP is rigidly configured to enforce short token lifetimes and explicitly includes both exp and iat claims in every single token payload it signs and issues.

Questions

If you have any questions or comments about this advisory, please email us at security@zitadel.com

Credits

Thanks to Android-Login-Analysis, Jason Zhou and Pedro Giglioti for reporting this vulnerability.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/zitadel/zitadel"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.80.0-v2.20.0.20260615122908-fad02c6d9f45"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-613"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-18T13:52:21Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\n\nTwo closely related token lifecycle validation vulnerabilities were discovered in ZITADEL\u0027s external JWT Identity Provider (IdP) implementation.\n\nSpecifically, within the validation pipeline:\n\n* **Missing Expiration (`exp`) Enforcement:** If an incoming JWT omits the `exp` claim entirely, the expiration block is silently skipped rather than rejected. The token is treated as valid forever.\n* **Missing Issued-At (`iat`) Enforcement:** ZITADEL enforces a 1-hour freshness window (`maxAge`) via the token\u0027s issue time. However, this safety check is guarded by a presence condition. If a token omits the `iat` claim, the freshness check is entirely bypassed, allowing arbitrarily old tokens to pass.\n\nPer the OIDC Core 1.0 specification, identity token validation pipelines must strictly handle and enforce session expiration. ZITADEL\u0027s silent acceptance of tokens missing these temporal constraints compromises session integrity.\n\n### Impact\n\nAn attacker in possession of a token that lacks both `exp` and `iat` claims holds a permanent credential that will never expire and will always be deemed \"fresh\" by the system. Even without combining both flaws, the absence of an expiration constraint means a leaked token effectively turns into a skeleton key for that user session with no automatic revocation window.\n\n### Affected Versions\n\nSystems running one of the following versions are affected:\n\n* **4.x**: `4.0.0` through `4.15.1` (including RC versions)\n* **3.x**: `3.0.0` through `3.4.11` (including RC versions)\n\n### Patches\n\nThe vulnerability has been addressed in the latest releases. ZITADEL now explicitly rejects tokens that lack an `exp` or `iat` claim.\n\n* **4.x**: Upgrade to $\\ge$ [4.15.2](https://github.com/zitadel/zitadel/releases/tag/v4.15.2)\n* **3.x**: Upgrade to $\\ge$ [3.4.12](https://github.com/zitadel/zitadel/releases/tag/v3.4.12)\n\n### Workarounds\n\nThe recommended solution is to update ZITADEL to a patched version.\n\nIf an immediate upgrade is not feasible, ensure at the Identity Provider level that the external IdP is rigidly configured to enforce short token lifetimes and **explicitly includes** both `exp` and `iat` claims in every single token payload it signs and issues.\n\n### Questions\n\nIf you have any questions or comments about this advisory, please email us at [security@zitadel.com](mailto:security@zitadel.com)\n\n### Credits\n\nThanks to [Android-Login-Analysis](https://github.com/Android-Login-Analysis), Jason Zhou and [Pedro Giglioti](https://github.com/Punisher100) for reporting this vulnerability.",
  "id": "GHSA-wxg7-w2v3-w38g",
  "modified": "2026-06-18T13:52:21Z",
  "published": "2026-06-18T13:52:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/security/advisories/GHSA-wxg7-w2v3-w38g"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/commit/fad02c6d9f4587956f830d4536c64a9a94baa7ac"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/zitadel/zitadel"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/releases/tag/v3.4.12"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zitadel/zitadel/releases/tag/v4.15.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": " ZITADEL: Missing Token Lifecyle Validation (`exp` and `iat`) in JWT IdP Provider"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…