Re: Fetch: HTTP authentication and CORS
On 7 mai 2013, at 02:23, HU, BIN wrote: Because nonce is needed to generate the appropriate digest, the 401 challenge is required. So the lesson here is: any developer that intends to use authenticated XHR should always start with an XHR that is a simple ping-like GET, then do the real things. Right? Paul
RE: Fetch: HTTP authentication and CORS
That is correct. Thanks Bin From: Paul Libbrecht [mailto:p...@hoplahup.net] Sent: Wednesday, May 08, 2013 1:14 PM To: HU, BIN Cc: Hallvord Reiar Michaelsen Steen; Jonas Sicking; Anne van Kesteren; WebApps WG; WebAppSec WG Subject: Re: Fetch: HTTP authentication and CORS On 7 mai 2013, at 02:23, HU, BIN wrote: Because nonce is needed to generate the appropriate digest, the 401 challenge is required. So the lesson here is: any developer that intends to use authenticated XHR should always start with an XHR that is a simple ping-like GET, then do the real things. Right? Paul
Re: Fetch: HTTP authentication and CORS
I had a discussion with Hallvord on IRC about the exact semantics we want for HTTP authentication in the context of CORS (and in particular for XMLHttpRequest, though it would also affect e.g. img crossorigin). So me and Anne have been going a bit back and forth on IRC, we agree on some stuff and disagree on other points - and we fundamentally agree that some implementor review and input would be valuable to really settle a conclusion on how this murky little intersection of specs should work.. So the basic issue is HTTP authentication (cached and/or supplied by JS) with XHR, and its interaction with CORS and other stuff like the anonymous flag and withCredentials. Username/password can be passed via open() or the URL. In that case we first check if the server challenges us (do a request without Authorization that results in a response with status 401). So far I agree :) For CORS, we'd return to the caller right there. Here I don't agree anymore. If I want to retrieve a HTTP auth-protected resource with XHR from a CORS-enabled server, the natural thing to do seems to try to pass in the user name and password in the XHR open() call. If the script author supplied user/pass and the server says 401 on a request without Authorization: surely the natural next step is to re-try with Authorization:? Granted, my scenario takes a little bit more work before we reach this point: I think that if user/pass are supplied in open() or URL for a CORS request, the implementation must detect that the request requires preflight, and send Access-Control-Request-Headers: Authorization as part of that preflight. Now, this is most definitely a corner case, me an Anne are both concerned about implementation complexity but we seem to draw different conclusions - I think that most of the infrastructure here is going to be in place already and making special XHR-CORS exceptions might be just as complex as implementing retry-with-Authorization, whereas I believe Anne thinks I'm prescribing too much complexity for too little gain. If the Authorization header is set via setRequestHeader() we'd treat it as any other header. We assume the developer already checked if he was challenged or not, etc. I agree with that :) If an Authorization header was cached for the URL in question (previous visit) we'd never reuse that under CORS. This *might* be a case for withCredentials - but it doesn't make much sense given that a JS author can't be expected to know if there are cached credentials for some other site, so we've dropped that. However, most browsers prompt for user/pass if XHR (or IMG) requests are challenged - so we need a loophole that make sure the cached credentials from a request *triggered by* XHR *are* used (this is one place that gets overly complex - I'd definitely love to nuke the whole prompts-for-user/pass in response to JS/inlines misfeature. Anyone else agrees we can kill it without too much compat pain..?) I'd be great to know if there's consensus on this. General not caring works too. Implementor views most welcome, including I don't really care, either way works for us :-) BTW, here's a sort of (amateur) flow chart for what I'm proposing - after accepting some of Anne's feedback: https://www.w3.org/Bugs/Public/attachment.cgi?id=1359 I just noticed I have omitted same-origin requests with anonymous flag set - if these get a 401 response we should probably go straight to Done, content denied. -- Hallvord R. M. Steen Core tester, Opera Software
Re: Fetch: HTTP authentication and CORS
On Mon, May 6, 2013 at 10:45 AM, Hallvord Reiar Michaelsen Steen hallv...@opera.com wrote: I had a discussion with Hallvord on IRC about the exact semantics we want for HTTP authentication in the context of CORS (and in particular for XMLHttpRequest, though it would also affect e.g. img crossorigin). So me and Anne have been going a bit back and forth on IRC, we agree on some stuff and disagree on other points - and we fundamentally agree that some implementor review and input would be valuable to really settle a conclusion on how this murky little intersection of specs should work.. So the basic issue is HTTP authentication (cached and/or supplied by JS) with XHR, and its interaction with CORS and other stuff like the anonymous flag and withCredentials. Username/password can be passed via open() or the URL. In that case we first check if the server challenges us (do a request without Authorization that results in a response with status 401). So far I agree :) For CORS, we'd return to the caller right there. Here I don't agree anymore. If I want to retrieve a HTTP auth-protected resource with XHR from a CORS-enabled server, the natural thing to do seems to try to pass in the user name and password in the XHR open() call. If the script author supplied user/pass and the server says 401 on a request without Authorization: surely the natural next step is to re-try with Authorization:? If the caller to the XHR.open() call provided a username and password, then shouldn't the implementation send that information in the *first* request rather than waiting for a 401? Well.. first request after having done a preflight which checks that the server is ok with an Authorization header being specified? / Jonas
Re: Re: Fetch: HTTP authentication and CORS
Here I don't agree anymore. If I want to retrieve a HTTP auth-protected resource with XHR from a CORS-enabled server, the natural thing to do seems to try to pass in the user name and password in the XHR open() call. If the script author supplied user/pass and the server says 401 on a request without Authorization: surely the natural next step is to re-try with Authorization:? If the caller to the XHR.open() call provided a username and password, then shouldn't the implementation send that information in the *first* request rather than waiting for a 401? I'd like to do that, but Anne thinks it violates the HTTP protocol (and apparently is hard to implement on top of certain networking libraries?). Any networking devs who would like to comment on that? -- Hallvord R. M. Steen Core tester, Opera Software
Re: Re: Re: Fetch: HTTP authentication and CORS
Here I don't agree anymore. If I want to retrieve a HTTP auth-protected resource with XHR from a CORS-enabled server, the natural thing to do seems to try to pass in the user name and password in the XHR open() call. If the script author supplied user/pass and the server says 401 on a request without Authorization: surely the natural next step is to re-try with Authorization:? If the caller to the XHR.open() call provided a username and password, then shouldn't the implementation send that information in the *first* request rather than waiting for a 401? I'd like to do that, but Anne thinks it violates the HTTP protocol Replying to self, this would break the authentication method negotiation that HTTP allows (i.e. selection of basic, digest, and more proprietary stuff like NTLM). Hence we should wait for a 401 challenge. (Could we however fix this in CORS so that the WWW-Authenticate header could be included in a preflight response where applicable?) -- Hallvord R. M. Steen Core tester, Opera Software
Re: Re: Re: Fetch: HTTP authentication and CORS
On Mon, May 6, 2013 at 1:39 PM, Hallvord Reiar Michaelsen Steen hallv...@opera.com wrote: (Could we however fix this in CORS so that the WWW-Authenticate header could be included in a preflight response where applicable?) Maybe we should wait for actual complaints about XMLHttpRequest + CORS lacking integrated support for HTTP authentication before complicating the protocol even more with unused garbage. In other words, given that the majority of sites are not using a variant of HTTP authentication at the moment I don't think further enshrining it is worth the cost. -- http://annevankesteren.nl/
RE: Re: Fetch: HTTP authentication and CORS
If we are talking about RFC2617 HTTP Authentication, there are 2 authentication models: (1) Basic Authentication model: Under this circumstance, basically client can send the username:password pair at the first request, e.g. in the form: https://username:passw...@www.example.com/path which in turn maps to an HTTP header Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== Where username:password is BASE64-encoded. Because of the vulnerability of Basic Authentication model (without encryption), https is strongly recommended. But in practice, Basic Authentication is rarely used, and it is mostly based on a challenge-response model, where the server challenges with 401 code, and a Authentication header to ask for Basic Authentication: WWW-Authenticate: Basic realm=WallyWorld (2) Digest Authentication model: Digest scheme is always based on challenge-response, and server challenges with 401 code, Authentication heade, and other important information such as nonce, e.g.: HTTP/1.1 401 Unauthorized WWW-Authenticate: Digest realm=testre...@host.com, qop=auth,auth-int, nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093, opaque=5ccc069c403ebaf9f0171e9517f40e41 so that client can apply the appropriate digest algorithm, such as MD5, and generate the response: Authorization: Digest username=Mufasa, realm=testre...@host.com, nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093, uri=/dir/index.html, qop=auth, nc=0001, cnonce=0a4f113b, response=6629fae49393a05397450978507c4ef1, opaque=5ccc069c403ebaf9f0171e9517f40e41 Because nonce is needed to generate the appropriate digest, the 401 challenge is required. Hope it helps Bin -Original Message- From: Hallvord Reiar Michaelsen Steen [mailto:hallv...@opera.com] Sent: Monday, May 06, 2013 11:13 AM To: Jonas Sicking Cc: Anne van Kesteren; WebApps WG; WebAppSec WG Subject: Re: Re: Fetch: HTTP authentication and CORS Here I don't agree anymore. If I want to retrieve a HTTP auth-protected resource with XHR from a CORS-enabled server, the natural thing to do seems to try to pass in the user name and password in the XHR open() call. If the script author supplied user/pass and the server says 401 on a request without Authorization: surely the natural next step is to re-try with Authorization:? If the caller to the XHR.open() call provided a username and password, then shouldn't the implementation send that information in the *first* request rather than waiting for a 401? I'd like to do that, but Anne thinks it violates the HTTP protocol (and apparently is hard to implement on top of certain networking libraries?). Any networking devs who would like to comment on that? -- Hallvord R. M. Steen Core tester, Opera Software
Re: Fetch: HTTP authentication and CORS
On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote: In the Gecko implementation they aren't. Assuming that you mean when with credentials is set to false? Right, when it's set to false. What's the normative reference for TLS client certificates? https://tools.ietf.org/html/rfc5246#section-7.4.6 maybe? We also don't reuse keep-alive http connections. Are we talking about persistent connections as per http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete HTTP/1.0 feature? -- http://annevankesteren.nl/
Re: Fetch: HTTP authentication and CORS
On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote: On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote: In the Gecko implementation they aren't. Assuming that you mean when with credentials is set to false? Right, when it's set to false. What's the normative reference for TLS client certificates? https://tools.ietf.org/html/rfc5246#section-7.4.6 maybe? We also don't reuse keep-alive http connections. Are we talking about persistent connections as per http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete HTTP/1.0 feature? In the sense of the keep-alive header. I'm not sure, but I think it was defined in HTTP 1.1. / Jonas
Re: Fetch: HTTP authentication and CORS
* Jonas Sicking wrote: On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote: On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote: We also don't reuse keep-alive http connections. Are we talking about persistent connections as per http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete HTTP/1.0 feature? In the sense of the keep-alive header. I'm not sure, but I think it was defined in HTTP 1.1. It's extremely unlikely that the `Keep-Alive` header is special here. It rather seems to me you meant We also don't reuse http connections. A HTTP connection has to be persistent, has to be kept alive, in order for it to be re-used, and how or why a connection is kept alive does, most probably, not affect whether Firefox will re-use it in your sense above. And no, HTTP/1.1 as defined in RFC 2616 does not use the `Keep- Alive` header. -- Björn Höhrmann · mailto:bjo...@hoehrmann.de · http://bjoern.hoehrmann.de Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de 25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Re: Fetch: HTTP authentication and CORS
I really don't know which spec is defining how/when we reuse http connections. All I know is that we have a pool of open TCP connections that were used for previous http requests. We don't use that pool when making credential-less CORS requests. We instead use a separate pool, specifically for credential-less CORS requests. Sorry I can't be more precise. I'm happy to point people to the relevant code if needed. / Jonas On Sat, May 4, 2013 at 3:58 PM, Bjoern Hoehrmann derhoe...@gmx.net wrote: * Jonas Sicking wrote: On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote: On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote: We also don't reuse keep-alive http connections. Are we talking about persistent connections as per http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete HTTP/1.0 feature? In the sense of the keep-alive header. I'm not sure, but I think it was defined in HTTP 1.1. It's extremely unlikely that the `Keep-Alive` header is special here. It rather seems to me you meant We also don't reuse http connections. A HTTP connection has to be persistent, has to be kept alive, in order for it to be re-used, and how or why a connection is kept alive does, most probably, not affect whether Firefox will re-use it in your sense above. And no, HTTP/1.1 as defined in RFC 2616 does not use the `Keep- Alive` header. -- Björn Höhrmann · mailto:bjo...@hoehrmann.de · http://bjoern.hoehrmann.de Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de 25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Re: Fetch: HTTP authentication and CORS
In the Gecko implementation they aren't. Assuming that you mean when with credentials is set to false? We also don't reuse keep-alive http connections. / Jonas On May 3, 2013 10:34 AM, Adam Barth w...@adambarth.com wrote: How does withCredentials interact with TLS client certificates? Ideally they wouldn't be used either. Adam On Friday, May 3, 2013, Anne van Kesteren wrote: I had a discussion with Hallvord on IRC about the exact semantics we want for HTTP authentication in the context of CORS (and in particular for XMLHttpRequest, though it would also affect e.g. img crossorigin). Username/password can be passed via open() or the URL. In that case we first check if the server challenges us (do a request without Authorization that results in a response with status 401). For CORS, we'd return to the caller right there. If the Authorization header is set via setRequestHeader() we'd treat it as any other header. We assume the developer already checked if he was challenged or not, etc. If an Authorization header was cached for the URL in question (previous visit) we'd never reuse that under CORS. This means that withCredentials effectively means with cookies (and we should have called it that, mea culpa). I'd be great to know if there's consensus on this. General not caring works too. Context: http://krijnhoetmer.nl/irc-logs/whatwg/20130503#l-318 and onwards. -- http://annevankesteren.nl/