Last Comment Bug 778548 - CORS preflight fails with Basic Authentication
: CORS preflight fails with Basic Authentication
Status: UNCONFIRMED
:
Product: Core
Classification: Components
Component: DOM (show other bugs)
: 14 Branch
: x86_64 Windows 7
: -- normal with 4 votes (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-07-29 08:21 PDT by ewolfman
Modified: 2013-04-04 13:52 PDT (History)
6 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
FF_authentication_error.png (42.90 KB, image/png)
2012-07-29 08:21 PDT, ewolfman
no flags Details
Chrome ignores 401 on the OPTIONS result (214.60 KB, image/png)
2012-07-29 22:58 PDT, ewolfman
no flags Details

Description ewolfman 2012-07-29 08:21:17 PDT
Created attachment 646970 [details]
FF_authentication_error.png

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Build ID: 20120713134347

Steps to reproduce:

Attempted to call a web service with Basic Authentication, with preflight. 

Steps to reproduce:
            var invocation = new XMLHttpRequest();
            var url = 'http://OtherServer/MyService.asmx/HelloWorld';
            var params = JSON.stringify({'name':'Joe'});
            invocation.open('POST', url, true);
            invocation.setRequestHeader('Authorization', 'Basic <base 64 credentials>');
            invocation.setRequestHeader('Content-Type', 'application/json');
            invocation.setRequestHeader("Content-length", params.length);
            invocation.withCredentials = true; 
            invocation.onreadystatechange = function () {
                if (invocation.readyState == 4) {
                    alert(invocation.responseText);
                }
            };
            invocation.send(params);

The IIS server is configured to return the following headers:
        <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
        <add name="Access-Control-Allow-Origin" value="http://origin-name" />
        <add name="Access-Control-Allow-Headers" value="Content-Type,Authorization" />
        <add name="Access-Control-Allow-Credentials" value="true" />




Actual results:

The web server returns a 401 for the preflight because the Authorization header is not being sent at that point, and as a result FF does not proceed to make the original request (with the Authorization header). BTW Chrome ignores the 401 on the OPTIONS and proceeds as expected to the original request.

withCredentials doesn't seem to have any effect whatsoever in this case, so omitting the client and server credentials is meaning-less


Expected results:

Obviously the server will return a 401 for the preflight because the Authorization header is not sent. Therefore I expect OPTIONS with a return code of 401 to be ignored in order to allow the original request to be processed with the Basic Authentication 'Authorization' header, just like in Chrome.
Comment 1 ewolfman 2012-07-29 08:39:46 PDT
BTW this resembles a conversation in #597301
Comment 2 Boris Zbarsky [:bz] 2012-07-29 19:22:08 PDT
> Obviously the server will return a 401 for the preflight because the Authorization header
> is not sent.

That would be a bug in the server, if so, if it actually wants to make the data accessible.

Per spec, an error response to the Options request requires that the original request not be made.  In particular, see http://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request which clearly says:

  
  If the response has an HTTP status code that is not 200
    Apply the network error steps.

I'm surprised that you say Chrome does something different.  Adam, do you know what that's about?
Comment 3 Boris Zbarsky [:bz] 2012-07-29 19:24:39 PDT
And yes, this is somewhat like bug 597301 except the spec has been clarified since then.
Comment 4 ewolfman 2012-07-29 22:30:31 PDT
Even if the spec says that, it does not make sense. Obviously the server would fail the authentication because no authorization header is sent at that stage. So all requests that perform a preflight to a non-anonymous web server would fail at this point - where's the logic in that?

Moreover, in IIS 6 or IIS7 with a classic App Pool one cannot configure the server to return a return code other than 401 in such a case.

And yes - this works in Chrome (v. 20)
Comment 5 ewolfman 2012-07-29 22:58:59 PDT
Created attachment 647074 [details]
Chrome ignores 401 on the OPTIONS result

Attached is a screenshot from Chrome. Chrome ignores 401 on the OPTIONS request, thus allowing the original request to be authenticated using the Authorization header - as expected.
Comment 6 Boris Zbarsky [:bz] 2012-07-30 00:46:02 PDT
> Even if the spec says that, it does not make sense.

Sure it does.  The point of the preflight is to avoid making the actual request unless the server opts in.  Any browser that ignores failures on the preflight and goes on to make the actual request is a security hole allowing cross-site attacks.

> Obviously the server would fail the authentication because no authorization header is
> sent at that stage.

Only if the server tries to authenticate preflights.  Which it shouldn't, since those never send any authentication information!

> Moreover, in IIS 6 or IIS7 with a classic App Pool one cannot configure the server

That's a problem for people using those servers, but doesn't mean that everyone else should be insecure as a result.

I reported http://code.google.com/p/chromium/issues/detail?id=139566
Comment 7 Boris Zbarsky [:bz] 2012-07-30 00:47:00 PDT
Note, by the way, that if you really think the spec should change you should raise that on public-webapps@w3.org
Comment 8 ewolfman 2012-07-30 07:01:37 PDT
It will be interesting to see how Chrome will reply here...
I have emailed to w3 as you suggested.

I think that although you have a point with regards to the current spec, there is a real issue here. If the preflight is supposed to negotiate headers and origins and OK the requests, either it should be determined that it does not authenticate (and therefore should ignore 401), or it should pass the credentials to negotiate them as well. 

Although you claim that "this is a problem for people using those servers", there are quite a few of those people... and they can't be ignored...
Comment 9 Boris Zbarsky [:bz] 2012-07-30 08:31:50 PDT
Passing credentials with the preflight is a security risk; that's why it doesn't do that....

I realize that a lot of people use the servers in question; the question is whether their setup can be made to work in spite of their servers' limitations without making _other_ server setups vulnerable in the process.
Comment 10 ewolfman 2012-07-30 08:56:43 PDT
I'll try to see whether I can configure IIS Classic App Pool to override the default 401 and will report back if successful. I don't think it's possible, but I'll give it (another) shot. Naturally it's possible to set the security to anonymous and then manually return 401 when needed, but that's even a greater risk IMHO.

BTW: for IIS Integrated App Pool this is very easy to overcome.
Comment 11 Boris Zbarsky [:bz] 2012-07-30 09:31:48 PDT
ewolfman, does http://nightly.webkit.org/ show the same behavior for you as Chrome does?
Comment 12 ewolfman 2012-07-30 11:05:55 PDT
Yes, it does.
Comment 13 Boris Zbarsky [:bz] 2012-07-30 11:13:04 PDT
Thank you for checking that!
Comment 14 Olli Pettay [:smaug] 2012-07-30 15:56:22 PDT
(In reply to ewolfman from comment #8)
> It will be interesting to see how Chrome will reply here...
> I have emailed to w3 as you suggested.

Could you post a link to the email thread?
I can't see it http://lists.w3.org/Archives/Public/public-webapps/
Comment 15 ewolfman 2012-07-30 21:44:21 PDT
I don't see it either. I got the following notice (also when trying to resend):

"Thank you, your message has now been marked as approved for archiving on our site. It may be subject to further delays before being distributed to the list; for example, it will be checked for viruses and spam, and tested against various list-specific posting restrictions."
Comment 16 Olli Pettay [:smaug] 2012-07-31 03:39:42 PDT
You may need to subscribe to that list. Search for public-webapps in http://lists.w3.org/Archives/Public/

Note You need to log in before you can comment on or make changes to this bug.