Bug 88139 - The value in Access-Control-Allow-Origin is not being matched correctly for CORS-enabled requests
Summary: The value in Access-Control-Allow-Origin is not being matched correctly for C...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL: http://w3c-test.org/webappsec/tests/c...
Keywords: InRadar, WebExposed
: 88628 (view as bug list)
Depends on:
Blocks: 88896
  Show dependency treegraph
 
Reported: 2012-06-01 14:59 PDT by Pablo Flouret
Modified: 2012-06-26 14:37 PDT (History)
11 users (show)

See Also:


Attachments
Patch (21.65 KB, patch)
2012-06-04 14:58 PDT, Pablo Flouret
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ec2-cr-linux-04 (678.81 KB, application/zip)
2012-06-05 03:35 PDT, WebKit Review Bot
no flags Details
Patch (22.03 KB, patch)
2012-06-08 14:44 PDT, Pablo Flouret
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pablo Flouret 2012-06-01 14:59:35 PDT
Step 3 of the resource sharing check algorithm in http://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#resource-sharing-check says:
[[
3. If the value of Access-Control-Allow-Origin is not a case-sensitive match for the value of the Origin header as defined by its specification, return fail and terminate this algorithm.
]]

Right now the value in Access-Control-Allow-Origin is compared via SecurityOrigin::isSameSchemeHostPort(), so the url is parsed and (i presume) normalized.
Comment 1 Pablo Flouret 2012-06-01 15:00:23 PDT
Adam,

I can make a patch, but do you think it would break a lot of things in the wild?
Comment 2 Adam Barth 2012-06-02 23:22:26 PDT
I suspect ap has an opinion here.  My understanding is that Firefox follows the spec, so I think we should give following the spec a try.  This is a security check, so we don't want to be sloppy.
Comment 3 Alexey Proskuryakov 2012-06-02 23:30:52 PDT
Yup.
Comment 4 Odin Hørthe Omdal (odinho, Opera) 2012-06-04 12:45:44 PDT
The testcase there is pointing to a wrong domain (www.w3c-test.org), it should be no-www. The server should probably be configured in a bit more restrictive way so that it's easier to rely on the domain.

Anyway, there's an updated test, that doesn't test for the exception code (which is not that interesting):

http://w3c-test.org/webappsec/tests/cors/submitted/opera/staging/origin.htm

That URI will also change at one point if it moves to approved.
Comment 5 Pablo Flouret 2012-06-04 14:58:30 PDT
Created attachment 145633 [details]
Patch
Comment 6 Adam Barth 2012-06-04 15:05:30 PDT
This patch LGTM.  Let's give folks a chance to comment before landing.
Comment 7 Adam Barth 2012-06-04 15:06:27 PDT
@peter: I wanted to add the WebVisible keyword to this patch, but it doesn't seem to exist yet.
Comment 8 jochen 2012-06-04 15:11:43 PDT
Comment on attachment 145633 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review

> Source/WebCore/loader/CrossOriginAccessControl.cpp:152
> +    if (accessControlOriginString != securityOrigin->toString()) {

should we check for !securityOrigin->isUnique() or would that be overkill?
Comment 9 Pablo Flouret 2012-06-04 15:12:54 PDT
(In reply to comment #8)
> (From update of attachment 145633 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review
> 
> > Source/WebCore/loader/CrossOriginAccessControl.cpp:152
> > +    if (accessControlOriginString != securityOrigin->toString()) {
> 
> should we check for !securityOrigin->isUnique() or would that be overkill?

That check is already a few lines above the change.
Comment 10 jochen 2012-06-04 15:14:40 PDT
(In reply to comment #9)
> (In reply to comment #8)
> > (From update of attachment 145633 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review
> > 
> > > Source/WebCore/loader/CrossOriginAccessControl.cpp:152
> > > +    if (accessControlOriginString != securityOrigin->toString()) {
> > 
> > should we check for !securityOrigin->isUnique() or would that be overkill?
> 
> That check is already a few lines above the change.

ok, patch looks good then
Comment 11 Alexey Proskuryakov 2012-06-04 15:15:35 PDT
Comment on attachment 145633 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review

> Source/WebCore/loader/CrossOriginAccessControl.cpp:152
>      // FIXME: Access-Control-Allow-Origin can contain a list of origins.
> -    RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
> -    if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin)) {
> +    if (accessControlOriginString != securityOrigin->toString()) {

I guess one way this could actually cause a compatibility regression is when Access-Control-Allow-Origin has a list of origins, which we used to mis-parse as a single one. In that case, scheme host and port could reasonably matched securityOrigin for the first item. So maybe we should address the FIXME now or very soon.

Is this relying on both accessControlOriginString and securityOrigin->toString() being lowercase? I cannot immediately see why they are.

> LayoutTests/http/tests/xmlhttprequest/resources/basic-auth/access-control-auth-basic.php:3
> -header("Access-Control-Allow-Origin: http://127.0.0.1:8000/");
> +header("Access-Control-Allow-Origin: http://127.0.0.1:8000");

Hmm. So all tests using this script used to fail in Firefox?
Comment 12 Pablo Flouret 2012-06-04 15:28:53 PDT
(In reply to comment #11)
> (From update of attachment 145633 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review
> 
> > Source/WebCore/loader/CrossOriginAccessControl.cpp:152
> >      // FIXME: Access-Control-Allow-Origin can contain a list of origins.
> > -    RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
> > -    if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin)) {
> > +    if (accessControlOriginString != securityOrigin->toString()) {
> 
> I guess one way this could actually cause a compatibility regression is when Access-Control-Allow-Origin has a list of origins, which we used to mis-parse as a single one. In that case, scheme host and port could reasonably matched securityOrigin for the first item. So maybe we should address the FIXME now or very soon.
> 

Does SecurityOrigin::createFromString() create a valid origin for the first url if accessControlOriginString is a list? I assumed the FIXME meant that having a list of origins would just not work at all. I'll look into it.

> Is this relying on both accessControlOriginString and securityOrigin->toString() being lowercase? I cannot immediately see why they are.
>

The url used for the security origin is lowercased when the SecurityOrigin is created. And then the comparison is case-sensitive with the value of Access-Control-Allow-Origin. The test covers this, but i didn't realize the test is run from 127.0.0.1, hmm. Any suggestions?

> > LayoutTests/http/tests/xmlhttprequest/resources/basic-auth/access-control-auth-basic.php:3
> > -header("Access-Control-Allow-Origin: http://127.0.0.1:8000/");
> > +header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
> 
> Hmm. So all tests using this script used to fail in Firefox?

Yes, it seems like it.
Comment 13 Alexey Proskuryakov 2012-06-04 15:41:07 PDT
> The url used for the security origin is lowercased when the SecurityOrigin is created. And then the comparison is case-sensitive with the value of Access-Control-Allow-Origin. The test covers this, but i didn't realize the test is run from 127.0.0.1, hmm. Any suggestions?

I misread "case sensitive" in bug description. Anyway, not sure how exactly to test, but perhaps localhost vs. LOCALHOST can be used?

>> Hmm. So all tests using this script used to fail in Firefox?
> Yes, it seems like it.

Can you test to confirm?
Comment 14 Pablo Flouret 2012-06-04 16:44:11 PDT
(In reply to comment #13)
> >> Hmm. So all tests using this script used to fail in Firefox?
> > Yes, it seems like it.
> 
> Can you test to confirm?

Sorry, i misread the results when i tested it before. The tests that use the script fail outright in Firefox, see https://bugs.webkit.org/show_bug.cgi?id=37781#c9

But Firefox passes all of the tests in the w3c testcase, so theoretically the trailing slash would matter in the tests that use the script.
Comment 15 Pablo Flouret 2012-06-04 17:46:58 PDT
(In reply to comment #11)
> (From update of attachment 145633 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=145633&action=review
> 
> > Source/WebCore/loader/CrossOriginAccessControl.cpp:152
> >      // FIXME: Access-Control-Allow-Origin can contain a list of origins.
> > -    RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
> > -    if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin)) {
> > +    if (accessControlOriginString != securityOrigin->toString()) {
> 
> I guess one way this could actually cause a compatibility regression is when Access-Control-Allow-Origin has a list of origins, which we used to mis-parse as a single one. In that case, scheme host and port could reasonably matched securityOrigin for the first item. So maybe we should address the FIXME now or very soon.

This indeed happens, but i can't think of any examples of a list of urls that is interpreted as a single url and should still work with the spec as it stands now.

The only one example i can think of that comes close would be something like "http://localhost:8000/ http://example.org". But even if we parsed the list correctly, the trailing slash would be there and it wouldn't match.

Can you think of a problematic example?
Comment 16 Adam Barth 2012-06-04 17:51:00 PDT
I don't think the list case is a problem for us yet because we never send a list in the Origin header to start with.  The FIXME is correct, but it's not something we need to worry about for this patch.
Comment 17 WebKit Review Bot 2012-06-05 03:35:36 PDT
Comment on attachment 145633 [details]
Patch

Attachment 145633 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/12900457

New failing tests:
http/tests/xmlhttprequest/origin-exact-matching.html
Comment 18 WebKit Review Bot 2012-06-05 03:35:40 PDT
Created attachment 145746 [details]
Archive of layout-test-results from ec2-cr-linux-04

The attached test failures were seen while running run-webkit-tests on the chromium-ews.
Bot: ec2-cr-linux-04  Port: <class 'webkitpy.common.config.ports.ChromiumXVFBPort'>  Platform: Linux-2.6.35-28-virtual-x86_64-with-Ubuntu-10.10-maverick
Comment 19 Pablo Flouret 2012-06-05 15:51:09 PDT
(In reply to comment #17)
> (From update of attachment 145633 [details])
> Attachment 145633 [details] did not pass chromium-ews (chromium-xvfb):
> Output: http://queues.webkit.org/results/12900457
> 
> New failing tests:
> http/tests/xmlhttprequest/origin-exact-matching.html

The cases that fail are the origins that end with a null character. It doesn't fail for me on chromium-mac, though, not sure what's going on there.
Comment 20 Anne van Kesteren 2012-06-08 00:10:51 PDT
*** Bug 88628 has been marked as a duplicate of this bug. ***
Comment 21 Adam Barth 2012-06-08 11:05:58 PDT
Comment on attachment 145633 [details]
Patch

One thing we can do is to land this patch without the null character tests and file a bug about the null character issue.
Comment 22 Pablo Flouret 2012-06-08 14:12:03 PDT
(In reply to comment #21)
> (From update of attachment 145633 [details])
> One thing we can do is to land this patch without the null character tests and file a bug about the null character issue.

Sounds good.
Comment 23 Pablo Flouret 2012-06-08 14:44:47 PDT
Created attachment 146653 [details]
Patch
Comment 24 Pablo Flouret 2012-06-08 14:50:23 PDT
(In reply to comment #23)
> Created an attachment (id=146653) [details]
> Patch

Removed the trailing null character tests (and filed bug 88688). Also reworked the test a bit to test case differences properly.
Comment 25 Adam Barth 2012-06-09 11:34:54 PDT
Comment on attachment 146653 [details]
Patch

Alright.  Let's give this a shot.
Comment 26 WebKit Review Bot 2012-06-09 11:42:59 PDT
Comment on attachment 146653 [details]
Patch

Clearing flags on attachment: 146653

Committed r119911: <http://trac.webkit.org/changeset/119911>
Comment 27 WebKit Review Bot 2012-06-09 11:43:05 PDT
All reviewed patches have been landed.  Closing bug.
Comment 28 Chris Dumez 2012-06-12 02:46:03 PDT
Comment on attachment 146653 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=146653&action=review

> LayoutTests/http/tests/xmlhttprequest/resources/origin-exact-matching-iframe.html:9
> +var urlTemplate = "http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?access-control-allow-origin=";

You're not passing any "url" argument to redirect-cors.php. What is the expected behavior in that case? On GTK and EFL ports (both using libsoup), we end up with "Too many redirects" errors because it keep redirecting the same URL (http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?access-control-allow-origin=...). Shouldn't we pass some URL to avoid this?
Comment 29 Pablo Flouret 2012-06-12 10:39:43 PDT
(In reply to comment #28)
> (From update of attachment 146653 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=146653&action=review
> 
> > LayoutTests/http/tests/xmlhttprequest/resources/origin-exact-matching-iframe.html:9
> > +var urlTemplate = "http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?access-control-allow-origin=";
> 
> You're not passing any "url" argument to redirect-cors.php. What is the expected behavior in that case? On GTK and EFL ports (both using libsoup), we end up with "Too many redirects" errors because it keep redirecting the same URL (http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?access-control-allow-origin=...). Shouldn't we pass some URL to avoid this?

Hmm, i thought that without a $url or $redirect_preflight it wouldn't actually do the redirect. I'll fix the test.
Comment 30 David Kilzer (:ddkilzer) 2012-06-26 14:37:32 PDT
<rdar://problem/11679305>