Le 29/04/2013 16:11, Kevin Reid a �crit :
> On Apr 29, 2013, at 6:19, David Bruant <
brua...@gmail.com> wrote:
>
>> So I was wondering if there was a good balance to be found that make deployment easier while getting rid of some security guarantees that are necessary only in the face of intentionally malicious code.
>> For instance, what is the best that can be done without the live server-side rewritter (rewriting the widget once with a command-line tool and loading the rewritten version can be considered acceptable for instance)?
> As Jasvir noted, Caja already has an almost pure client-side mode, ES5 mode (almost in that it still uses a server purely as a proxy to permit cross-origin/referrerless loading of resources).
I don't see how this server is provided in Jasvir example. Or is it the
cajaServer parameter of caja.initialize?
Interestingly, referrerless will be possible without a proxy in the
future [1]. In lots of circumstances, leaking the referrer isn't a huge
deal anyway.
Cross-origin requests are more annoying, but probably workable either
through CORS or having a copy of the widget on the server.
> Also, there is in fact a command-line tool (bin/cajole) which will work in nearly all of the cases where the server will.
>
>> What I looking for is a solution that would be easier to deploy with smaller runtime footprint but that would mostly confine well-behaving standard code, giving it the impression it leaves on its own page while only sitting on a div. And based on the different possible solutions, how hard would it be to develop it (I assume stripping out parts of Caja that wouldn't be necessary).
> I believe it is nearly trivial to do this. All you need to do is load the code which is responsible for constructing virtual pages:
>
> - domado.js (DOM virtualization wrapper),
> - html-emitter.js (constructing HTML from parser events),
> - and their dependencies.
Aren't they already loaded in caja.js to make Jasvir code snippet work?
Or maybe you meant the lighter Caja I'm asking for would just be the
parts that you just listed?
Do you have an idea of the order of magnitude all this code takes
minified? 100k? 300k?
> The one wrinkle is that you would have to stub out the calls into the Caja runtime intended to make secured objects; again, not that complex.
>
> You still need, for example, the HTML and CSS schema/whitelist, because it contains information about parsing and the semantic categories of language constructs which is important both for interpreting input content and to get correct virtualization (as opposed to having parts of one guest leak into another).
>
> Overall, the result of this would be essentially identical to ES5 mode, except that nothing would be frozen and there would be none of SES's workarounds for browser bugs; both of these would likely be significant performance improvements (the former because JS implementations tend to be optimized for the common case of not-frozen objects, and the latter because reimplementing built-in algorithms tends to be slow).
>
>
> There is another possibility for lightening which you did not mention: removing the requirement for 'standard code'.
In general, I'd like to try to keep things according to standard, but
what you list below as resulting in a perf boost often turns out to also
be good practices for other reasons or rarely used features.
> A lot of the heavy weight of the DOM virtualization arises from implementing the exact specified DOM interface behavior, or behavior that code in the wild expects; in this hypothetical case we would instead be free to implement our own subsetted or modified API.
>
> Off the top of my head, these are some possibilities for making things faster, or at least simpler:
>
> - Get rid of NodeList objects which are 'live' (update in response to DOM mutations), which are a pain to implement and require several layers of special gimmicks.
Very few people know that NodeLists are live. Even less do use this
property, so that's easy to give up for the vast majority of cases.
> - Remove the possibility of global (to a virtual document) variables; all executed scripts have clean lexical environments except for some explicit sort of export/import. (This would eliminate the need for a client-side (!) rewrite of JS and also simplify environment setup for eval.)
That's also a JavaScript good practice in general.
> - Remove all of the HTML parser special cases and require the input to be well-formed XML; this would mainly be less code but should remove some indirections.
Well-formed XML is not expected to be a good practice. Quoteless
attributes, some elements that don't need to be closed help authoring
and people use them extensively. However, well-formed HTML is a
requirement that could work.
> - Remove the node list puns, where window.frames === window and form elements are node lists of form elements.
Not that used in practice anyway.
> - Remove upward navigation, i.e. .parentNode .offsetParent .nextSibling and so on. This would allow more capability-styled access control and remove some of the necessary logic for creating a well-defined document boundary.
Forbidding that would probably break a lot of things, so that's fine to
keep.
Thanks Kevin and Jasvir for your insightful responses!
David
[1]
http://wiki.whatwg.org/wiki/Meta_referrer
[2]
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
[3]
https://bugs.webkit.org/show_bug.cgi?id=72674