-
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
feat!: create result.values with null prototype #111
Conversation
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.
Should this be accompanied by removing a bunch of defensive coding that's no longer needed when setting/accessing things off of result.values
?
Yes, but I am not assuming which lands first. |
I'm on the fence about this one, do we want to take away object helper methods from users, for the benefit of having less confusing behavior around edge-cases like a key called "toString"? If someone has a need for this key name, couldn't they use hasOwnProperty to handle the edge case themselves? |
Nobody uses object helper methods, precisely because of the risk of collision. |
Argument lands for me, if we want to go this route 👍 |
This is a generalisation which is not true in my experience. I see lots of use of object helper methods. I can't know whether because of carefully reasoned balance of the convenience vs the theoretical risk, or dismissal of the risk, or ignorance. To check my impression, I tried searched for "javascript hasownproperty" and opened the top four links. All were showing how to use the helper method. Some of the pages did also mention or demonstrate the possibility of Only one of the pages actually pointed away from using the helper function with a note at the top of the page:
One of the pages introduced an alternative in a small trailing section with :
|
Let's say you're right, and users will be confused by this. So? The result is hopefully that they'll be educated on how the language works, and their code will be better as a result. The alternative is that code using parseArgs has a CVE, or worse, is exploited without a CVE. Some amount of confusion from people who misunderstand the language seems far preferable to the likely potential for security exploits ("prototype pollution" CVEs are one of the most popular flavors of the last few years in the npm ecosystem, in my experience). |
I tend to agree, let's err on the side of caution. I really want to avoid having to cut a patch Node.js release for a sporius prototype pollution vulnerability. |
(That was a pretty loaded comparison, but the concerns are real.) |
From an earlier discussion (#32 (comment)) @bcoe said:
and @ljharb replied:
What's the issue here? Is |
Yes, it's different. Using it syntactically in an object literal is grammar, and has nothing to do with the setter, which comes into play if someone does |
The setter does also apply there. It's just a normal accessor on Object.prototype; it works like every other accessor. |
- add __proto__:null in expected values - rename passedArgs to args - rename passedOptions to options - rename args (result) to result
Updated original comment with notes and crack at documentation. I didn't soak up the rest of the utils page for style. |
Both the reviews were from when there was just one line of code, so bumped for re-review as much to make sure you were not misrepresented as to give you the opportunity! |
@@ -117,19 +116,9 @@ function checkOptionUsage(longOption, optionValue, options, | |||
*/ | |||
function storeOption(longOption, optionValue, options, values) { | |||
if (longOption === '__proto__') { | |||
return; | |||
return; // No. Just no. |
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'm not actually sure we should be returning here - we can just set a data property of the string "__proto__"
, no?
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.
My concern is it is fine in the values
we return, but is it a potential foot-gun when the author copies it out into some full object? Or does who-knows-what? We are going to great lengths to make this as safe as we can, why would we allow it?
(I might have missed the point though. Not sure what you meant by string "proto"
.)
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.
It would only be a footgun if a user is relying on the (deletable) Object.prototype.__proto__
accessor. Otherwise, it'd just be a string property.
If we want to disallow it, why not throw in strict mode?
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.
Existing behaviour. I care enough about it to add a comment showing it is deliberate. But not to do work on it in this PR. 😄
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.
lol totally fine, we can look at it later.
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.
will wait to approve until I see edits to tests,
Simple code change, with repercussions for tests and documentation.
Closes: #108
Removed the recently added protections when storing option values in
values
.First cut at documentation follows. I gave two shallow examples, just pick one? I went further than the existing reference which didn't unblock my problems. (The caveats and work-arounds could go on a canonical page, if there is somewhere appropriate. I didn't go looking for that, out of scope for my current efforts!)
Reference documentation: https://nodejs.org/api/querystring.html#querystringparsestr-sep-eq-options