Origin enables XSS to escalate to XSRF (was: security issue with XMLHttpRequest API compatibility)

On Thu, Apr 9, 2009 at 8:48 AM, Bil Corry <bil@corry.biz> wrote:
> My point is that a robust Origin moves us closer to better security
> controls, perhaps not all the way, but certainly much closer than
> CORS-Origin gets us.

I admit that I haven't followed in detail the various origin
proposals (cors, html5, ietf (withdrawn?)). I am glad to see that
people want an origin proposal with good security
properties. However, I fear all the current proposals amplify one of
the browser's worst security hazards -- abuse of ambient authority
creating confused deputy hazards. The current browser same origin
policy already has plenty of these problems
<http://waterken.sourceforge.net/aclsdont/>.

To be concrete, pages contain content -- whether mashups, gadgets, or
simple libraries -- whose authorship does not correspond to the
browser's notion of origin. As Crock said in his w2sp keynote
<http://w2spconf.com/2009/presentations/keynote-slides.pdf>, "A mashup
is a self inflicted cross site script." The problem isn't the mixing
of scripts representing different interests. The problem is that all
scripts that execute on a page are implicitly allowed to exercise all
the authority that this browser associates with that page's origin.

How do these origin proposals amplify this hazard? The main (only?)
motivation for the origin header is to enable servers to make
allow/deny access decisions on cross-origin requests based on the
presented value of the origin header. This means that a script running
on a page from origin A can now make a cross-origin request to a
server at origin B and exercise the authority that this server
associates with origin A. If some of these origin proposals still
allow the browser to present the credentials (e.g., cookies) that
browser associates with B, then, despite protestations to the
contrary, we have also failed to address existing XSRF dangers.

Three proposals I've seen in these threads, if combined and extended,
point towards a solution.

1) The thread starting at
<http://www.mail-archive.com/public-webapps@w3.org/msg02791.html> and
ending in:

On Tue, Apr 14, 2009 at 5:34 AM, Arthur Barstow <art.barstow@nokia.com> wrote:
> On Apr 14, 2009, at 6:33 AM, ext Thomas Roessler wrote:
>
>> So, to pick up on this discussion again -- I don't think we've had a
>> useful conclusion whether or not the client-side JavaScript code ought
>> to explicitly enable cross-site requests (as Tyler suggests, and as IE
>> implements in XDR) or not.
>>
>> All things considered, any thoughts?
>
> I tend to think that when adding new semantics, it generally makes sense to
> add new syntax to support those semantics and in this case that it would be
> better to err on the side of caution even if the mechanism chosen isn't
> particularly friendly to the app developer.

2) In the IETF origin proposal but absent from the cors proposal, a
browser (user agent) must send an origin header for cross origin
requests, but may send "Origin: null", i.e., identify only that this
is a cross-origin request without identifying what the requesting
origin is.

3) In some of these proposals, the browser may, should, or must
(apologies for losing track) not present its credentials for B when
making a cross origin request from A to B. (Note that the definition of
"credential" used in these discussions never mentions the new origin
header despite expectation that servers will use this header to make
access control decisions. This is confused.)


Being a language geek, I wouldn't describe Tyler's proposal as "new
syntax" but rather "distinct API". That nit aside, I agree with Arthur
that these
are adequate reasons to adopt this API change. But I care about this
for a bigger reason. It points the way to a general solution to the
ambient authority problems currently associated with browser origin policies.

In Tyler's proposal, there are different constructors for making
XMLHttpRequest objects. All such constructors would create
XMLHttpRequest objects with the same API but with different security
policies.
* The policy associated with the current constructor name
  would continue to refuse to make cross-origin requests.
* If, as I expect, there are people here who are attached to currently
  proposed policies, despite the ambient authority dangers, a
  different constructor could provide XMLHttpRequest objects with that
  behavior. (And future noscript-like browser extensions can disable
  it.)
* When the script initially occupying a page wishes to deny its own
  ambient authority to later scripts loaded onto that page, it can
  arrange that only our third constructor is available to them. This
  third constructor creates XMLHttpRequest objects that never transmit
  ambient credential information (e.g. cookies) and that adds
  "Origin: null" as an extra header to *all* requests, even those back
  to the page's own origin, in order to warn servers to treat all
  these requests as cross origin requests with no identified
  origin. This is the initial script's way of saying "Content on this
  page does not speak for me or my origin."

Tyler's proposal only mentioned the first two, in order to avoid
weakening the browser's current security. By adding the third
constructor, we could actually make browser security better,
rather than merely avoid making it worse.

As a concrete example, a Caja container currently has no way to allow
a sanitized (cajoled) script on its page even to make an
XMLHttpRequest back to its own origin without also transmitting the
browser's credentials for that origin.

Servers receiving such credential-free origin-free cross-origin
requests should honor them or not depending only on the explicitly
sent content of the message. A scripted component on a page must
therefore include all authorizing information explicitly within the
requests it makes.

Why identify even same origin requests as cross-origin? Given that all
cross-origin requests are identified as such, then even without the normal
credentials, the mere absence of an origin header identifies the
requestor as being from the same origin. This is in fact a form of
credential. If the containing page does not consider the script in
question to speak for it, then it shouldn't be allowed to implicitly
claim (by the absence of an origin header) to be from the same origin.

-- 
    Cheers,
    --MarkM

Received on Wednesday, 3 June 2009 23:22:18 UTC