# Patch Analysis: CVE-2026-34752 Prototype Pollution Fix

## Summary
The vulnerability in haraka-email-message v1.2.0 was fixed in v1.3.1 with a defense-in-depth approach.

## Vulnerability (v1.2.0 and earlier)
In the `_add_header()` method:
```javascript
_add_header(key, value, method) {
    this.headers[key] ??= []          // Line 216
    this.headers[key][method](value)  // Line 217
}
```

When `key` is `__proto__`:
1. `this.headers['__proto__']` returns `Object.prototype` (the object's prototype)
2. `Object.prototype` is truthy, so `??=` is skipped
3. `Object.prototype.push(value)` throws `TypeError: not a function`

## The Fix (v1.3.1+)

### Fix 1: Belt - Object.create(null)
Changed from:
```javascript
constructor(options) {
    this.headers = {}
    this.headers_decoded = {}
```

To:
```javascript
constructor(options) {
    this.headers = Object.create(null)
    this.headers_decoded = Object.create(null)
```

This creates objects with NO prototype, so `this.headers['__proto__']` returns `undefined` instead of `Object.prototype`.

### Fix 2: Suspenders - Explicit Guards
Added guards in both `_add_header()` and `_add_header_decode()`:
```javascript
_add_header(key, value, method) {
    if (['__proto__', 'constructor', 'prototype'].includes(key)) return
    this.headers[key] ??= []
    this.headers[key][method](value)
}
```

This explicitly blocks three dangerous keys:
- `__proto__` - Could access/modify Object.prototype
- `constructor` - Could access/modify the constructor
- `prototype` - Could access/modify the prototype property

## Fix Assumptions and Potential Gaps

1. **Case Sensitivity**: The guard uses exact string matching: `['__proto__', 'constructor', 'prototype'].includes(key)`. Since JavaScript property access is case-sensitive, variations like `__PROTO__`, `__Proto__`, `Constructor`, `PROTOTYPE` would NOT match the guard. However, due to Fix 1 (Object.create(null)), these variations would also not return a prototype object - they would return `undefined`.

2. **Entry Points**: The guards are placed in `_add_header()` and `_add_header_decode()`, which are called from:
   - `parse()` - called with `match[1].toLowerCase()` (lowercase transformation applied)
   - `add()` - called with `key.toLowerCase()` (lowercase transformation applied)
   - `add_end()` - called with `key.toLowerCase()` (lowercase transformation applied)

3. **Key Lowercasing**: All entry points normalize keys to lowercase via `.toLowerCase()`, which prevents case-based bypass attempts since the guard checks lowercase versions.

## Variant Testing Strategy

1. **Case Variation Test**: Even though keys are lowercased, test edge cases where `.toLowerCase()` might behave unexpectedly
2. **Alternative Entry Points**: Check if there are any other methods that directly manipulate headers without the guards
3. **Unicode/Encoding Test**: Test if encoded versions of `__proto__` could bypass the check
4. **Property Descriptor Test**: Test if Object.defineProperty or similar could bypass the guards

## Assessment
The fix is comprehensive for this specific attack vector. The combination of:
- `Object.create(null)` removing the prototype chain entirely
- Explicit guards for the three dangerous keys
- Key normalization via `.toLowerCase()`

Makes this a robust fix that would be difficult to bypass through header key manipulation.
