{"repro_id":"REPRO-2026-00128","version":2,"title":"Haraka Mail Server DoS via __proto__ prototype pollution in email headers","repro_type":"security","status":"published","severity":"high","description":"DoS via unsafe header key handling leading to uncaught exception","root_cause":"# Root Cause Analysis: CVE-2026-34752\n\n## Summary\n\nCVE-2026-34752 is a Denial of Service vulnerability in the haraka-email-message library (v1.2.0 and earlier). The vulnerability occurs in the `Header.parse()` method when processing email headers with the key `__proto__`. Due to unsafe property assignment using `this.headers[key]`, accessing `this.headers['__proto__']` returns `Object.prototype` instead of a normal array. This causes the subsequent `this.headers[key][method](value)` call (where method is \"push\") to fail with a TypeError, as `Object.prototype.push` is not a function. This uncaught exception can crash the entire application.\n\n## Impact\n\n- **Package**: haraka-email-message\n- **Affected Versions**: 1.2.0 and earlier (bundled with Haraka@3.1.3)\n- **Fixed Versions**: 1.3.2 (latest as of March 2026)\n- **Risk Level**: High\n- **Consequences**: \n  - Application crash/DoS via prototype pollution\n  - Uncaught TypeError terminates Node.js process\n  - In Haraka SMTP server context: single-process mode causes full server crash, cluster mode kills worker processes\n\n## Root Cause\n\nThe vulnerability exists in `lib/header.js` (in v1.2.0 bundled in `index.js`) in the `_add_header()` function at lines 150-151:\n\n```javascript\n_add_header (key, value, method) {\n    this.headers[key] = this.headers[key] || [];\n    this.headers[key][method](value);\n}\n```\n\nWhen `key` is `__proto__`:\n1. `this.headers['__proto__']` returns `Object.prototype` (the object's prototype chain)\n2. `Object.prototype` is truthy, so the `|| []` short-circuit is not executed\n3. `this.headers['__proto__']` evaluates to `Object.prototype`\n4. `Object.prototype['push'](value)` is called, but `Object.prototype.push` is `undefined`/not a function\n5. TypeError is thrown: \"this.headers[key][method] is not a function\"\n\nThe `Header.parse()` method calls `_add_header(key, val, \"push\")` for each header line parsed, making it the attack vector for converting malicious email documents into internal structures.\n\n**Fix**: The patched version uses `Object.create(null)` for the headers object or validates/sanitizes header keys to prevent prototype pollution.\n\n## Reproduction Steps\n\nThe reproduction script `repro/reproduction_steps.sh`:\n\n1. Installs the vulnerable haraka-email-message@1.2.0 package\n2. Creates a Node.js harness that imports the library\n3. First tests normal headers to confirm baseline functionality\n4. Then tests malicious headers containing `__proto__: crash`\n5. Confirms the TypeError is thrown as expected\n\n**Execution**:\n```bash\n./repro/reproduction_steps.sh\n```\n\n**Expected Evidence**:\n- Normal headers parse successfully\n- Malicious headers with `__proto__` key cause TypeError: \"this.headers[key][method] is not a function\"\n- Crash evidence saved to `artifacts/crash_evidence.json`\n\n## Evidence\n\n**Log Files**:\n- `logs/npm_install.log` - Package installation log\n- `logs/exploit.log` - Exploit execution log showing the crash\n\n**Key Excerpt from exploit.log**:\n```\n[+] Test 2: Parsing malicious headers with __proto__ key...\n[+] This triggers the prototype pollution vulnerability in _add_header()\n[+] CRASH CONFIRMED!\n[+] Error type: TypeError\n[+] Error message: this.headers[key][method] is not a function\n[+] This matches the expected vulnerability behavior\n```\n\n**Crash Evidence** (artifacts/crash_evidence.json):\n```json\n{\n  \"vulnerability\": \"CVE-2026-34752\",\n  \"library\": \"haraka-email-message\",\n  \"version\": \"1.2.0\",\n  \"entrypoint\": \"Header.parse()\",\n  \"trigger\": \"__proto__ header key\",\n  \"error\": {\n    \"type\": \"TypeError\",\n    \"message\": \"this.headers[key][method] is not a function\"\n  }\n}\n```\n\n**Environment**:\n- Node.js version: v18.x (from container)\n- Library version: haraka-email-message@1.2.0\n- OS: Linux (container environment)\n\n## Recommendations / Next Steps\n\n**Fix Approach**:\n1. Use `Object.create(null)` instead of `{}` for the `this.headers` object to create a prototype-less object\n2. Sanitize all header keys to reject or escape `__proto__`, `constructor`, and `prototype` keys\n3. Use a Map instead of plain objects for header storage\n\n**Upgrade Guidance**:\n- Upgrade to haraka-email-message@1.3.2 or later\n- If using Haraka SMTP server, upgrade to v3.1.4 or later which includes the patched library\n\n**Testing Recommendations**:\n1. Add unit tests for prototype pollution attempts in header parsing\n2. Test with malicious header keys: `__proto__`, `constructor`, `prototype`\n3. Implement input validation for all user-controlled data that becomes object keys\n\n## Additional Notes\n\n**Idempotency**: The reproduction script is fully idempotent. It creates a fresh test directory `/tmp/haraka_lib_test` each run and cleans up after itself.\n\n**Edge Cases Tested**:\n- Normal email headers: Parse successfully\n- Malicious `__proto__` header: Confirmed crash\n\n**Limitations**:\n- The reproduction demonstrates the library-level vulnerability in isolation\n- In a real Haraka SMTP server deployment, the exploit would require sending an actual email via SMTP with the malicious header\n- The impact in production depends on process configuration (single vs cluster mode)\n","cve_id":"CVE-2026-34752","cwe_id":"CWE-248 Uncaught Exception","source_url":"https://github.com/advisories/GHSA-xph3-r2jf-4vp3","package":{"name":"npm/Haraka","ecosystem":"github","affected_versions":"< 3.1.4 (last known affected <= 3.1.3)"},"reproduced_at":"2026-04-04T12:49:04.556446+00:00","duration_secs":1025.0,"tool_calls":155,"handoffs":3,"quality":{"idempotent_verified":false,"community_verifications":0},"published_at":"2026-04-04T12:49:05.066896+00:00","retracted":false,"artifacts":[{"path":"repro/rca_report.md","filename":"rca_report.md","size":5095,"category":"analysis"},{"path":"repro/reproduction_steps.sh","filename":"reproduction_steps.sh","size":5088,"category":"reproduction_script"},{"path":"vuln_variant/rca_report.md","filename":"rca_report.md","size":6318,"category":"analysis"},{"path":"vuln_variant/reproduction_steps.sh","filename":"reproduction_steps.sh","size":12117,"category":"reproduction_script"},{"path":"coding/proposed_fix.diff","filename":"proposed_fix.diff","size":926,"category":"patch"},{"path":"bundle/ticket.json","filename":"ticket.json","size":3470,"category":"other"},{"path":"bundle/AGENTS.repro.md","filename":"AGENTS.repro.md","size":686,"category":"documentation"},{"path":"bundle/ticket.md","filename":"ticket.md","size":2928,"category":"ticket"},{"path":"repro/runtime_manifest.json","filename":"runtime_manifest.json","size":554,"category":"other"},{"path":"repro/validation_verdict.json","filename":"validation_verdict.json","size":661,"category":"other"},{"path":"logs/npm_install.log","filename":"npm_install.log","size":138,"category":"log"},{"path":"logs/exploit.log","filename":"exploit.log","size":564,"category":"log"},{"path":"vuln_variant/variant_manifest.json","filename":"variant_manifest.json","size":2034,"category":"other"},{"path":"vuln_variant/source_identity.json","filename":"source_identity.json","size":778,"category":"other"},{"path":"vuln_variant/patch_analysis.md","filename":"patch_analysis.md","size":3360,"category":"documentation"},{"path":"vuln_variant/validation_verdict.json","filename":"validation_verdict.json","size":1999,"category":"other"},{"path":"logs/variant_test.log","filename":"variant_test.log","size":7446,"category":"log"},{"path":"logs/npm_vuln.log","filename":"npm_vuln.log","size":414,"category":"log"},{"path":"logs/npm_fixed.log","filename":"npm_fixed.log","size":429,"category":"log"},{"path":"coding/verify_fix.log","filename":"verify_fix.log","size":666,"category":"log"},{"path":"coding/verify_fix.sh","filename":"verify_fix.sh","size":2826,"category":"other"},{"path":"coding/summary_report.md","filename":"summary_report.md","size":2251,"category":"documentation"}]}