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

CVE-2026-54431: liboauth2 Auth Bypass Vulnerability

CVE-2026-54431 is an authentication bypass flaw in liboauth2 where DPoP verification accepts proofs with private key material in the JWK header. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-54431 Overview

CVE-2026-54431 affects liboauth2, an OAuth 2.0 and OpenID Connect library maintained by OpenIDC. The oauth2_token_verify() function fails to reject Demonstrating Proof-of-Possession (DPoP) proofs whose JSON Web Key (jwk) header embeds private key material. RFC 9449 section 4.3 step 7 explicitly requires verifiers to reject such proofs, but the affected versions return success for malformed DPoP proofs containing private Elliptic Curve (EC) keys. The issue is categorized under [CWE-358] (Improperly Implemented Security Check for Standard). The maintainers resolved the flaw in version 2.3.0.

Critical Impact

The DPoP verifier violates RFC 9449 by accepting proofs that expose sender-constrained private key material, weakening the token binding guarantees DPoP is intended to provide.

Affected Products

  • OpenIDC liboauth2 prior to version 2.3.0
  • Applications and reverse proxies embedding liboauth2 for DPoP validation
  • Downstream OAuth 2.0 resource servers relying on oauth2_token_verify() for DPoP-bound access tokens

Discovery Timeline

  • 2026-07-02 - CVE-2026-54431 published to NVD
  • 2026-07-02 - Last updated in NVD database
  • Fix released in liboauth2 version 2.3.0

Technical Details for CVE-2026-54431

Vulnerability Analysis

DPoP binds an OAuth 2.0 access token to a client-held key pair. The client signs a proof JSON Web Token (JWT) with a private key and embeds the corresponding public key in the JWT header jwk parameter. Resource servers verify the proof signature using that public key. RFC 9449 section 4.3 step 7 mandates that verifiers reject any proof where the jwk header contains private key components, because a well-formed proof must expose only the public key.

In affected liboauth2 releases, oauth2_token_verify() performs signature validation without inspecting the jwk header for private key parameters such as the EC d value. A proof carrying a private EC key in the header is accepted as valid. This defeats the assumption that the jwk header exposes only public material and allows malformed proofs to pass validation.

Root Cause

The verifier omits the RFC 9449 step 7 check. When parsing the DPoP proof header, the library does not enumerate jwk members to confirm that private key parameters are absent. Any proof presenting a JWK with embedded private key attributes is treated identically to a compliant proof.

Attack Vector

Exploitation requires a local attack path per the CVSS 4.0 vector, with low complexity and no privileges or user interaction. An attacker crafting a DPoP proof containing a private EC key in the jwk header can submit it to a resource server using liboauth2 and have the proof accepted. Impact is limited to low confidentiality effects because the flaw undermines a specification-mandated defensive check rather than directly disclosing tokens or granting unauthorized access.

text
- dpop: reject a DPoP proof whose jwk header contains private key material
  per RFC 9449 section 4.3 step 7 (CWE-345)
  thanks Michał Majchrowicz and Marcin Wyczechowski, members of the AFINE Team
- bump to 2.2.2dev

Source: GitHub Commit c0b5715

Detection Methods for CVE-2026-54431

Indicators of Compromise

  • DPoP proof JWTs whose decoded header jwk object contains private key parameters such as d for EC keys or p, q, dp, dq, qi for RSA keys.
  • Authentication logs on liboauth2-backed resource servers showing successful DPoP-bound token validations with unusually large proof header sizes.
  • Requests to protected endpoints where the DPoP header carries JWKs with non-standard member counts compared to prior baselines.

Detection Strategies

  • Inventory all services linking against liboauth2 and identify versions prior to 2.3.0 through package managers and software bill of materials tooling.
  • Add a middleware or ingress-layer inspection that parses incoming DPoP headers and flags proofs whose jwk member set intersects with known private key parameter names.
  • Instrument application logging to capture the jwk header thumbprint per validated proof and alert on entries containing private parameters.

Monitoring Recommendations

  • Track liboauth2 version drift across build pipelines and container images to catch reintroduction of vulnerable versions.
  • Correlate DPoP validation successes with anomalous client behavior such as new user agents or geolocation shifts.
  • Monitor upstream advisories from OpenIDC and CERT Polska for related DPoP handling issues.

How to Mitigate CVE-2026-54431

Immediate Actions Required

  • Upgrade liboauth2 to version 2.3.0 or later in all deployments and rebuild any statically linked binaries.
  • Restart resource servers, reverse proxies, and OAuth 2.0 gateways after upgrading to load the patched library.
  • Audit historical DPoP validation logs for proofs containing private key parameters to identify prior misuse.

Patch Information

The fix is delivered in liboauth2 2.3.0. The remediation adds an explicit rejection path when the DPoP proof jwk header contains private key material, restoring compliance with RFC 9449 section 4.3 step 7. See the upstream GitHub commit c0b5715 for the code change and the OpenIDC liboauth2 repository for release artifacts.

Workarounds

  • Deploy an ingress-level filter that rejects DPoP proofs whose decoded jwk header includes private key parameters such as d, p, or q.
  • Constrain DPoP usage to trusted client populations until the patched liboauth2 release is deployed.
  • Rotate any DPoP-bound refresh tokens issued during the exposure window to invalidate proofs already accepted by the vulnerable verifier.
bash
# Verify installed liboauth2 version and upgrade
pkg-config --modversion liboauth2
# Expected output: 2.3.0 or higher

# Example: rebuild from source at the fixed release
git clone https://github.com/OpenIDC/liboauth2.git
cd liboauth2
git checkout v2.3.0
./autogen.sh && ./configure && make && sudo make install

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.