GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fixing child_process module to check values passed strictly to the options object by lirantal · Pull Request #24267 · nodejs/node Conversation
|
|
Tagging as semver-major because of possible breakage. I think this change should be documented. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM. It would be nice to try cloning the options with Object.create(null). If that works, we could avoid needing to check hasOwnProperty() for shell and potentially other options in the future.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
@mcollina Sure. Could you share with me what you were thinking in terms of documenting it, and where? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@cjihrig I updated the tests and code, everything is passing locally so I pushed the changes. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
This needs one more @nodejs/tsc approval and a CITGM run. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Isn't there a rabbit hole here? if we accept this then won't we be up for changing a lot of Don't get me wrong, I'd love if all our APIs were really strict, on own-properties as well as types, but they aren't and this is a really big ship to turn around so we'd better be absolutely sure we're up for that pain. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
CITGM: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1642/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@rvagg I don't think we should do this everywhere, but in this specific case this makes harder to escalate a security vulnerability on an http route for example. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@mcollina so do you have a limiting principle? Or are you just happy to roll on a case-by-case basis? I'm not a fan of pragmatism on such matters and would rather have a principle which we can apply across the board. Otherwise we're in for (a) a lot of discussion and argument for the many other |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
IIUC this is an issue that crops up every once in a while (#12956, and #12981) in that the core lib lives in the same domain as user code, so monkey-patching can violate many assumptions. > Object._assign = Object.assign; > Object.assign = (a, b) => Object._assign(a, b, {shell: true}) > var o = Object.assign(Object.create(null), {a:1}) > o [Object: null prototype] { a: 1, shell: true } |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I understand that the counter-argument is that the prototype chain is the building block of the language and where you're going with theoretically requiring to make this change elsewhere as well. With that said, this type of issue came up through a related vulnerability reported to the ecosystem, which I later brought up to the node core security team and eventually agreed to accept it as a pull request that conforms with secure coding practices rather than an actual vulnerability. At the very least, the programmer's intention in the context of the modified code was to explicitly check a property was set on the argument it received. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@rvagg I don't, and I think this needs to be done on a case-by-case basis. I'm fine in not landing this as long as we spell clearly that this type of things are not a security vulnerability in our threat model. Do you want to talk about this in the next tsc meeting? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I think TSC discussion would be a good thing, this is one of those topics that has broader impact. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'm -1 on landing this without a @nodejs/tsc discussion about this topic.
(I'm ok with the actual change, and this -1 is only to avoid this being landed without that discussion)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
@lirantal Can you elaborate on whether this particular API is more vulnerable than the others that also accept an option object? If it's not any more vulnerable in generable, or does not have more serious security implications, then from a maintenance viewpoint I'd prefer we do this in a central place for all the options (or most of them) in our API. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Object.prototype and an own property are not the only two places where a value can be stored. There may be a legitimate prototype chain such that there is a prototype in between Object.prototype and the object itself. IOW a property on the options object may legitimately not be an own property. With this change we'd be expressing an opinion that doesn't really give us any more security because of all the other changes we'd have to make, like also addressing #24267 (comment).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
In any case, it would be good to have our threat model documented in https://github.com/nodejs/node/blob/master/SECURITY.md. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@lirantal would you be able to join the next TSC meeting to present this pull request, and why doing this change is worthwhile? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
@mcollina @gabrielschulhof Do you have any example that would be broken by this particular change? That said, protecting against malicious Object.prototype modifications is not much useful in general.
I don't think that hardening against malicious I am not against this particular PR, in fact, I lean forward to that we should land it (if it won't cause actual breakage). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I'm -1 only for having this discussion. I'm +0 on the change itself. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Apologies for not replying sooner, my e-mail inbox didn't receive a lot of love recently. I believe the thread comments summarize it well - an unauthorized access to manipulate the prototype chain will probably break many things anyway, and I don't think we're trying to solve here prototype manipulations across all of node. If we're not 100% to land because of code conventions between this place and others in the code-base I'm ok, but at the very least the change proposed in this PR is making senseful code practice. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@lirantal sorry for the late notice but do you have time to come to the TSC meeting Tomorrow (Wednesday) at 4EST to participate in a discussion on this? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
No worries, I should be able to make it. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@lirantal I'll send you the information to join through email. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sounds good, thanks! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I think that if |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I can relate to that Sam. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I think that if
console.log(options.SHELL)prints a string, thenchild_process.execFile(options)should use that string for the shell. Anything else is strange and unintuitive. If every node API was like that, people might learn to expect it, but if it is only child_process that ignores the options passed to it then the API behaviour would be pretty weird.
I agree with Sam.
From what I can tell, the primary base concern here is that a theoretical vulnerability here would be harder to detect than just accessing child_process directly. However, any code that can do that can _(easily enough, even to hide, you did see the event-stream vuln, right?) just access child_process itself if you want to.
Back to Sam's quote: Really, there are a great number of things inherent in how JavaScript works where similar issues manifest. JavaScript itself could be 'more secure' in this and similar ways but that is a job that is on a different level than us, IMO.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Is it worth considering something like |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
/cc @nodejs/security-wg, just in case if there is more input on this topic. Upd: sorry, hit the wrong button. :-/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This was discussed in the TSC meeting today and the net of the discussion is that the TSC does not believe that the PR should land as the Node.js security model does not protect against these kinds of attacks and changing that in one small way while leaving the other unchanged does not add enough value to outweigh the risk of breaking existing code or setting a precedent for many similar changes. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Removing TSC agenda as we should have removed after the discussion in the last meeting. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
We discussed in the TSC meeting that this shouldn't be regarded as something to be fixed and is expected behavior. Closing. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.