feat: add evalTaming option#961
Conversation
erights
left a comment
There was a problem hiding this comment.
Hi @Jack-Works , very nice! Some questions:
IIUC, what you really care about is the Function and eval of the start compartment. Under the 'unsafe' setting you want these left as is. But I don't understand what you intend for the evaluate method of compartments, nor for the per-non-start-compartment setting of eval and Function.
For production use, IIUC, you want this to actually be safe if in an environment where evaluation is suppressed by other means, like CSP. However, in that environment specifically, how would it make a difference whether eval and Function were tamed or not? In fact, to better support that environment, should this PR instead have a three-settings option, perhaps with names like the following?
'noEval'-- all evaluators are disabled, achieving no-eval safety with or without CSP. This would be compat with the CSP no-eval option, but would be redundant belt and suspenders, in case the CSP was, for example, mistakenly changed under maintenance.'safeEval'-- status quo'unsafeEval'-- supports the development mode you're concerned about, by leaving (only?) the start compartmentevalandFunctionuntamed.
I'm hitting "Request changes" but I'm really requesting dialog ;). I'd like your reaction to these questions before completing the review. Thanks!
What should happen for eval within a compartment? The compartment itself internally based on the real eval and provide a CSP-safe eval? |
|
And is it possible to have different eval behavior in the start compartment and the child compartment? For example, start compartment has |
Are you asking about the |
It could be possible by other means. But I don't think appropriate for such lockdown options, since these are not per-compartment. I don't think we need to go that far in this PR. |
|
I can only think of motivating uses to rationalize two modes: one where eval cannot be used in any form and one where we use eval. Which of these three modes do we not need and can we frame the remaining two in a way that makes the choice clearest to the end user? Or: what’s the third motivating use case? |
|
Updated cc @erights @kriskowal |
|
ping @erights @kriskowal can u check out this PR? |
|
I’ve given this a scan and it looks close. I will ask @erights and @mhofman to sign off on the architecture and I will send a review with suggestions to clarify the feature documentation, which will help me think through the rationale for each of the taming options. This will need a short entry in NEWS |
kriskowal
left a comment
There was a problem hiding this comment.
This is good and close to merge-worthy, pending architecture approval from some combination of @erights and @mhofman. The code does not yet have the intended effect for the "unsafe" option.
I would like to propose the names "safe", "unsafe", and "none" for which there is precedent on other taming options.
I would like to see a test case that verifies that compartment evaluators work with the "unsafe" option.
erights
left a comment
There was a problem hiding this comment.
Environment variable misnamed?
erights
left a comment
There was a problem hiding this comment.
LGTM modulo lint errors.
kriskowal
left a comment
There was a problem hiding this comment.
Now that I’ve slept on it, I agree with Mark that the taming option names should be noEval, safeEval, and unsafeEval. Mostly, none is not a good name. My apologies for making more work for you.
kriskowal
left a comment
There was a problem hiding this comment.
Thank you. This is looking great. I would like compartment evaluator tests for each of the modes.
It would also be good to test compartments constructed within another compartment, specifically to highlight the TODO you added regarding the propagation of evalTaming to child compartments. I expect safeEval will work fine, but noEval might not be working correctly.
Otherwise, nits.
Thank you for the drive-by cleanups.
|
hi @kriskowal can I get a review? this is blocking our product to adopt lockdown |
I am satisfied and defer to @erights for final sign-off.
|
hi is this change you're expecting? I just pushed a new commit @kriskowal |
|
Yes, that will do, thank you!
…On Wed, Feb 16, 2022 at 8:40 AM Jack Works ***@***.***> wrote:
hi is this change you're expecting? I just pushed a new commit @kriskowal
<https://github.com/kriskowal>
—
Reply to this email directly, view it on GitHub
<#961 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAOXBTOBW2TNPT6DL2IGNDU3PHPRANCNFSM5KKI7T6A>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
mhofman
left a comment
There was a problem hiding this comment.
There is regression about marking the eval and Function globals as native functions.
I'm a little confused about the goal of noEval and the interaction with the Compartment shim. compartment.evaluate() is also an evaluator. Shouldn't it throw as well in the case of noEval taming? That would limit the usefulness of Compartment since the shim doesn't natively support ES modules (to replicate CSP, I would imagine only some modules would be allowed to be imported based on some policy)
erights
left a comment
There was a problem hiding this comment.
LGTM. All my comments are only on documentation.
Thanks for this enhancement!
|
|
||
| ```js | ||
| const c = new Compartment() | ||
| c.globalThis.eval = c.globalThis.Function = function() { |
There was a problem hiding this comment.
All the *Function constructors reachable by somePrototype.constructor are inert. They only throw. They don't do tamed evaluation.
The only *Function constructor that has ever been reachable any other way is the Function constructor itself, by name from the global object. Thus, by default, that one is a tamed evaluator.
Besides eval and Function, we have one other per-compartment global evaluator: Compartment.prototype.evaluate. If we want to turn off all evaluators in a compartment, we need to turn that one off as well.
Co-authored-by: Kris Kowal <kris@cixar.com> Co-authored-by: Mark S. Miller <erights@users.noreply.github.com>
Co-authored-by: Mark S. Miller <erights@users.noreply.github.com>
Co-authored-by: Kris Kowal <kris@cixar.com>
Co-authored-by: Mark S. Miller <erights@users.noreply.github.com>
Co-authored-by: Mark S. Miller <erights@users.noreply.github.com>
We have agreed out-of-band that to keep the compartment evaluator behavior as written.
|
Cool! |
Closes: #XXXX Refs: #961 #2690 #2723 ## Description #961 deviated from our general convention that lockdown option values be kebob-case, instead adding `evalTaming:` option values `safeEval`, `unsafeEval`, `noEval`. (I approved #961 at the time, apparently without noticing this discrepancy.) This PR fixes those to be `safe-eval`, `unsafe-eval`, and `no-eval`. But to avoid breaking any old usage, this PR ensure the only names continue to work for now, but always commented in the code as "deprecated". This PR does only that. Other changes to the relevant lockdown option or relevant lockdown options machinery are left to #2723 or #2690 respectively. I request that this PR go first, with those others adjusting to this one. ### Security Considerations none ### Scaling Considerations non ### Documentation Considerations This PR simply changes the documentation to use the new names without ever mentioning the deprecated old names. That seems like an appropriate simplification for the docs. ### Testing Considerations With a bit of duplication and renaming, we now test the new names and the old deprecated names. ### Compatibility Considerations To avoid breaking any old usage, this PR ensure the only names continue to work for now, but always commented in the code as "deprecated". It would be very nice to eventually be able to retire the deprecated names, but I find it hard to imagine how we'd test that it is safe to do so. ### Upgrade Considerations Nothing BREAKING, since the old deprecated names continue to work. - [x] Update `NEWS.md` for user-facing changes.
This PR adds a new option
evalTamingwhich defaults to"safeEval"(current behavior).I introduced a new behavior
"unsafeEval"and"noEval".This option is for the environment that does not allow
evalin the production mode but allows it in the development mode for webpackeval-source-map.The current behavior will replace the
evalconstructor and cause the webpack bundle to fail to load.I have documented this new option and warned any users do not use it unless they have the same situation as us.