# Postfix — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

Two O(n²) defects in Postfix's SMTP routing and address masquerading. One scans a domain list on every RCPT-TO; the other scans exception and masquerade domain lists per address. Measured at 500× and 200× respectively. Patches ready for upstream review.

## The Defects

**postfix-0001 (PATCHED — HIGH):** `resolve.c:161`

```c
/* Inside resolve_addr() — per RCPT-TO per message: */
/* string_list_match() — O(K) ARGV linear scan */
if (string_list_match(virtual_transport_maps, domain)) { ... }
if (string_list_match(relay_transport_maps, domain)) { ... }
/* O(K) per domain lookup — called for every recipient address */
```

`string_list_match()` performs O(K) linear ARGV scan for virtual/relay domain lookups on every RCPT-TO command. **Measured ratio: 500×.**

**postfix-0002 (PATCHED — HIGH):** `cleanup_masquerade.c:108`

```c
/* Per address in masquerade rewriting: */
/* O(E) exceptions scan + O(D) masq-domains scan per address */
while ((cp = argv_iter(exceptions_iter)) != 0) {
    if (strcmp(cp, domain) == 0) ...  /* O(E) scan */
}
```

Linear scans over exception and masquerade domain lists per address rewrite. **Measured ratio: 200×.**

## Complexity Proof

**postfix-0001:** For K=500 virtual/relay domain entries:
- Per RCPT-TO: O(K) scan
- Fixed: pre-built `HTABLE` hash → O(1) lookup
- **500× measured ratio.**

**postfix-0002:** For E=200 exception entries:
- Per address: O(E) scan
- Fixed: hash cache → O(1) with cache hit
- **200× measured ratio.**

## Impact

All Postfix MTA deployments with virtual domain routing (nearly universal) and address masquerading. postfix-0001 fires on every incoming RCPT-TO for multi-domain setups. postfix-0002 fires on every outgoing message rewrite. Postfix is one of the most widely deployed MTAs on the internet, powering email for millions of domains. High-volume mail servers hit these defects on every message.

## The Fix

**postfix-0001:** Replace `string_list_match()` ARGV scan with `HTABLE` hash:

```c
/* Before */
if (string_list_match(transport_maps, domain)) { ... }  /* O(K) ARGV scan */

/* After */
/* CWE-407 fix: HTABLE for O(1) domain lookup instead of O(K) ARGV scan. */
if (htable_find(transport_htable, domain) != 0) { ... }
```

**postfix-0002:** Cache masquerade domain lookups in an `HTABLE`.

## Patch

`defects/postfix/patch/postfix-0001-0002-domain-htable.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your routing and masquerade test suites.
3. Assess CVE eligibility — postfix-0001 fires on every RCPT-TO on multi-domain servers.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.
