-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Security Fix for Prototype Pollution - huntr.dev #35
Conversation
Security fix for Prototype Pollution
@robinvdvleuten - let me know if you have any questions or thoughts, cheers! 🍰 |
@JamieSlome thanks for your effort! I tried to fix the issue myself in v2.0.2, how does your solution differs? |
@robinvdvleuten - this does a comparison against the Cheers! 🍰 |
@ljharb - since our discussion on Prototype Pollution yesterday, does this fix look good to you? 🍰 Perhaps we don't care so much about |
}, obj = object)[path.pop()] = val), object; | ||
}; | ||
|
||
function isPrototypePolluted (key) { | ||
return ['__proto__', 'constructor', 'prototype'].includes(key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd argue it is incorrect to omit constructor/prototype from this, but __proto__
is correct here.
Also, .includes
would not be available in an ES5 environment, which this package appears to work on, so you may want to use .indexOf
here (or use three ===
comparisons)
We do need to consider about // poc.js
var shvl = require("shvl")
let obj = {}
console.log("Before: " + {}.polluted)
shvl.set(obj, 'constructor.prototype.polluted', 'Yes! Its Polluted')
console.log("After: " + {}.polluted) and i have an idea about how to fix it, which doesn't introduce new functions. export function set (object, path, val, obj) {
return !/__proto__|constructor|prototype/.test(path) && ((path = path.split ? path.split('.') : path.slice(0)).slice(0, -1).reduce(function (obj, p) {
return obj[p] = obj[p] || {};
}, obj = object)[path.pop()] = val), object;
}; Should we use this fix as quick as possible? |
That precise fix would also block “.constructorx” which should be allowed, but the general approach is reasonable. However, i don’t think these are actually bugs. If the user explicitly intended to pollute the prototype, then that is a correct usage if the library, and if a different package is doing that with untrusted user input, that is a bug in the caller and not this library. |
I think it indeed a vulnerability because if we use const store = {};
app.use("/test", (req, res) => {
const k = req.query.key;
const v = req.query.value;
shvl.set(store, k, v);
}); In this application malcioud input it will lead to a disaster. Also And this may be a more precious fix: export function set (object, path, val, obj) {
return !/^(__proto__|constructor|prototype)$/.test(path) && ((path = path.split ? path.split('.') : path.slice(0)).slice(0, -1).reduce(function (obj, p) {
return obj[p] = obj[p] || {};
}, obj = object)[path.pop()] = val), object;
}; |
The bug is using unsanitized user input. It’s not shlvl’s fault that someone uses it unsafely, just like it’s not “rm”’s fault if someone runs |
Thanks for all the input! The fix will be released in v2.0.3 |
https://huntr.dev/users/arjunshibu has fixed the Prototype Pollution vulnerability 🔨. Think you could fix a vulnerability like this?
Get involved at https://huntr.dev/
Q | A
Version Affected | ALL
Bug Fix | YES
Original Pull Request | 418sec#1
Vulnerability README | https://github.com/418sec/huntr/blob/master/bounties/npm/shvl/1/README.md
User Comments:
📊 Metadata *
shvl
is vulnerable toPrototype Pollution
.Bounty URL: https://www.huntr.dev/bounties/1-npm-shvl
⚙️ Description *
Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects.
JavaScript allows all Object attributes to be altered, including their magical attributes such as
__proto__
,constructor
andprototype
. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain.💻 Technical Description *
Fix implemented by not allowing to modify object prototype.
🐛 Proof of Concept (PoC) *
🔥 Proof of Fix (PoF) *
+1 User Acceptance Testing (UAT)