Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-75509

CVE-2026-75509: joserfc Authentication Bypass Vulnerability

CVE-2026-75509 is an authentication bypass flaw in joserfc Python library that allows attackers to bypass issuer validation through array-valued claims. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-75509 Overview

CVE-2026-75509 is an issuer-validation bypass in joserfc, a Python library implementing JSON Object Signing and Encryption (JOSE) standards including JWT, JWS, and JWE. Versions prior to 1.7.3 apply membership matching to list-valued iss and sub claims. An array-valued iss that contains the expected issuer passes an intended equality check, allowing an attacker to bypass issuer validation with a crafted JWT. The maintainers fixed the issue in version 1.7.3 by enforcing type validation that requires iss and sub to be StringOrURI scalar values per RFC 7519. The weakness is classified as [CWE-290] Authentication Bypass by Spoofing.

Critical Impact

A crafted JWT containing an array iss value that includes the expected issuer bypasses the JWTClaimsRegistry equality check, enabling identity spoofing against services relying on joserfc for issuer validation.

Affected Products

  • joserfc Python library versions prior to 1.7.3
  • Applications using JWTClaimsRegistry for iss or sub claim validation
  • Downstream services performing JWT-based authentication with joserfc

Discovery Timeline

  • 2026-08-24 - CVE-2026-75509 published to NVD
  • 2026-08-25 - Last updated in NVD database

Technical Details for CVE-2026-75509

Vulnerability Analysis

The JWTClaimsRegistry class in joserfc validates registered JWT claims including iss (issuer) and sub (subject). RFC 7519 defines both as StringOrURI scalar values. The pre-patch implementation used a membership check (in) when comparing claim values against expected values. When a token supplies iss as a JSON array rather than a string, the membership operator evaluates whether the expected issuer is present in the list rather than performing a strict equality comparison. An attacker who controls a token signing path can therefore include the trusted issuer inside an array alongside arbitrary values and defeat issuer validation.

Root Cause

The root cause is a missing type constraint on the iss and sub claims combined with permissive membership matching. joserfc did not enforce that these claims must be strings before performing the comparison. The fix in src/joserfc/_rfc7519/claims.py adds explicit validate_iss, validate_sub, and validate_aud methods that raise InvalidClaimError when the value is not a StringOrURI string.

Attack Vector

Exploitation is network-based and requires no authentication or user interaction. An attacker crafts a JWT whose payload sets iss (or sub) to a JSON array such as ["https://trusted-issuer.example", "attacker-controlled"]. When the relying party calls JWTClaimsRegistry validation with an expected issuer of "https://trusted-issuer.example", the membership check returns true. Downstream authorization logic then treats the token as issued by the trusted authority.

python
// Security patch in src/joserfc/_rfc7519/claims.py
// Source: https://github.com/authlib/joserfc/commit/76ee6a59bf5773c0af00b99076c5e199031f97f1
            return self._now()
        return self._now

    def validate_iss(self, value: str) -> None:
        """The "iss" (issuer) claim identifies the principal that issued the
        JWT.  The processing of this claim is generally application specific.
        The "iss" value is a case-sensitive string containing a StringOrURI
        value.  Use of this claim is OPTIONAL.
        """
        if not isinstance(value, str):
            raise InvalidClaimError("str", "Claim 'str' must be a StringOrURI value")
        self.check_value("iss", value)

    def validate_sub(self, value: str) -> None:
        """The "sub" (subject) claim identifies the principal that is the
        subject of the JWT.  The claims in a JWT are normally statements
        about the subject.  The subject value MUST either be scoped to be
        locally unique in the context of the issuer or be globally unique.
        """
        if not isinstance(value, str):
            raise InvalidClaimError("sub", "Claim 'sub' must be a StringOrURI value")
        self.check_value("sub", value)

Source: GitHub Commit 76ee6a5

Detection Methods for CVE-2026-75509

Indicators of Compromise

  • JWT payloads where the iss claim decodes to a JSON array instead of a string
  • JWT payloads where the sub claim decodes to a JSON array or non-string type
  • Authentication events referencing an expected trusted issuer but originating from unexpected client identities or IP ranges

Detection Strategies

  • Inventory Python applications and container images to identify joserfc versions below 1.7.3 using SBOM and dependency scanning tools.
  • Add JWT payload inspection at API gateways or reverse proxies to reject tokens whose iss or sub claims are not JSON strings.
  • Correlate authentication logs against expected issuer patterns and alert when token issuer types deviate from RFC 7519 StringOrURI.

Monitoring Recommendations

  • Log the decoded JWT header and claim types on authentication endpoints for post-hoc analysis of malformed claims.
  • Alert on InvalidClaimError exceptions after upgrading to 1.7.3, as a spike indicates active probing.
  • Track dependency drift for joserfc across CI/CD pipelines to prevent regression to vulnerable versions.

How to Mitigate CVE-2026-75509

Immediate Actions Required

  • Upgrade joserfc to version 1.7.3 or later in all Python environments, virtualenvs, and container images.
  • Audit application code that calls JWTClaimsRegistry to confirm expected issuer and subject values are configured.
  • Rotate signing keys and revoke long-lived tokens if logs indicate array-typed iss or sub claims were accepted.

Patch Information

The fix is committed in 76ee6a59bf5773c0af00b99076c5e199031f97f1 and released in joserfc 1.7.3. The patch adds validate_iss, validate_sub, and validate_aud methods that enforce StringOrURI typing before comparison. Details are published in GitHub Security Advisory GHSA-r74j-q665-7rpj.

Workarounds

  • Wrap JWTClaimsRegistry calls with a pre-check that rejects any decoded token whose iss or sub claim is not an instance of str.
  • Enforce strict issuer allow-listing at an upstream gateway so that only exact string matches are forwarded to the application.
  • Reduce JWT lifetimes and require re-authentication to limit the window for token replay while upgrades roll out.
bash
# Upgrade joserfc to the patched release
pip install --upgrade 'joserfc>=1.7.3'

# Verify installed version
python -c "import joserfc; print(joserfc.__version__)"

# Optional: pin the minimum version in requirements.txt
echo 'joserfc>=1.7.3' >> requirements.txt

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.