svnlabs / google-caja

Automatically exported from code.google.com/p/google-caja
0 stars 1 forks source link

Problems with named DOM elements masking other properties #1371

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
There are several ways that a named DOM element can appear as a property with 
that name.  In some cases, setting another definition of that property will 
mask the DOM element.  In other cases the reverse is true.

Case 1.  another definition masks DOM element
   <div id="a"></div>
   <script>
      alert(window.a);
      window.a = 2;
      alert(window.a);
   </script>
That will show "[Object HTMLDivElement]", then "2".
Setting window.a masked the lookup of an element named "a".

We're immunized against those problems, because we rewrite all @id and most 
@name attributes with the per-gadget suffix, which makes it unlikely that a 
gadget can do meaningful interference with the host page's global scope.

If we didn't do that suffixing, an untrusted gadget might interfere with the 
host page's code by creating an element with a name that's meaningful but 
doesn't exist yet.  For example, a gadget might create a "JSON" element on a 
browser without the JSON object, and confuse host code that tests for the 
existence of JSON.

Case 2: DOM element masks other definition
  <form name="f">
    <input name="x">
    <input name="getAttribute">
  </form>
  <script>
    f.x = 3;
    f.y = 4;
    alert(f.x + ',' + f.y + ',' + f.getAttribute);
  </script>
That will show "[Object HTMLInputElement],4,[Object HTMLInputElement]".
Input elements mask any other interpretation of the name.

We do not rewrite the @name attributes of input elements, because those become 
part of the query parameter if the form is submitted.

So this gives a malicious gadget a couple ways that it could interfere with 
host page code.  For example, domita uses getAttribute quite a bit, but calls 
to getAttribute on that form element will fail.

I think this is "harmless" in that the worse that happens is the host code 
throws an unexpected exception, but I haven't thought through all the cases yet.

We can defend against that type of interference by being very careful about 
accessing properties of arbitrary DOM elements, but this is error-prone manual 
auditing, and innocent tamed functions aren't necessarily going to get this 
type of scrutiny.

It might be possible to discover these problems with static analysis, so that 
part of the taming process would be to run the linter.

It might be possible to add a per-gadget suffix to input @name attributes, and 
then remove the suffix before it gets used externally, such as form submission.

Original issue reported on code.google.com by felix8a on 22 Jun 2011 at 1:26

GoogleCodeExporter commented 9 years ago
todo:
* verify that input elements cannot be escalated into a security breach.
* see if suffixing input @name is viable.
* if suffixing isn't viable, see if domita can be hardened against input @name 
confusion.

Original comment by felix8a on 22 Jun 2011 at 1:28

GoogleCodeExporter commented 9 years ago
standards notes:
these magic name behaviors are specified by the WebIDL attributes
  [Replaceable]
  [ReplaceableNamedProperties]
  [OverrideBuiltins]
which are defined here
  http://dev.w3.org/2006/webapi/WebIDL/#es-extended-attributes
and used in various places in the html5 spec.

also, I seem to remember IE6 has somewhat different behavior, but I haven't 
checked that yet.

Original comment by felix8a on 22 Jun 2011 at 1:40

GoogleCodeExporter commented 9 years ago
fwiw, my oldish project to catch such occurences might be of interest — 
http://kangax.github.com/domlint/

Original comment by kan...@gmail.com on 22 Jun 2011 at 3:22

GoogleCodeExporter commented 9 years ago
This is less a threat now that Domado is cajoled, right?

Original comment by metaw...@gmail.com on 3 Aug 2012 at 9:26

GoogleCodeExporter commented 9 years ago
No; the issue is cases where names in the DOM get turned into properties of 
objects by the browser. The only aspect of Caja that affects this is what DOM 
trees a gadget is allowed to cause to exist.

Original comment by kpreid@google.com on 3 Aug 2012 at 9:39

GoogleCodeExporter commented 9 years ago
If innocent code in a host page is doing feature detection, guest code might be 
able to confuse it by naming a form or an input.  On the other hand, guest code 
can't assign to any properties of the node except whitelisted ones; creating a 
log method on a node named "console" would put the method in a weak map, not on 
the node itself, so innocent calls to console.log() would still fail.  And if 
there's a debugger running, its console would mask the form in the global scope.

Original comment by metaw...@gmail.com on 31 Aug 2012 at 9:57

GoogleCodeExporter commented 9 years ago

Original comment by kpreid@google.com on 11 Nov 2013 at 6:31