Liran Tal
Liran Tal
  • Dec 2, 2024

Bun JavaScript Runtime Found Vulnerable to Prototype Pollution

Bun puts the speed in your JavaScript runtime but also suffered from a prototype pollution vulnerability.

Bun Found Vulnerable to Prototype Pollution

I found a prototype pollution vulnerability in the server-side JavaScript runtime Bun. The security vulnerability is now addressed and fixed by Jarred Sumner and the Bun team through a newly released version of Bun. Curious to learn more about the vulnerability and how it was fixed? Read on.

What is Prototype Pollution?

A prototype pollution vulnerability is a type of security vulnerability that is specific to JavaScript due to the language design. In a prototype pollution attack, the application mishandles property checks or performs insecure JSON serialization, deserialization, or nested object merge that result in the Object prototype being altered. This prototype pollution attack would allow an attacker to inject properties into existing JavaScript language construct prototypes. The result of such an attack on JavaScript server-side runtime software like Bun or Node.js can lead to unexpected behavior in the application that can be exploited by attackers to perform malicious actions.

If you’re curious to learn about the Node.js angle of prototype pollution attacks I’ve written about understanding and preventing prototype pollution in Node.js.

Bun JavaScript Runtime and Prototype Pollution

Many of Bun’s APIs are quite minimal in terms of function signature and are very lean (all of that is a good thing!), but some of these APIs allow for objects to be passed in (e.g: globa.scan({})) which are susceptible to a prototype pollution manipulation, which if exploited at the Bun application-level code, would result in unintended altered behavior for some of Bun’s APIs.

Exploiting Bun Prototype Pollution Vulnerability by Example

Here’s a real-world example of a prototype pollution vulnerability in Bun’s API surface:

import { Glob } from "bun";
const glob = new Glob("*.ts");
const a = {};
a.__proto__.followSymlinks = true;
console.log(a.nothing);
console.log(a.followSymlinks);
const b = {};
console.log(b.followSymlinks);
const opts = {};
opts.cwd = '.';
for await (const file of glob.scan(opts)) {
console.log(file);
}

The scenario in the above Bun code snippet goes to show that if an attacker is able to create a prototype pollution in the Bun runtime, they could potentially inject properties into the configuration object passed to the glob.scan() function.

For a practical attack scenario, imagine that this Bun application reads configuration from several files and merges them into a single configuration object. If an attacker is able to:

  • Create a prototype pollution in the runtime (as in: a.__proto__.followSymlinks = true;)
  • Upload files to the server where Bun is running-
  • Create a symlink to the uploaded file

Then the attacker could inject properties into the configuration object.

The Prototype Pollution Details and Fix

This above vulnerability and exploit code was tested with Bun 1.1.27 and was later fixed in Bun 1.1.30 by the team when they triaged my security disclosure to the team.

The CVE hasn’t been assigned yet but is scored with CVSS 7.5 (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H), an CWE assignment of Improperly Controlled Modification of Object Prototype Attributes (‘Prototype Pollution’) (CWE-1321)

Many thanks to the Bun team for their quick response and fix to the security vulnerability and the recognition and maintaining security research credit to Liran Tal in the Bun 1.1.30 release notes:

Liran Tal discovers a prototype pollution vulnerability in the Bun runtime

The Impact of Prototype Pollution Bugs in the Wild

It is possible to track dozens of reports about prototype pollution to bug bounty programs, here are a few public references:

In July 2023, a code change landed on the Node.js code-base through a pull request to harden against prototype pollution for child_process.

Even though that pull request aimed at safeguarding native Node.js core APIs it had missed one and caused a security regression/bug which I found a couple of months ago and reported and pushed a fix for to the Node.js project.

Bun Security Vulnerability Prototype pollution