tc39 / proposal-dynamic-code-brand-checks

TC39 proposal that enables flexible brand checks before dynamic code loading
MIT License
31 stars 5 forks source link

IsCodeLike needs rewrite #4

Closed mikesamuel closed 5 months ago

mikesamuel commented 5 years ago

@erights @waldemarhorwat have ideas.

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

mikesamuel commented 4 years ago

@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
koto commented 4 years ago

@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.

koto commented 4 years ago

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

koto commented 3 years ago

@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.

waldemarhorwat commented 3 years ago

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?

koto commented 3 years ago

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. https://github.com/tc39/proposal-dynamic-code-brand-checks/issues/1#issuecomment-501346106.

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.

koto commented 3 years ago

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.

koto commented 3 years ago

@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.

koto commented 3 years ago

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

lukewarlow commented 5 months ago

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)