tc39 / proposal-dynamic-code-brand-checks

TC39 proposal that enables flexible brand checks before dynamic code loading

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IsCodeLike needs rewrite

mikesamuel opened this issue · comments

@erights @waldemarhorwat have ideas.

+ @bakkot too since failure to resolve concerns from issue #1 would obviate this.

@erights
As discussed in person, IsCodeLike is not meant to preserve security properties; security properties about what can execute are in the host callout, so the fact that any user code can add a symbol is not security significant. It just allows more consistency in the host callout since host callouts don't need to do checks like "if called via eval and the argument is not a string or a value I consider codelike."

There are backwards compatibility concerns with eval that might arise if we were to just have eval always stringify.

{
  let NaN = 42;
  isNaN(eval(0/0));  // -> true
  isNaN(eval(String(0/0)));  // -> false
}
// If we always stringified, both would always -> true

@waldemarhorwat
As discussed in person, the threat model is that an attacker may control strings, numbers, and so may craft the kinds of objects that you might get from JSON.parse(x).
We want to keep those away from eval, so are concerned with

// In the absence of CSP
const attackerControlledString = ' ["alert(1)"] ';
eval(JSON.parse(attackerControlledString));  // currently just returns an array

@waldemarhorwat @erights Do you have outstanding concerns regarding isCodeLike shape, after Mike's explanation? It's not clear to me if this issue was resolved in December, looking at the minutes.

@waldemarhorwat @erights, friendly ping. I wanted to understand if there are remaining concerns after Mike's explanation.

@waldemarhorwat @erights ping, I wanted to apply for stage 2 at the next meeting, and I wanted to understand if you consider this a blocker. The proposal was changed recently, please see the updated text.

I'm still missing the big picture here. If I understand this correctly, you want to allow implementations to disallow strings in eval and allow only vetted objects to be eval'd. That just shifts the problem from trying to sneak exploits past function A (eval) to trying to sneak exploits past function B (the function that sets isCodeLike). What justifies the extra complexity?

That just shifts the problem from trying to sneak exploits past function A (eval) to trying to sneak exploits past function B (the function that sets isCodeLike).

Correct, with the note that function B is also guarded (via CSP in the web platform).

What justifies the extra complexity?

https://github.com/tc39/proposal-dynamic-code-brand-checks#motivation. In short, the host controls of allowing or disallowing eval completely are not good enough in practice, as the majority of the programs (web applications) end up requiring eval. This was discussed in #1, see e.g. #1 (comment).

Having brand checks allows the authors to guard eval payloads selectively. For a practical example: with it, we can make sure that only the payloads for the anti-abuse eval-based VM engine are allowed in the application without opening up the application for eval fully. We're essentially moving the guard to a more effective place - from the sink to the value producer.

One extra thing I realised might not be clear without having worked with Trusted Types, that seems relevant: The guards for the 'code like' producers in the web platform are set up on their factories (Trusted Type policies) - this allows us to restrict code-like object creation like capabilities (one can only create a codelike, if one has a reference to a policy object, and creation of policy objects is guarded), so e.g. we can be sure that only a given module will produce codelikes, and unless the capability is exported from that module, nothing else will successfully call eval, even though they have a reference to eval function.

@waldemarhorwat does my explanation clear up things? I wanted to apply for stage 2 advancement and the deadline is approaching. I want to understand if you (or @erights) consider this a blocker for stage 2.

Still waiting for y'all feedback. I tentatively applied for stage 2, happy to discuss this before or at the plenary.

This can be closed as there is no longer an IsCodeLike concept (there's a host hook that serves a similar purpose but the security semantics are down to the host platform now)