Skip to content
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

fix(ses): Patch leak of globalLexicals thru moduleLexicals #1341

Closed
wants to merge 3 commits into from

Conversation

kriskowal
Copy link
Member

Fixes #912

The global lexicals are intended to provide a namespace that guest code cannot enumerate for arbitrary properties. By employing a transform for all evaluation in a compartment and also transforming all module code provided to a compartment's import hooks, a host program can introduce a name like meter into the global lexical scope of a program and also deny that program access to the lexical name through censorship of the original source. Previously, a crafted module could use a function in module lexical scope to capture the global lexicals object or the scope proxy. This change creates another intermediate layer in the safe evaluator that separates the global lexicals from the module lexicals, plugging this leak.

Individually reviewable commits.

  • test(ses): Leak globalLexicals through moduleLexicals
  • refactor(ses): Decouple moduleLexicals from globalLexicals
  • test(ses): Cover moduleLexicals optimizer overshadowing

@mhofman
Copy link
Contributor

mhofman commented Oct 26, 2022

Fixes #912

It would fix #904, not #912, which is a problem self contained within module lexicals

Copy link
Contributor

@mhofman mhofman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preliminary observations, not a full review yet, and nothing actionable, just stream of thoughts.

So I'm wondering, should moduleLexicals be allowed to shadow globalLexicals, I suppose a global lexical should come with a transform denying normal lexical access to these bindings, but I don't quite remember if that global transform would apply before or after the module transforms which introduce the corresponding module lexical usages.

Then, if no shadowing is allowed between global and module lexical, and given the use case of moduleLexicals which do not get optimized (not immutable since they're getter / setters), I'm wondering if the removal of the evaluate factory wasn't premature. If we had kept the evaluate factory, we technically could have cached it on the compartment, and re-used it between evaluate calls with different __moduleShimLexicals__, but that kinda feels like we'd want another kind of 2 stage process where only the moduleLexicals change instead of the whole context object.

Finally, I really hope we get to a point where we can build the evaluate factory more dynamically if globalLexicals or moduleLexicals are missing / empty, removing layers of unnecessary with blocks siting between the user code and lookups on the globalObject.

Comment on lines +34 to +35
__moduleShimLexicals__ !== undefined &&
__moduleShimLexicals__ !== null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really one of those cases where I prefer to write __moduleShimLexicals__ != null

Comment on lines -29 to +31
* @param {object} context.globalLexicals
* @param {object} context.globalObject
* @param {object} context.globalLexicals
* @param {object} context.moduleLexicals
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if we should keep the order the same as in the nested scopes

Comment on lines +52 to +55
const moduleLexicalOptimizer = buildOptimizer(
moduleLexicalConstants,
'moduleLexicals',
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this ever actually happen? I mean this is probably the safest way, and doesn't cost much.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in any correct arrangement. Any potential overlap would need to be censored by a transform.

@kriskowal
Copy link
Member Author

In out-of-band group review, we elected to instead remove support for globalLexicals entirely #1343

@kriskowal kriskowal closed this Oct 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Module shims lexicals leak internal live bindings object
2 participants