W3C home > Mailing lists > Public > public-webapps@w3.org > October to December 2012

Fwd: [XHR] Open issue: allow setting User-Agent?

From: Julian Aubourg <j@ubourg.net>
Date: Thu, 11 Oct 2012 15:09:07 +0200
Message-ID: <CANUEoeuVFTs1Gg0Dx2u2miRPryFdGspxCfqeVG++vp5uKtfu9A@mail.gmail.com>
To: public-webapps@w3.org
Sorry, I've been cut by keyboard short cuts :P

... so the burden of proof is on *you*. *You* have to establish the
consequences of making a backward incompatible change. Not brush away
arguments pro, or cons, to advance your agenda. Did you ask backend devs
why they white-listed browsers? Did you try and educate them? Did you ever
encounter any sensible use-case for this? Do you really want to break a lot
of backends expectations because you "don't see the reason"?

You have to be very careful with breaking backward compatibility. Just look
the jQuery's bug tracker for a prime example of what happens when you do.

We don't have to prove it is useful. We just have to prove it is used and
*you* brought this up yourself. Now you want to bypass this by pretty much
hacking client-side. Please make a compelling case for it.

> I still don't fully understand the scenario(s) you have in mind.

You're confusing the script's origin with the site's origin. XHR requests
from within a script are issued with the origin of the page that the script
is included into.

Now, read back your example but suppose the attack is to be pulled against
cnn.com. At a given time (say cnn.com's peek usage time), the script issues
a gazillions requests. Bye-bye server.

That's why I took the ad example. Hack a single point of failure (the ad
server, a CDN) and you can DOS a site using the resource from network
points all over the net. While the frontend dev is free to use scripts
hosted on third-parties, the backend dev is free to add a (silly but
effective) means to limit the number of requests accepted from a browser.
Simple problem, simple solution and the spec makes it possible.

Note that this use-case has nothing to do with filtering out a specific
browser btw. Yet you would break this with the change you propose.

Maybe it's not the best of examples. But I came up with this in something
like 5 minutes. I can't imagine there are no other ways to abuse this.

> This is a way more interesting (ab)use case. You're presuming that there
are web-exposed backend
> services that are configured to only talk to other backend servers, and
use a particular magic token
> in User-Agent as authentication? If such services exist, does being able
to send a "server-like" UA
> from a web browser make them significantly more vulnerable than being
able to send the same string
> from a shell script?

Same as above: single point of failure. You hack into a server delivering a
shared resource and you have as many unwilling "agents" participating into
your attack.

So far I see that only Jaredd seems to like the idea (in this thread

> I agree with Hallvord, I cannot think of any additional *real* security
risk involved with setting the
> User-Agent header.  Particularly in a CORS situation, the server-side
will (should) already be
> authenticating the origin and request headers accordingly.  If there
truly is a compelling case for
> a server to only serve to Browser XYZ that is within scope of the open
web platform, I'd really like to
> hear tha

By that line of reasoning, I don't see why we need preflight in CORS and
specific authorisation from the server-side for content to be delivered
cross-domain. It is not *open*. After all since any backend could request
the resource without problem, why should browsers be limited?

But then again, the problem has nothing to do with CORS but with
third-party scripts that effectively steal the origin of the page that
includes them and the single point of failure problem that arises. That's
why JavaScript is as sandboxed as it is.

In all honesty, I'd love to be convinced that the change is without
consequences, but the more I think about it, the less likely it seems.

---------- Forwarded message ----------
From: Julian Aubourg <j@ubourg.net>
Date: 11 October 2012 14:47
Subject: Re: [XHR] Open issue: allow setting User-Agent?
To: "Hallvord R. M. Steen" <hallvord@opera.com>

We end up in a philosophical disagreement here :-) I'd say that whatever
> browser the user decides to use is the user's choice and the server should
> respect that.

I'm sorry but that's complete non-sense. The backend is the provider of the
data and has all the right when it comes to its distribution. If it's a
mistake on the backend's side (they filter out while they didn't intend to)
just contact the backend's maintainer and have them fix this server-side
problem... well... server-side.

You're trying to circumvent a faulty implementation server-side by breaking
a client-side related spec backward compatibility. If you can't see how
wrong the whole idea is, I'm afraid you didn't have to suffer the
consequences of such drastic changes in the past (I had to with script tag
injection and it was a just a pure client-side issue, nothing close to what
you're suggesting in term of repercussions).

> One word: legacy. For example Amazon.com might want to enable CORS for
> some of its content. The team that will do that won't necessarily have any
> intention of blocking browsers, but will very likely be unaware of the
> widespread browser sniffing in other parts of the Amazon backend. (With
> sites of Amazon's or eBay's scale, there is in my experience simply no
> single person who is aware of all browser detection and policies). Hence,
> there is IMO non-negligible risk that a large web service will be
> "cooperative" on CORS but still shoot itself in the foot with browser
> sniffing.
> If I write, say, a CORS content aggregator, I would want it to run in all
> browsers, not only those allowed by the content providers. And I'd want to
> be in control of that. Hence, in my view this issue is mostly a trade-off
> between something script authors may need and more theoretical purity
> concerns.
First of all, my point was that the backend should be in control of its
content distribution, not some client-side javascript, and that it was
exactly in that spirit that the CORS spec had been written.

That being said...

You're shooting yourself in the foot here. It's because of legacy, hardly
(if ever) maintained backends that we shouldn't change this point of the
spec. What you're saying here is that people on the backend will adapt a
part of their site for CORS, realise there is filtering some place else yet
not try and fix the issue? And a client-side spec should be changed as a
consequence of this unbelievably lazy behaviour because...? They have to
make changes because of CORS anyway, let them go the extra mile.

Please leave unmaintained backends alone. You can expect your server's
behaviour to change if you change, say, the version of PHP you're using.
But to see it change because some client-side spec broke backward
compatibility? Did you write server-side code in the past?

I don't like browser sniffing any more than you do but I acknowledge that
it exists and is supported by the spec as a viable means to filter in/out
some or all browsers. From what I can tell from your use cases, you're
confronted to white listing which means the server intentionally guards
against unknown sources (stupidly but that's hardly the point).

As long as the spec doesn't change (and why should it?), the backend cannot
be tricked into delivering content by some javascript code in the browser
and I'm quite fine with it.

> Yes, this could give a generic library like jQuery less control of the
> contents of *its* request. However, there will still be plenty of requests
> not sent through XHR - the browser's main GET or POST for the actual page
> contents, all external files loaded with SCRIPT, LINK, IMG, IFRAME, EMBED
> or OBJECT, all images from CSS styling etc. Hence I still believe the
> information loss and effect on stats will be minimal.
> Also, the above could be a feature if I'm working on extending a site
> where I don't actually fully control the backend - think a CMS I'm forced
> to use and have to work around bugs in even if that means messing with how
> jQuery sends its requests ;-).
Point is you make it possible to rig the game pretty badly. It's not about
jQuery losing control (in fact the code snippet will set the user agent
string for all script-initiated requests, no matter the lib, even in pure
javascript): good luck with your usage analytics on single page apps,

>> Oh, I agree entirely. Except checking User-Agent is a quick and painless
>> means to protect against malicious JavaScript scripts. I don't like the
>> approach more than you do, but we both know it's used in the wild.
> I'm afraid I don't know how this is used in the wild and don't fully
> understand your concerns. Unless you mean we should protect dodgy SEO
> tactics sending full site contents to Google bot UAs but a paywall block to
> anyone else from user-applied scripts trying to work around that?

The burden of proof is on you. *You* ha

>  A malicious ad script would presumably currently have the user's web
>>> browser's User-Agent sent with any requests it would make
>  The malicious script can trick the server into accepting a request the
>> backend expects to be able to filter out by checking a header which the
>> standard says is set by the browser and cannot be changed by user scripts.
>> Think painless DOS with a simple piece of javascript.
> I still don't fully understand the scenario(s) you have in mind.
> For a DOS attack you'd be launching it against some third-party site (it
> doesn't make sense for a site to DOS itself, right?). Trying to understand
> this, here are my assumptions:
> * The threat scenario is trying to DOS victim.example.com by getting a
> malicious javascript targetting this site to run on cnn.com or some
> similar high-volume site. (The attacker presumably needs to run the script
> on a high-volume site to be able to generate enough bogus requests for a
> successful DOS attack). This can be achieved for example by hacking into
> some service that delivers ads to cnn.com or in-transit modification of
> scripts requested by cnn.com (only for end users downstream of your
> network location).
> * The malicious script will be using XHR in an attempt to DOS
> victim.example.com (if it uses other ways to do it, it's outside the
> scope of what we're trying to decide)
> * The concern is whether allowing a custom User-Agent for XHR requests
> makes this scenario harder to defend against.
> * You're saying that victim.example.com may have a white-list of
> User-Agent strings as a security measure to avoid serving content in
> response to requests presumed to be malicious, and that this helps them
> avoid XHR-based DOS attempts.
> First observation is that victim.example.com needs to enable CORS for
> this attack venue to be possible in the first place. This to some extent
> limits the feasibility of the whole exercise (sites that are commonly
> targeted for DOS attacks are perhaps not likely to enable CORS - partly
> because it may make them more vulnerable to malice).
> Secondly, this attempted DOS attack uses in-browser JavaScript (again, if
> it uses any other method it's outside of our scope). Out of the box, all
> the requests will be sent with the browser's original User-Agent string. As
> we're launching our attack from end users' regular web browsers, there is a
> very high chance that the User-Agent string is already on
> victim.example.com's whitelist. Hence, the DOS script will probably be
> more successful if it does *not* set User-Agent.
> Why would setting User-Agent make the malicious script more effective at
> DOSing victim.example.com?
>  but the use-case is really to prevent browsers from mascarading as
>> servers).
> This is a way more interesting (ab)use case. You're presuming that there
> are web-exposed backend services that are configured to only talk to other
> backend servers, and use a particular magic token in User-Agent as
> authentication? If such services exist, does being able to send a
> "server-like" UA from a web browser make them significantly more vulnerable
> than being able to send the same string from a shell script?
> --
> Hallvord R. M. Steen
> Core tester, Opera Software
Received on Thursday, 11 October 2012 13:09:36 UTC

This archive was generated by hypermail 2.3.1 : Friday, 27 October 2017 07:26:49 UTC