W3C home > Mailing lists > Public > whatwg@whatwg.org > February 2011

[whatwg] Thoughts on recent WhatWG blog post

From: Adam van den Hoven <adam@littlefyr.com>
Date: Mon, 7 Feb 2011 15:15:02 -0800
Message-ID: <AANLkTimC_-f1p0tiCnYcJPZMAudYgB1zbLVDVPq9nq53@mail.gmail.com>
On Mon, Feb 7, 2011 at 12:03 PM, Aryeh Gregor
<Simetrical+w3c at gmail.com<Simetrical%2Bw3c at gmail.com>
> wrote:

> On Mon, Feb 7, 2011 at 12:33 PM, Adam van den Hoven <adam at littlefyr.com>
> wrote:
> > In reality all these belong to javascript, but modifying JS to include
> them
> > is not feasible. Also, what if I don't want to do crypto in my code, why
> > should I have all that lying around (not that its a hardship but why
> pollute
> > the global namespace)?
>
> Generally we try not to create new objects in the global namespace.
> Instead, we try sticking them on other preexisting global objects in
> most cases.
>

But that is exactly what has happened, or perhaps some existing pollution is
simply being codified. There is no meaningful connection between atob and
window. So yes it already exists... I'm just not sure that it should.


> > I think that we would all be better served if we were to introduce
> something
> > like CommonJS to the browser, or perhaps a modified version of the
> require()
> > method. This would allow us to move the crytpo and the atob/btoa into
> > specific modules which could be loaded using:
> >
> > <script>
> > var my_crypto = window.require( 'html:crypto' ); //or however you wanted
> to
> > identify the 'crypto library defined by html'
> > var my_util = window.require( 'html:util' ); // my_util.atob();
> > var $ = window.require( '
> > https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js' );
> > </script>
> >
> > and so on.
>
> What problem does this solve?  The problem of global namespace
> pollution?  Why not just define window.html (or some other single
> name) and make all the functions methods of that object?  This is kind
> of what we're doing already, although not so systematically.  Your
> solution seems overly complicated.


You could collect them into a single global object, and that was something I
though about, as well. But I think that this is a more generally applicable
solution. There are many libraries that do nothing but load javascript from
within javascript. They all do it by writing a script tag to the DOM. I
believe this is a code smell. Having a consistent way to do this sort of
thing would improve the lives of a lot of code developers and create some
consistency between what is happening on the server side as well.


> > Further, in CommonJS, the library has to export an object in order to
> make
> > it available. If we could define things in such a way that the browser
> > compiled the library independent of the page that loads it, the browser
> > could cache the *compiled* code and provide that to the browser page. It
> > would also be necessary to either enforce that these cached libraries be
> > immutable or that a copy of the compiled code be made available. I
> couldn't
> > implement this so I'm not sure how feasible this is but I suspect that
> > requiring immutability would be the easier to implement.
>
> What problem does this solve?  How is it better than inserting a
> <script> element, when the returned resource has suitable caching
> headers?
>

It seems to me that allowing a mechanism by which *compiled* javascript to
be cached between page requests should be a benefit.

Inserting a script element is great, so long as you're writing code that
only gets run in a browser. Sure you could write a shim that does this but
that argument could be made for a lot of things.


> > This would have two interesting effects. 'widgets' loaded this way could
> > easily be taken from different libraries, this jquery accordion that
> > mootools tree view. No having access means that it would have to require
> it
> > itself, and the normal scoping would keep that version internal to
> itself.
>
> How is this different from importing any well-behaved library?


The number of well behaved libraries is very limited and generally they
don't work well together.


> > Second, this could reduce security risks, if the widget requires a
> library
> > using some authoritative URL (say from Google's CDN), then some
> blackhatter
> > who injects JS onto a page by what ever means could not modify the
> meaning
> > of, say, jQuery.ajax to do something else. They would have to compromise
> the
> > the source code itself which is a significantly more difficult thing to
> do.
>
> What attacks does this prevent?  If an attacker can already inject JS,
> can't they pretty much do whatever they want?
>

Its quite simple. If you have a page that contains user contributed content,
you spend lots of time trying to prevent people from injecting bad code. For
example, if you were to bypass the filters (which unfortunately does happen
from time to time) you could redefine jQuery.ajax to send a copy to where
ever.

However, that requires that you have a copy of the jQuery object being used.
I'm suggesting that require returns a pristine copy, pulled from the object
cache (or what ever you would call it), so that copy could not be affected
by any malicious code, provided things are make immutable (for instance by
forcing something like Object.freeze). Further, the require creates a scope
into which no malicious code should be able to reach.

It seem to me that this achieves *some* of what Doug Crockford has talked
about in the past to create secure javascript. Because, at least in my head,
the compilation should be independent of the page that requested it, there
could be no access to the global namespace, from within the required script.
This would largely prevent any malicious individual from compromising the
libraries that you've loaded.

adam
Received on Monday, 7 February 2011 15:15:02 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 16:59:30 UTC