← Blog
Article

Bun Security in 2026: The Brotli RCE, Bun 1.4.4 and How to Harden bun install

Bun security in 2026: the Brotli RCE (CVE-2026-111497) fixed in Bun 1.4.4, two more advisories, why npm worms ship Bun, and how to harden bun install.
11 min readSecurityBunJavaScriptSupply Chain

By Assim ElHammouti, Founder and Lead Engineer, NordbeamPublished Updated

Short answer

Which Bun vulnerabilities matter right now?

The most serious Bun vulnerability of 2026 is CVE-2026-111497, an out-of-bounds write in the Brotli decoder that Bun bundles, reachable by fetching from a malicious server. Bun 1.4.4, released on 22 October 2026, fixes it along with two other High-severity issues. Run bun upgrade and rebuild compiled executables. Compiled by Nordbeam, a development studio in Gothenburg and Malmö.

Patch to
Bun 1.4.4 or later
Affected
Bun 1.0.21 up to 1.4.3
Also rebuild
bun build --compile binaries

Bun publishes far fewer security advisories than Node.js or PHP. Until this month, its GitHub advisory page was empty for 2026. Then, on 23 and 24 October 2026, three High-severity advisories landed at once, all fixed in Bun 1.4.4. The most serious is the same Brotli bug that Node.js fixed a day earlier, because both runtimes bundle the same Google library.

Bun was in the security news for another reason this year too. The biggest npm worms of 2026 brought their own copy of Bun to run their payloads. That is not a Bun vulnerability, but it changes what "Bun is installed on this machine" should mean to a security team.

This article covers both, then compares Bun's install-time defaults with npm's. If you also run Node.js, PHP or Ruby, we have written the same roundup for Node.js, PHP and Ruby and Rails.

What is the most serious Bun vulnerability right now?

CVE-2026-111497, an out-of-bounds write in the Brotli decoder bundled with Bun. It affects Bun 1.0.21 up to 1.4.3 and is fixed in Bun 1.4.4. Bun's advisory, GHSA-663w-cv8g-jj2p, rates it High and was published on 23 October 2026. Google, which assigned the CVE, rates the underlying library bug Critical, CVSS v4.0 9.2 (NVD).

The bug is in Google's Brotli library, not in Bun's own code. A crafted Brotli stream makes the decoder write past an internal buffer. That can corrupt memory, leak it, crash the process or potentially lead to code execution. Bun 1.4.4 updates the bundled Brotli from 1.2.0 to 1.2.1, which contains the fix.

In Bun, these APIs reach the vulnerable decoder:

  • fetch(). Bun sends Accept-Encoding with br by default and decodes Content-Encoding: br responses automatically. In the advisory's words, "a server that an application connects to can therefore send data to the decoder." On plain HTTP, so can anyone in the network path.
  • node:zlib: brotliDecompress, brotliDecompressSync and createBrotliDecompress.
  • DecompressionStream with the brotli format.
  • Executables built with bun build --compile. They embed the runtime, so they stay vulnerable until you rebuild them with 1.4.4.

The fetch() path is the one to worry about. Any Bun service that fetches URLs it does not control is exposed through ordinary HTTP calls: webhooks, link previews, scrapers, AI agents with a browsing tool. There is no process-wide workaround. You can pass decompress: false to individual fetch() calls until you upgrade, but the fix is the upgrade.

1.4.4

The Bun release that fixes every 2026 advisory (22 October 2026)

3
High-severity advisories: the Brotli decoder, compromised emSign CAs, HTTP/3 QPACK
1.0.21
the oldest Bun version affected by the Brotli bug
0
process-wide workarounds for the Brotli bug, per Bun's advisory

Is the Bun Brotli bug the same as the Node.js one?

Yes. It is one CVE in a shared library, fixed separately by every project that bundles it. Google Brotli 1.0.3 to 1.2.0 contain the bug. The upstream fixes are Brotli 1.0.10, 1.1.1 and 1.2.1. The GitHub Advisory Database entry nicknames it "Node2Shell", because it surfaced through the Node.js security release of 21 October.

One library bug, three runtimes
Upstream library

Google Brotli 1.0.3 to 1.2.0

The bug

Decoder out-of-bounds write

c/dec/decode.c · CVE-2026-111497

The fix

Brotli 1.0.10, 1.1.1 or 1.2.1

Shipped inside each runtime's own release

node:zlib and fetch()

Node.js

22.23.4 · 24.22.1 · 26.12.1

Fixed 21 October 2026

fetch(), node:zlib, DecompressionStream

Bun

1.4.4

Fixed 22 October 2026

pip install

Python

brotli 1.2.1 · brotlicffi 1.2.1.0

PyPI packages

A bug in a bundled C library reaches you through every runtime that ships it, and each one needs its own upgrade.

The Node.js release of 21 October also fixed nine other CVEs: TLS hostname checks, DNS name truncation, keep-alive handling and others (see our Node.js article). Those are bugs in Node's own code. We found no Bun advisory or release note saying whether Bun's separate implementations had the same flaws, so do not assume they did, or that they did not.

What other Bun vulnerabilities were fixed in 2026?

AdvisoryWhat it isSeverityAffectedFixed in
GHSA-663w-cv8g-jj2p (CVE-2026-111497)Brotli decoder out-of-bounds writeHigh1.0.21 up to 1.4.31.4.4
GHSA-26q8-h657-pf84Bundled root store still trusted compromised eMudhra (emSign) intermediate CAsHighBefore 1.4.41.4.4
GHSA-cf8x-9m69-3gg3HTTP/3 QPACK amplification: remote memory exhaustion and CPU stallHigh1.3.14 up to 1.4.31.4.4
CVE-2026-24910Default trusted-dependencies list could be spoofed by a file:, link:, git: or github: package with a trusted nameMedium, 5.9Before 1.3.51.3.5

The emSign certificate issue is the one with the widest reach after Brotli. Eight eMudhra intermediate CAs were revoked for key compromise, and Bun 1.4.3 and earlier still trusted the root they chain to. An attacker holding those keys could impersonate any TLS server to a Bun process. That includes the registry downloads that bun install and bunx make, so packages could be tampered with in transit.

  • --use-system-ca does not help, because it adds to the bundled roots rather than replacing them.
  • Until you upgrade, the workaround is an explicit ca per connection, or cafile under [install] in bunfig.toml.

The HTTP/3 issue only applies if you turned HTTP/3 on: Bun.serve({ http3: true }) or fetch(url, { protocol: "http3" }). HTTP/3 is off by default, and HTTP/1.1 and HTTP/2 are not affected.

CVE-2026-24910 shows why Bun's install-time defaults matter, which is the next topic. Bun runs lifecycle scripts only for packages on a trusted list. Before 1.3.5, a dependency from a local path or git repository could borrow the name of a trusted npm package and have its scripts run.

Is Bun more secure than Node.js?

Bun's defaults for installing packages are safer than npm's; its support model is not as conservative as Node's. "More secure" depends on which half you care about.

BunNode.js with npm
Dependency install scriptsBlocked unless the package is on a trusted listRun by default
Release-age cooldownminimumReleaseAge in bunfig.toml (since Bun 1.3)min-release-age in npm CLI v12
Vulnerability auditbun audit (since Bun 1.2.15)npm audit
Support modelLatest 1.x release only, no LTSLTS lines with published end-of-life dates
2026 advisories3 GitHub advisories in October, plus one CVE in JanuaryAround 50 CVEs across five security releases

The last row is not a score. Node.js has a large security team, a scheduled release process and years of researchers looking at it. Fewer published Bun advisories partly means fewer people filing them. What the table does show is that Bun's package manager blocks the most common npm attack, a lifecycle script, out of the box. Per Bun's lifecycle docs, "Bun does not execute arbitrary lifecycle scripts by default, unlike other npm clients."

The trade-off is support. Bun's security policy supports the 1.x line and documents no backports. In practice, fixes land in the next release, and staying secure means staying current. Bun shipped at least ten releases between February and October 2026, so "pin a version and patch it" is not a strategy that works with Bun.

Why do npm worms ship their own copy of Bun?

To get out of sight of security tools that watch Node.js. The big npm worms of 2026 did not exploit Bun. They downloaded it and used it to run their payloads.

  • ChainDrop (August 2026). Its preinstall hook ran a small setup.mjs, which launched what Microsoft calls a "heavily obfuscated Bun-based JavaScript payload". It reached more than 400 packages.
  • Mini Shai-Hulud (TanStack, May 2026). The payload ran under Bun, according to StepSecurity's analysis.
  • Shai-Hulud 2.0 (November 2025). It took the same route.

Endor Labs' analysis gives the reasons:

  • A bun process is a different binary from the node process that monitoring tools watch during installs.
  • Node security tools often hook in through --require or NODE_OPTIONS, which Bun does not honour in the same way.
  • Shell, HTTP and decompression are built in, so the payload avoids the child_process and zlib imports that scanners match on.
  • bun.sh and GitHub releases are trusted download hosts that egress rules usually allow.
  • The runtime is a static binary that needs no root and can be deleted afterwards.
How a worm uses Bun
1 · Hook

Tiny preinstall script

Looks harmless in a diff

2 · Fetch

Downloads the Bun binary

From hosts egress rules allow

3 · Run

Large payload runs under bun

Outside Node-focused monitoring

4 · Clean up

Deletes the runtime

Nothing left for a responder

What to alert on

A package manager starting an unexpected runtime or download during install

Attackers bring Bun along because most install-time monitoring watches node, not bun.

For defenders, the useful signal is not "Bun is installed", which on a JavaScript team is normal. It is a package manager (npm, yarn, pnpm or bun) starting an unexpected runtime or downloader during an install. An unexpected ~/.bun directory in a CI image, or a short-lived binary in /tmp that deletes itself, is also worth an alert. Endor Labs lists all three.

How do you harden bun install?

Set a release-age cooldown, keep the trusted list short, and install from the lockfile. All three are a few lines of configuration. In bunfig.toml:

[install]
# Skip package versions published in the last 3 days (value in seconds)
minimumReleaseAge = 259200
# Exempt specific packages if you need them immediately
minimumReleaseAgeExcludes = ["@types/bun"]
# Optional, strictest: no lifecycle scripts at all, even for trusted packages
# ignoreScripts = true

Then:

  1. Make trustedDependencies explicit. Without it, Bun trusts a built-in list of popular packages with install scripts. Defining trustedDependencies in package.json replaces that list, so name exactly the packages that need scripts, such as esbuild or sharp, and nothing else. Use [] to trust none.
  2. Commit bun.lock and install with bun ci (or bun install --frozen-lockfile) in CI and Docker builds, so new versions only arrive when someone updates the lockfile on purpose.
  3. Run bun audit in CI, for example bun audit --audit-level=high. It checks bun.lock against the npm advisory database. Like npm audit, it reports known advisories, not a malicious release in its first hours.
  4. Remember the limits. These settings govern bun install. A developer running npm install in the same repository gets npm's defaults.

Which Bun version should you run?

Bun 1.4.4 or later. Check with bun --version in every environment that runs Bun: laptops, CI runners, container images and servers. Then:

  • Upgrade with bun upgrade, or brew upgrade bun and scoop update bun if you installed Bun that way.
  • Pin and rebuild Docker images to the exact Bun version, because a cached base image keeps the old runtime.
  • Rebuild every bun build --compile binary. All three October advisories say compiled executables stay vulnerable until they are rebuilt with a patched Bun.

Tip

Keep a list of where Bun runs

Compiled Bun executables do not look like Bun: they are just a binary called my-tool. If your team ships CLIs or services that way, keep a list of them, because each one needs a rebuild when Bun ships a security fix.

What should you do this week?

  1. Upgrade Bun to 1.4.4 everywhere and rebuild compiled binaries and images.
  2. Until then, pass decompress: false to fetch() calls against servers you do not control, and leave HTTP/3 off.
  3. Add minimumReleaseAge and an explicit trustedDependencies list to every project.
  4. Install from bun.lock with bun ci and run bun audit in CI.
  5. Alert on unexpected runtimes started during installs, whichever package manager you use.
  6. Patch Node.js too, if you run it alongside Bun. The Brotli fix is 22.23.4, 24.22.1 or 26.12.1.

Nordbeam builds production systems on TypeScript and Node.js, and the site you are reading is built and deployed with Bun. If you are deciding between them, or need help getting a fleet of services onto patched versions, our software development team can help.

Is Bun affected by the Node.js Brotli vulnerability?
Yes. CVE-2026-111497 is a bug in Google's Brotli library (versions 1.0.3 to 1.2.0), which both Node.js and Bun bundle. Bun 1.0.21 up to 1.4.3 are affected through fetch(), node:zlib and DecompressionStream. Bun fixed it in version 1.4.4, released on 22 October 2026.
How do I update Bun?
Run bun upgrade, or use brew upgrade bun or scoop update bun if you installed it with Homebrew or Scoop. Then check bun --version in CI and in your container images too, and rebuild any executables made with bun build --compile.
Does Bun have an LTS version?
No. Bun's security policy covers the 1.x line and documents no long-term support releases or backports. Security fixes ship in new releases, so the safe approach is to stay on the latest version, which is Bun 1.4.4 as of October 2026.
Does Bun run postinstall scripts?
Not by default. Bun only runs lifecycle scripts such as preinstall and postinstall for packages on a trusted list: a built-in list of popular packages, or the trustedDependencies field in package.json, which replaces the built-in list. Setting ignoreScripts = true in bunfig.toml disables scripts entirely.
What is minimumReleaseAge in Bun?
minimumReleaseAge is a bunfig.toml setting, under [install], that makes bun install skip package versions published more recently than the given number of seconds. For example, 259200 waits three days. It protects against malicious releases that are detected and removed shortly after publication.
Is Bun more secure than Node.js?
Bun's package manager has safer defaults: it blocks dependency install scripts unless trusted, and has a built-in release-age cooldown. Node.js has a more conservative support model, with LTS lines and scheduled security releases. Neither is safe without keeping it updated.
Do I need to rebuild bun build --compile executables?
Yes. Compiled executables embed the Bun runtime they were built with. All three Bun security advisories from October 2026 say executables built with an affected version stay vulnerable until they are rebuilt with Bun 1.4.4 or later.

Running Bun or Node.js in production?

Tell us what you run and how it is deployed. We will tell you what it takes to keep it on patched versions without it becoming a weekly chore.

Start the Conversation →

Get in Touch

Which workflow should AI improve first?

Book a practical review of one high-value workflow. You'll speak directly with Assim, Nordbeam's founder and lead engineer.
Email directly
Email
hello@nordbeam.io
Locations
Gothenburg & Malmö, Sweden
Response time
Within 24 hours