CVE-2022-37621 is a high-impact security vulnerability found in the browserify-shim npm package, specifically version 3.8.15, maintained by thlorenz. This vulnerability is tied to prototype pollution in the resolveShims function inside the resolve-shims.js file. If you're using browserify-shim to manage your front-end dependency shims, this issue could let attackers seriously mess with your app’s internal logic.
In this post, we’ll walk through what this vulnerability is, show you a code snippet to illustrate it, explain the exploitation in plain English, and provide links for further reading.
What is Prototype Pollution?
Prototype pollution is a security risk mainly in JavaScript, where an attacker can manipulate the special __proto__ property or other global prototype objects. If the prototype is polluted, all objects can be affected, potentially leading to denial of service, privilege escalation, or code execution.
Where’s the Vulnerability?
In browserify-shim v3.8.15, the problem lies in the resolveShims function, which doesn’t properly sanitize keys drawn from user-controlled input. Specifically, the fullPath variable, assembled from possibly untrusted data, is assigned as a key on an object. If someone provides a value like __proto__, they can change the application's core behavior.
Here’s a simplified version of the problematic code from resolve-shims.js
function resolveShims(cfg, basePath) {
var shims = {};
Object.keys(cfg).forEach(function(key) {
var fullPath = path.resolve(basePath, key);
shims[fullPath] = cfg[key];
});
return shims;
}
If key comes from user input, an attacker could pass a value like __proto__/badkey, which when resolved could pollute the prototype chain.
Let’s see how this could be attacked
// Attacker-controlled input
const maliciousShimConfig = {
"__proto__": { "polluted": true }
};
// Simulate resolveShims
function resolveShims(cfg, basePath) {
let shims = {};
Object.keys(cfg).forEach(function(key) {
var fullPath = key; // no path.resolve for simplicity
shims[fullPath] = cfg[key];
});
return shims;
}
resolveShims(maliciousShimConfig, "/tmp");
console.log({}.polluted); // --> true! (Prototype polluted!)
When your code later checks {}.polluted, it now returns true—clearly, the prototype has been polluted. In real-world apps, attackers could escalate this to perform malicious actions or completely break your app.
What’s the Fix?
The main fix is to block dangerous keys (__proto__, prototype, constructor) or use safer methods like Object.create(null) when building objects expected to hold user input as keys.
Example safe code
function resolveShims(cfg, basePath) {
var shims = Object.create(null);
Object.keys(cfg).forEach(function(key) {
if (key !== "__proto__" && key !== "constructor" && key !== "prototype") {
var fullPath = path.resolve(basePath, key);
shims[fullPath] = cfg[key];
}
});
return shims;
}
Or use a third-party package like lodash’s hasOwnProperty protection.
References & Links
- CVE-2022-37621 on NVD
- npm Advisory
- browserify-shim GitHub
- OWASP: Prototype Pollution
Summary
CVE-2022-37621 is a prototype pollution vulnerability that exists in the way browserify-shim’s resolveShims function creates object keys from potentially untrusted input. Left unfixed, attackers can manipulate your app’s object prototypes, causing unexpected or dangerous behavior.
If you use browserify-shim (3.8.15), you should update or patch immediately. Always sanitize user input before using it as object keys!
If you found this helpful, share it so others can keep their Node.js apps secure.
Timeline
Published on: 10/28/2022 20:15:00 UTC
Last modified on: 11/03/2022 14:31:00 UTC