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

Feedback request on not capturing the caller in new Function and indirect eval #679

Open
nicolo-ribaudo opened this issue Sep 4, 2024 · 0 comments

Comments

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Sep 4, 2024

tc39/ecma262#3374 (which is currently a Stage 2.7 proposal in TC39) is trying to change new Function and indirect eval to not capture context from their caller, thus making them "normal function". The only caller-dependent function remaining in ECMA-262 would be direct eval.

By "normal function" I mean a function that follows the normal JavaScript rules and could be implemented in userland: if that changes land, eval could easily be implemented with a JS parser and interpreter, both written in JavaScript.

Another property of "normal functions" is that these two pieces of code are equivalent:

<script>
  var myNormalFunction = /* ... */;
  var argForMyNormalFunction = /* ... */;
  function runIt(x) { myNormalFunction(x) }
</script>
<script>
  runIt(argForMyNormalFunction);
</script>
<script>
  var myNormalFunction = /* ... */;
  var argForMyNormalFunction = /* ... */;
</script>
<script>
  myNormalFunction(argForMyNormalFunction);
</script>

new Function and indirect eval currently do not respect that "normal function" property, when it comes to nonce-based CSPs. Example, with CSP set to script-src 'nonce-foo' 'unsafe-eval':

<script>
  var myNormalFunction = eval;
  var argForMyNormalFunction = 'import("https://example.com/foo.js")';
  function runIt(x) { myNormalFunction(x) }
</script>
<script nonce="foo">
  runIt(argForMyNormalFunction); // this *will not* execute https://example.com/foo.js
</script>
<script>
  var myNormalFunction = eval;
  var argForMyNormalFunction = 'import("https://example.com/foo.js")';
</script>
<script nonce="foo">
  myNormalFunction(argForMyNormalFunction) // this *will* execute https://example.com/foo.js
</script>

With the proposed ECMA-262 changes, the behavior of eval and new Function will only depend on the realm/document that they come from, and not on their caller: this means that wrapping them in an intermediate function would have no effect, unlike the example above.

More specifically, in both cases https://example.com/foo.js would not be executed, because the nonce is <script>-specific and not document-wide.

My questions are:

  • what do you think about this behavior?
  • do you think this change would be web-compatible, with regards to CSP?
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

No branches or pull requests

1 participant