Skip to content

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

Open
@nicolo-ribaudo

Description

@nicolo-ribaudo

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds concrete proposalMoving the issue forward requires someone to figure out a detailed plan

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions