high · 7.5 Patched

postal-mime: Quadratic CPU consumption when decoding a header of many joinable RFC 2047 base64 encoded words

GHSA-f2hq-32vh-53cc · published 23 Oct 2026

How serious is it

  • Severity: high, CVSS score 7.5 out of 10.
  • No exploit prediction (EPSS) score yet.
  • Not on the CISA list of exploited vulnerabilities.
  • No public exploit in Exploit-DB.

Is your app affected by GHSA-f2hq-32vh-53cc?

Paste this prompt into Claude Code, Cursor or any AI coding tool: it runs a free Shippable scan of your project and fixes what it finds. Built with Lovable, Bolt or v0? Scan your live app. Or upload your package file.

Who is affected

  • postal-mime (npm) >= 3.0.0, < 4.0.8

How to check

  1. Run npm ls postal-mime in your project to see the installed version, including copies pulled in by other packages.
  2. Or paste your lockfile into the checker: it lists every package with a known vulnerability, this one included.
  3. Or run npx shippable-dev scan localhost:3000 in your project folder. It reads your lockfile and flags this vulnerability along with every other known one.

How to fix

Copies a prompt for Claude Code, Cursor or Codex: it checks your lockfiles for this and upgrades it.
  1. Upgrade postal-mime to 4.0.8 or later, commit the lockfile and redeploy.
  2. If a vulnerable version was live, check your logs and rotate the secrets that server could read.

The advisory

### Impact Decoding a header that holds a long run of joinable RFC 2047 base64 encoded words, such as `=?utf-8?B?QUJD?=` repeated tens of thousands of times in a `Subject`, `From`, `To`, a filename or a description, took time quadratic in the number of words. The join check ran a regex over the text joined so far for every word, which flattens the accumulated string each time. A single well formed message of about 1.6 MB blocked the event loop for one to twenty seconds depending on the host, and inline `message/rfc822` parts multiplied the cost, since each nested message carried its own header budget. Any application that parses untrusted mail with postal-mime 3.0.0 through 4.0.7, including the exported `decodeWords()` helper, is affected. There is no confidentiality or integrity impact. ### Patches Fixed in 4.0.8. The pad check now tracks the last appended word instead of testing the joined text, so decoding is linear in the header length. The same release also counts the parts and header bytes of inline `message/rfc822` sub-messages against the limits of the message as a whole, counts every header line for at least 64 bytes of `maxHeadersSize`, and adds a scaling test that measures every stage of the parser at two input sizes. ### Workarounds Lower `maxHeadersSize` from its 2 MiB default to bound the cost per message, or parse untrusted mail in a worker that can be terminated. ### Credits Reported by Felipe Fernández.

Check your whole app

Dependencies are only half of it. Free and read-only: before you push, run npx shippable-dev scan localhost:3000 in your project folder, no account needed. For your live app, you prove it's yours with a one-line tag first.

References

Merged from GitHub Advisory Database, OSV. Last updated 26 Oct 2026. All vulnerabilities · RSS · JSON