# Forge has signature forgery in RSA-PKCS due to ASN.1 extra field

node-forge's RSASSA-PKCS1-v1_5 verify accepts forged signatures for e=3 keys by allowing extra ASN.1 garbage and <8 padding bytes, enabling Bleichenbacher forgery.

- Payout: Research
- Severity: high
- Program: node-forge
- Found by: corbanvilla, dderpym, sohcato
- Disclosed: 2026-03-26
- CVE: CVE-2026-33894
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-ppp5-5v6c-4jwp
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-ppp5-5v6c-4jwp
- Tags: area:oss domain:oss impact:integrity kind:research platform:ghsa sev:high tech:nodejs technique:parser-differential technique:source-review vuln:crypto vuln:signature-replay

**Target:** lib/rsa.js key.verify / _decodePkcs1_v1_5
**Root cause:** The verifier only checks that all DER bytes are consumed, not that DigestInfo is the canonical minimal shape, so attacker-controlled extra ASN.1 content inside the container passes. _decodePkcs1_v1_5 also fails to enforce the RFC-mandated minimum 8 bytes of padding.
**Steps:**
1. Generate RSA keypair with modulusLength 4096 and publicExponent 3.
2. Build EM prefix `00 01` + ffCount 0xff bytes + `00` + `30 <len>` + SHA-256 DigestInfo + `04 <len>` + garbageLen bytes, iterating garbageLen so total EM length equals k.
3. Compute interval [low, high) of EM values starting with that prefix; find s = cbrtCeil(low) such that s^3 lands in the interval.
4. Submit sig = s padded to k bytes to `key.verify(digest, sig, undefined, {_parseAllDigestBytes: true})`.
5. Observe forge returns true while Node/OpenSSL `crypto.verify` with RSA_PKCS1_PADDING returns false.
**How found:** Researchers compared forge's DER parsing semantics against OpenSSL and noticed strict byte-consumption does not imply canonical DigestInfo shape; also spotted the unimplemented PS>=8 check comment in _decodePkcs1_v1_5, mirroring CVE-2022-24771 but with bytes inside the ASN.1 container.
**Exploitation:** Attacker with a target e=3 public key constructs a forged signature by cube-root interval search over an EM whose DigestInfo container carries extra ASN.1 bytes (and optionally <8 padding bytes), so forge accepts a signature the attacker never had a private key for. Enables forging signed messages/tokens verified by forge.
**Insight:** When auditing signature verifiers, differential-test against OpenSSL and check whether 'strict' parsing enforces canonical minimal DER structure, not just full byte consumption; also verify spec-mandated padding-length minimums are actually coded, not just commented.

