Improper Handling of Highly Compressed Data (Data Amplification) Affecting jose package, versions >=1.0.0 <1.11.13


Severity

Recommended
0.0
medium
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
0.25% (17th percentile)

Do your applications use this vulnerable package?

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 applications
  • Snyk IDSNYK-HEX-JOSE-21755411
  • published27 Oct 2026
  • disclosed26 Oct 2026
  • creditPeter Ullrich

Introduced: 26 Oct 2026

NewCVE-2026-65627  (opens in a new tab)
CWE-409  (opens in a new tab)

How to fix?

Upgrade jose to version 1.11.13 or higher.

Overview

Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification) via jose_jwe_zip:uncompress/2, which calls zlib:inflate/2 on attacker-controlled raw-DEFLATE data with no bound on output size or inflation ratio. When a JWE token carries a zip:"DEF" protected header, decryption automatically routes the ciphertext through this function, allowing an attacker to supply a token of a few kilobytes that forces the victim node to allocate hundreds of megabytes. For RSA-OAEP and ECDH-ES key agreement algorithms, the attacker requires only the recipient's public key to produce a token with a valid AEAD tag, achieving amplification of up to approximately 772x of token bytes with no cap.

PoC

The attached script encodes an outside-attacker threat model in which the attacker holds only the recipient's RSA public key.

On the attacker side, the script generates a recipient RSA-2048 key pair and keeps only the public half (JOSE.JWK.to_public/1), mirroring what an outside attacker would have for RSA-OAEP or ECDH-ES. It builds a plaintext of 256 MiB of zero bytes — trivially compressible — and encrypts it with the header %{"alg" => "RSA-OAEP", "enc" => "A128GCM", "zip" => "DEF"}. The zip: "DEF" header forces DEFLATE compression, so the resulting compact token (JOSE.JWE.compact/1) is only a few kilobytes. The script prints that token's byte size to show how small the malicious payload is.

On the victim side, the script crosses the trust boundary by calling JOSE.JWE.block_decrypt(recipient_private, malicious_token) on the attacker-supplied compact token. Inside that call, jose sees the zip: "DEF" header and routes the decrypted plaintext through jose_jwe_zip:uncompress/2, which invokes the unbounded zlib:inflate/2. This is the exact mechanism: the small compressed field is inflated to its full 256 MiB with no cap.

The script measures :erlang.memory(:total) before and after decryption and computes both the decompressed size and the amplification factor (decompressed bytes divided by token bytes). It prints VERIFIED only when the plaintext is at least 256 MiB and the measured memory delta exceeds 100 MB:

if decompressed >= 256 * 1024 * 1024 and delta_mb > 100 do

Seeing this line together with a multi-thousand-fold amplification factor demonstrates that a tiny token, craftable with only the recipient's public key, forces the victim to allocate hundreds of MB during a single decrypt. The full script is attached below under "Scripts and Logs" so the reader can run it directly.

Note: The PoC states no specific environment, OS, or runtime version beyond the use of RSA-OAEP with A128GCM and a 256 MiB zero-byte plaintext compressed with DEF.

CVSS Base Scores

version 4.0
version 3.1