Skip to content

Check the signature hash in the python-rsa RSAKey.verify - #429

Open
neeraj1235476 wants to merge 1 commit into
mpdavis:masterfrom
neeraj1235476:rsa-verify-hash-alg
Open

neeraj1235476 wants to merge 1 commit into
mpdavis:masterfrom
neeraj1235476:rsa-verify-hash-alg

Conversation

@neeraj1235476

Copy link
Copy Markdown

With only the default dependencies installed (python-rsa backend), an RS256 allowlist accepts signatures made with other digests:

>>> sig = rsa.sign(signing_input, priv, "MD5")   # also SHA-1, SHA-512
>>> jwt.decode(token, pub_pem, algorithms=["RS256"])
{'sub': 'admin'}

RSAKey.verify in jose/backends/rsa_backend.py calls rsa.verify(), which takes the hash algorithm from the DigestInfo inside the signature and returns its name. The key's hash_alg was never compared, so the header alg and the algorithms allowlist did not bind the digest that was checked (RFC 7518 section 3.3 fixes RS256 to SHA-256). Any PKCS#1 v1.5 signature the key holder ever made over MD5 or SHA-1, in any protocol, verified as RS256. The cryptography backend already passes the hash explicitly, so this brings the pure-Python backend in line with it.

The fix compares the returned hash name with self.hash_alg. The new test signs with MD5, SHA-1 and SHA-512 and expects an RS256 key to reject each. It fails on master and passes with the change. The full suite and tox -e lint pass locally. test_incorrect_public_key_hmac_signing in test_EC.py fails the same way on master.

rsa.verify() reads the hash algorithm from the DigestInfo in the
signature and returns its name, so an RS256 key accepted PKCS#1 v1.5
signatures over MD5, SHA-1 or SHA-512 made by the same key. Compare
the returned name with the key's hash_alg.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant