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

CVE-2026-13089: OIDC::Lite Auth Bypass Vulnerability

CVE-2026-13089 is an authentication bypass flaw in OIDC::Lite for Perl that allows ID Token signature verification bypass through algorithm manipulation. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-13089 Overview

CVE-2026-13089 is a signature verification bypass in OIDC::Lite versions through 0.12.1 for Perl. The flaw allows attackers to forge OpenID Connect ID Tokens and authenticate as any user against Relying Parties that use the library. The vulnerability stems from OIDC::Lite::Model::IDToken::verify trusting the algorithm identifier taken from the untrusted token header. Attackers can supply alg=none to skip signature checks or alg=HS256 to trigger RS-to-HS key confusion against the RP's RSA public key. This is classified under [CWE-347: Improper Verification of Cryptographic Signature].

Critical Impact

An unauthenticated remote attacker can forge ID Tokens with attacker-chosen claims (such as sub) and be authenticated as arbitrary users on any Relying Party using the unpinned verification path.

Affected Products

  • OIDC::Lite for Perl versions through 0.12.1 (git repository)
  • OIDC::Lite CPAN release 0.10 (latest CPAN version)
  • Any Perl Relying Party application using load(token)->verify or load(token, key) without pinning an explicit algorithm

Discovery Timeline

  • 2026-07-22 - CVE-2026-13089 published to NVD
  • 2026-07-22 - Openwall OSS-Security disclosure published
  • 2026-07-22 - Last updated in NVD database

Technical Details for CVE-2026-13089

Vulnerability Analysis

The vulnerability exists in OIDC::Lite::Model::IDToken::verify. When the caller does not pin an algorithm, the method executes $self->alg($self->header->{alg}), populating the algorithm field from the untrusted token header. It then calls decode_jwt(token, key, 1, [$self->alg]), handing JSON::WebToken an accepted-algorithm allowlist derived from the attacker-controlled token.

This pattern violates guidance in IETF RFC 8725 Section 3.1, which requires Relying Parties to determine acceptable algorithms out of band and never trust the alg header value.

Root Cause

The root cause is trust in an attacker-controlled JWT header field. The library uses the token's own alg claim to build the allowlist that authorizes its own verification. This circular trust removes any effective signature check when the caller does not explicitly pin an algorithm.

Attack Vector

Two concrete exploitation paths exist against the unpinned verification flow. First, an attacker submits an ID Token with alg=none, which produces the allowlist ['none']. decode_jwt returns the claims without any signature verification. Second, an attacker submits an ID Token signed with HS256, causing the library to verify the HMAC using the RP's RSA public key as the shared secret. Because the RSA public key is typically discoverable through the OpenID Connect JWKS endpoint, the attacker can compute a valid HMAC and forge any claims, including sub.

Callers that pass an explicit algorithm so $self->alg is set before verify runs are not affected, because the header-derived allowlist is bypassed. See the GitHub Pull Request #31 for the fix and the Openwall OSS-Security Discussion for further details.

Detection Methods for CVE-2026-13089

Indicators of Compromise

  • Authentication events where the ID Token JWT header contains alg: none or alg: HS256 while the RP is configured to expect an RSA-family algorithm such as RS256.
  • Successful authentications with ID Tokens whose signatures cannot be re-verified against the identity provider's published JWKS using the expected algorithm.
  • Sessions where the authenticated sub claim does not correspond to any prior authorization request or PKCE state issued by the RP.

Detection Strategies

  • Inspect application logs and reverse proxy captures for JWTs whose header decodes to {"alg":"none"} or {"alg":"HS256"} on OIDC callback endpoints.
  • Instrument the RP callback handler to log the alg value and cryptographic outcome for every ID Token, then alert on any algorithm mismatch versus the provider's advertised signing algorithms.
  • Perform a source code audit for calls to OIDC::Lite::Client::load($token)->verify or load($token, $key) without an explicit algorithm argument.

Monitoring Recommendations

  • Enable verbose OIDC transaction logging that captures the full JOSE header of every received ID Token for post-hoc analysis.
  • Correlate ID Token acceptance events with corresponding authorization requests to detect tokens accepted without matching state or nonce values.
  • Monitor CPAN and the upstream git repository for new OIDC::Lite releases and integrate version telemetry into software inventory dashboards.

How to Mitigate CVE-2026-13089

Immediate Actions Required

  • Audit all Perl code invoking OIDC::Lite and pass an explicit algorithm to verify, ensuring $self->alg is set before the header-derived allowlist can execute.
  • Apply the vendor patch published at Metacpan Patch for CVE-2026-13089 to all deployed installations.
  • Invalidate active sessions established through the vulnerable code path and require reauthentication using the fixed configuration.

Patch Information

The upstream fix is tracked in GitHub Pull Request #31, and a backport patch for CPAN version 0.10 is available at Metacpan Patch for CVE-2026-13089. Note that the latest CPAN release is 0.10 while later versions up to 0.12.1 are only available in the git repository, so operators must confirm which source their deployment uses before patching.

Workarounds

  • Pin the expected algorithm at every call site by using load($token, $key, $expected_alg) or by setting alg on the IDToken object before calling verify.
  • Reject any ID Token whose header alg is not on a server-side allowlist of RSA or ECDSA algorithms before invoking OIDC::Lite verification.
  • Follow IETF RFC 8725 Section 3.1 guidance and configure a fixed algorithm per issuer rather than reading alg from the token.
bash
# Configuration example: pin the algorithm explicitly at the call site
# Vulnerable pattern (do not use):
#   my $id_token = OIDC::Lite::Client::load($token)->verify;
#
# Fixed pattern: pass the expected algorithm so the header-derived
# allowlist is bypassed.
#   my $id_token = OIDC::Lite::Model::IDToken->load($token);
#   $id_token->alg('RS256');           # pin before verify
#   $id_token->verify($rsa_public_key);

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.