ES4 Security

Brendan Eich brendan at
Mon May 19 15:21:18 PDT 2008

On May 18, 2008, at 7:50 AM, Steven Mascaro wrote:

> On Sun, May 18, 2008 at 7:54 PM, Brendan Eich <brendan at>  
> wrote:
> Brendan wrote:
>> I think you kept it too short. :-/
> I've been accused of being verbose, so I tried to keep my *opening*
> statement concise. It was meant as an invitation to discussion, not a
> final statement.

I got your intent, but vague feel-good words (sorry, that's  
unfortunately what "security" and too often "privacy" are) do not  
help us make progress in this forum. Kinda like appealing to  
motherhood and apple pie ;-). From a post to es4-discuss I wrote last  

> Security is an "issue" (not in the Oprah sense), all right. A bit  
> more precisely, it is a set of end-to-end properties that need  
> solid enforcement mechanisms at many layers of abstraction.  
> Security is however not a unitary good or "product".

So we should talk about specific, well-defined properties that can be  
verified somehow (whether statically or not).

>> "Cross-site" exploits happen on the server side too. They're possible
>> in proxies and other kinds of gateways. They arise when data
>> originating from different trust domains mix in ways that lose track
>> of each datum's trust label (ignore policy questions, including the
>> folly of putting the user in the loop). The mixing involves control
>> flow, so the problem is not solvable by data-labeling alone.
> I'm confused. Aren't these man-in-the-middle attacks? Yes, there are 3
> parties, but the structure and solution (usually
> encryption/signatures/hash checks) is different.

No MITM -- think mashups, user-generated content hosting (myspace,  
lj, etc.). Firefox and other Mozilla-based apps are indeed the ur- 
mashup (code and markup loaded from various origins mixing in a  
single JS runtime).

> For example, suppose that it were possible to retrieve the text of any
> <script src="..."></script> element using '.textContent' from
> javascript, regardless of origin. You'll agree that this is
> unthinkable today. But I assume you'll also agree that there is no
> security problem in doing this if no cookies (or other private data)
> are sent in the initial request to retrieve the script page?

Absolutely not. Why do you think that would be safe? Shaver's  
followup shows a "Princeton attack" against inside-the-firewall known- 
intranet-address data. That's just one problem. You can blame the  
firewall or doc-hosting server admin, but it's a real-world problem.

In the Netscape 3 data tainting model, with a much simpler DOM,  
properties of equivalent asset value would be tainted with the page's  
origin. They could freely flow into scripts loaded from other  
origins, but the results (*any* results) could not leak back  
(feasibly, or at least in practically cheap-enough flows) to the  
other origins' servers. But as I've noted in the last message and in  
recent talks about this experiment, the purely dynamic information  
flow system cannot untaint the virtual machine pc, so taint mixtures  
accumulate badly. The system is too pessimistic, for want of static  
analysis -- a hybrid approach I'm experimenting with now.

In the same-origin model under which we all suffer still, there's no  
taint or trust label associated exactly with .textContext's value, so  
to protect this asset, ignoring cookie leaks, we would be relying (as  
we do for all such DOM assets today) on the access-control checks  
done between trust containers (window objects, "frames" in general).  
This is a bad bet, because browsers constantly patch bugs in their  
leaky inter-frame reference monitors. This is the bigger problem I  
alluded to above ("That's just one problem").

> The same issues affect XMLHttpRequest. The solution adopted by 'AJAX'
> developers is to ask their own server for the page, which is
> equivalent to asking for the page without cookies. The recently
> suggested cross-site XMLHttpRequest extensions still do not solve the
> problem completely (the original page sends cookies to the 3rd party
> server, which may not be what either the original page or the user
> wants).

Right, and cookies are a hot point of contention in the W3C Web API  
working group, and among Mozillans, right now. We pulled XS-XHR based  
on the draft recommendation from Firefox 3 in order to get it right,  
and avoid spreading a de-facto standard before the de-jure one was  
finished (this is a chicken and egg situation; some on the working  
group would want us to set precedent -- I think that's wrong, but I  
understand it, and so [evidently] does Microsoft).

This is getting far afield from es4-discuss, however. Suggest we take  
it to a w3c public list, if there is one.

> If there are non-cookie examples of XSS, please point me to them
> (setting aside equivalents like DOM storage, but also the :visited
> example from below).

Yikes. Where to start? 

>>> Once this problem is solved, ES4 *does* *not* need RO/DD/IH for
>>> security. (IH=information hiding.)
>> Now you've changed the subject to Integrity.
> No, I am talking about Integrity, Confidentiality and more (like
> Authenticity).

Sorry, but you wrote "Once [a Confidentiality problem is solved], ES4  
*does* *not* need [Integrity features]". I disagreed -- even  
excluding the programming-in-the-large reasons for those Integrity  
features -- and gave my reasons. Cookies are not the only or even the  
main pain point.

>>> It is not about whether RO/DD/IH can make development/maintenance
>>> easier.
>> The main issue in ES4 is not "development/maintenance", it's being
>> able to make sane type judgments (static or dynamic, doesn't matter),
>> at all.
> So making application development and maintenance as simple as
> possible is *not* your Number 1 Priority?

You didn't see me write that, so please don't put your interpretation  
in my mouth.

> Who, in that case, are you developing ES4 for? Theoreticians?

This is a cheap shot. C'mon.

Type judgments mean something to programmers, even in JS today.  
Consider the "which Object or Array constructor got called" JSON  
issue alone.

JS hackers have to hand-code their own type tests today, using  
typeof, instanceof, and ad-hoc "shape testing". Ajax libraries do  
this all the time. The virtues of duck-typing are well-known, but  
there's a down side. If you disagree, we should have a better  
argument about this topic in a separate thread.

Writing a bunch of duck-typing code is more onerous than writing a  
'like' test in ES4, and there's no way to write an 'is' test (the  
subtype relation enforced on every write to a type-annotated variable  
in ES4) in ES3 today. The duck could turn into a monster a split  
second after the duck-type test executes.

Therefore I believe that ES4 makes application development and  
maintenance strictly better, compared to ES3. If you have not read  
the evolutionary programming tutorial (only slightly out of date),  
you really ought to. My blog has a slideware version of it that's  
even quicker to digest, from last fall.

I can understand programmers favoring dynamic languages for good  
reasons, and viewing type systems such as Java's with alarm. I'm on  
that "side" often enough, myself.

What I can't abide is painting ES4 as a "static language" (heck,  
we've even dropped the optional type checker from the draft specs!),  
or rejecting systematic thinking about types and programming in the  
large. Every JS programmer working on non-trivial web app code today  
must design and enforce (or not) a latent type system in untyped JS,  
which interacts heavily with nominal types in the DOM and browser  
objects. Every JS programmer today doing non-trivial work must deal  
with name clash hazards and modularity pitfalls.

ES4 supports the untyped idiomatic styles used with ES3, but also  
gives programmers tools otherwise unavailable to harden abstractions  
against unwanted mutation, hide names cheaply, suspend and resume  
functions, and eliminate error-prone boilerplate (which is verbose  
enough in ES3 that it's often skipped). I've posted on this before.  
See the thread:

of course the annotated slideware blog post I cited above.

> After reading up on implicit flows, I still have no idea what
> 'tainting the pc' means. In any event,

Consider this code:

   var A = 0, C = 0;
   var B = secret;
   if (B) {
     A = 1;
   } else {
     C = 1;

In unsound dynamic-only data tainting, if B (secret) is true, then A  
will be tainted with the secret's label, else C will be. But this  
misses the "implicit flow" (Dorothy Denning, SOSP 1976 -- an OS  
journal, that's where the action was then!) through the else or then  
clause not taken and into the other (C or A) variable.

So in sound dynamic data tainting, one must associate a trust label  
with the state of execution, call it the program counter (pc), and  
taint the pc when control flow forks based on a secret (on any data  
whose trust label is not the pc's label). The tainted pc then taints  
effects in all paths that could be taken -- this handles implicit flows.

The problem then becomes untainting the pc. Netscape 3's optional  
security model could not untaint, lacking static analysis of all  
possible effects committed by alternative control flow graph paths  
(liveness analysis can help too). Such analyses are hard without more  
certainty about name binding and data types.

This is an interesting area of research, which we're pursuing at  
Mozilla in partnership with some academic researchers. I'll have more  
to say about it shortly.

> it would seem to me that
> data-tainting is impossible without integrity. And I'm arguing that
> tight cookie policies would ensure integrity.

I think you are missing the big picture by focusing on cookies. There  
are, and will be for a while yet, too many ways to leak data.

> But if no cookies are sent, there is no problem. For example, suppose
> did the following instead:
> <script
> src=" 
> address-book.json"></script>
> can do that today, and will forever be able to do that.
> There is no problem, though, because the 'graburl.cgi' script can't
> send the user's cookies to I don't understand why
> there is any confusion about this.

There's no confusion. You are simply assuming proper authentication,  
which is over-optimistic (Murphy was an optimist). Joe Walker's blog  
did not get read by everyone using JSON across origins. Reality bites  
(major sites have had firedrills).

Defense in depth requires more than one line of defense. This is why  
cookie-sending in XS-XHR is a hot issue. Will existing sites fail to  
authenticate where they should? Will they naively extend their  
existing auth systems from XHR to XS-XHR, compromising non-public  
data? Will mashup sites over-auth too much thereby training users to  
re-enter reusable credentials? These are hard, ultimately human- 
factors problems. The solutions are not obvious, and the difficulties  
here are vexing the Web API committee, or at least the members of it  
I know.

To get away from XS-XHR and back to JSON data and JS/ES: Jesse's  
whole point in filing that Mozilla bug was to plead for greater  
defense in depth, specifically greater Integrity for object and array  

> In fact, if you really do like the defense-in-depth idea (and I'm
> loathe to suggest this), you could implement the cookie restrictions
> I've argued for PLUS the language restrictions.

Now you are talking! (I'm not kidding.)

>> "Security" is a big topic, not something to simplify with too few
>> words. You cannot reduce a difficult argument to a short-hand formula
>> that "proves" ES4 should let Object or Array be overridden (or not).
> I believe you can't 'prove' much that's interesting, anyway... (again,
> that's why I don't believe in the utility of code verification).

Bill Gates begs to differ (device driver verification, also great  
work from various MSR researchers), and we're seeing wins from static  
analysis in the Mozilla world. Not full program verification, mind  
you, but formal methods should not be dismissed wholesale based on  
poor results from the past. Proving correctness and soundness are  
hard, but checking programmer assumptions and would-be invariants --  
that's what ES4 makes easier with its gradual types. That kind of  
"model-checking" or "shape testing" is also what a lot of JS code,  
and a lot of Mozilla code (including C++ code) needs.

You don't have to "believe in the utility" of anything. Either  
analysis is useful, or it isn't. It's clear that checking latent  
types in JS, or checking other invariants that can't be expressed via  
the weak notion of types in JS and the DOM today, is hard enough that  
Ajax libraries spend a great many lines of code on it, with  
standardized patterns and helpers. Such code patterns are signs of  
gaps in JS1/ES3, and the Ajax libraries can't fill these gaps  
completely (e.g., because they can't guarantee name bindings or seal  
objects against mutation).

> In the message I found, you mention logging (and other post-hoc
> instrumentation) as a potential use for AOP. Being from a simulation
> background, I'd find statistics a compelling use. Being a programmer,
> I'd find debugging a compelling use. Being a hacker (not cracker!),
> I'd find modifying other people's code another compelling use.

Not to digress again, but the conclusion Mitch reached, in his  
summary words, was "sound plugin APIs good, AspectJ-like hacks bad".

Debugging is a whole other can of worms. It must be able to violate  
abstractions. But let's leave it for another day. It should be  
sufficient to note here that debuggers are privileged in ways  
ordinary ES code, even with ES4 reflection APIs being proposed, is not.


-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Es4-discuss mailing list