-
-
Notifications
You must be signed in to change notification settings - Fork 744
feat: add secure JSON parsing with prototype poisoning handling #603
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
base: master
Are you sure you want to change the base?
Conversation
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
secure-json-parse also has protection against constructor poisoning. Should I include that as well? Are there any use cases for it? |
lib/types/json.js
Outdated
@@ -55,6 +56,7 @@ function json (options) { | |||
|
|||
var reviver = options?.reviver | |||
var strict = options?.strict !== false | |||
const protoPoisoning = options?.onProtoPoisoning || 'ignore' |
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.
In a future major version, we can make this throw an error or ignore it, but in the meantime, to maintain compatibility, this option is handled.
@@ -17,6 +17,7 @@ | |||
"on-finished": "^2.4.1", | |||
"qs": "^6.14.0", | |||
"raw-body": "^3.0.0", | |||
"secure-json-parse": "^3.0.2", |
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.
There's a version 4, but they theoretically support from node 20 onwards, so to avoid any potential issues, we’re sticking with version 3, which supports Node 18+
lib/types/json.js
Outdated
@@ -74,7 +76,7 @@ function json (options) { | |||
|
|||
try { | |||
debug('parse json') | |||
return JSON.parse(body, reviver) | |||
return secureJson.parse(body, reviver, { protoAction: protoPoisoning }) |
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.
Another option would be to always protect against this issue by passing 'error' or 'remove', but I'm not sure. Other packages chose to make it a configurable option, and I think it would make some sense to do the same.
Do we want to cover this type of scenarios ( const obj = {};
const otherObj = {}
console.log("obj.polluted", obj.polluted) // undefined
console.log("otherObj.polluted", otherObj.polluted) // undefined
obj.constructor.prototype.polluted = true;
console.log("obj.polluted", obj.polluted) // true
console.log("otherObj.polluted", otherObj.polluted) // true |
Yeah, although I don't think it hurts to add an option for constructor poisoning, so I'm going to add tests for the constructor prototype and add the option |
…andling Signed-off-by: Sebastian Beltran <[email protected]>
f4db4db
to
6b4e150
Compare
Im not crazy about the current form of the PR. I'd prefer we fight against bloating the options further, especially in cases where there is no strong reason for someone to deviate from the default. Philosophically...I don't like these kinds of mitigations for language level issues, they should be fixed in the language. That ship has long since sailed, as `Object.assign` is likely never to change. At least the spread operator was fixed to no longer set prototype.I also am not convinced that the output of body-parser should ever be considered trusted input. There is a vuln here only in that some code may pass We cannot code around all of them, but since this one is common and the intent of developers so clear (nobody is meaning to pollute the root proto, whether there was something malicious or not in the input) it is worth considering. I'd consider dropping But whatever we do, lets be consistent. the extended urlencoded parser (using |
I agree with that approach, adding the option was more about being permissive, but I’d really prefer to just remove it. |
Users of this middleware are given the option to control prototype poisoning
closes: #347