Bug 132523

Summary: http/tests/security/xss-DENIED-xsl-document-redirect.xml fails with NetworkProcess
Product: WebKit Reporter: Myles C. Maxfield <mmaxfield>
Component: New BugsAssignee: Myles C. Maxfield <mmaxfield>
Status: RESOLVED FIXED    
Severity: Normal CC: andersca, ap, beidson, commit-queue, dino, japhet, jonlee, mitz, sam, simon.fraser, thorton
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 132714    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Patch
none
Not for review
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch ap: review+

Description Myles C. Maxfield 2014-05-03 04:23:27 PDT
[WK2] NetworkProcess doesn't set response URL on error
Comment 1 Myles C. Maxfield 2014-05-03 04:27:06 PDT
Created attachment 230751 [details]
Patch
Comment 2 Brady Eidson 2014-05-03 11:41:36 PDT
Comment on attachment 230751 [details]
Patch

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

r- because the ambiguity in the code change concerns me

> Source/WebKit2/ChangeLog:4
> +        [WK2] NetworkProcess doesn't set response URL on error
> +        https://bugs.webkit.org/show_bug.cgi?id=132523

Would like a more accurate  ChangeLog message here, as this is specifically about synchronous XHRs

> Source/WebKit2/NetworkProcess/SynchronousNetworkLoaderClient.cpp:105
> +    if (m_response.isNull() && m_response.url().isNull())
> +        m_response.setURL(m_originalRequest.url());

The bug title suggests that response urls are never set for these loads, yet this code suggests that they are sometimes set...?

In which cases is it already set?

> LayoutTests/ChangeLog:8
> +        Un-marking test as fail

I find it kind of hard to parse this.

"Re-enable test that now passes"?
Comment 3 Myles C. Maxfield 2014-05-03 13:49:24 PDT
Comment on attachment 230751 [details]
Patch

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

>> Source/WebKit2/ChangeLog:4
>> +        https://bugs.webkit.org/show_bug.cgi?id=132523
> 
> Would like a more accurate  ChangeLog message here, as this is specifically about synchronous XHRs

Done.

>> Source/WebKit2/NetworkProcess/SynchronousNetworkLoaderClient.cpp:105
>> +        m_response.setURL(m_originalRequest.url());
> 
> The bug title suggests that response urls are never set for these loads, yet this code suggests that they are sometimes set...?
> 
> In which cases is it already set?

Originally I did this to be conservative. However, I can't find a place where this gets set at all.

Done.

>> LayoutTests/ChangeLog:8
>> +        Un-marking test as fail
> 
> I find it kind of hard to parse this.
> 
> "Re-enable test that now passes"?

Done.
Comment 4 Myles C. Maxfield 2014-05-03 13:53:40 PDT
Created attachment 230763 [details]
Patch
Comment 5 Alexey Proskuryakov 2014-05-03 14:27:32 PDT
Comment on attachment 230763 [details]
Patch

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

Thank you for tackling this, very nice!

I think that this approach is OK, although not the right long-term fix.

> Source/WebKit2/ChangeLog:9
> +        On network failure, WK1 sets the response URL to the original request
> +        URL (at the end of ResourceHandle::platformLoadResourceSynchronously).

This code has a FIXME, which I think makes sense. Manufacturing a response when there is no response is bad, we should fix the code that needs it.

        // FIXME: We might not ever need to manufacture a response: This might all be dead code.
        // When exploring removal of this code, we should substitute appropriate ASSERTs.

I'd add a FIXME in NetworkProcess code too, and amend the one in platformLoadResourceSynchronously() saying that at least this test verifies that we still need the URL.

> Source/WebKit2/NetworkProcess/SynchronousNetworkLoaderClient.cpp:104
> +    m_response.setURL(m_originalRequest.url());

m_response can be non-null if the failure occurred after didReceiveResponse. But ResourceHandle code overwrites the response too.

It seems wrong to use the original URL and not the latest one. It's not really clear what the response should contain, which is why I think that we shouldn't rely on it when loading fails.
Comment 6 Myles C. Maxfield 2014-05-06 14:12:59 PDT
I agree with you, ap. Marking as r-.
Comment 7 Myles C. Maxfield 2014-05-06 14:36:38 PDT
The problematic code is in docLoaderFunc() in XSLTProcessorLibxslt.cpp
Comment 8 Myles C. Maxfield 2014-05-06 17:39:36 PDT
Created attachment 230960 [details]
Not for review
Comment 9 Myles C. Maxfield 2014-05-06 17:40:23 PDT
This latest patch is not quite right. Rebaselining the expected result for xss-DENIED-xsl-document-redirect.html should not have to be done.
Comment 10 Alexey Proskuryakov 2014-05-07 09:53:00 PDT
Removing [WK2] from the title, as the code change is now expected to touch non-WebKit2 files.
Comment 11 Myles C. Maxfield 2014-05-07 18:59:34 PDT
Created attachment 231036 [details]
Patch
Comment 12 Alexey Proskuryakov 2014-05-08 09:23:23 PDT
Comment on attachment 231036 [details]
Patch

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

Nice!

> Source/WebCore/xml/XSLTProcessorLibxslt.cpp:132
> -            requestAllowed = globalCachedResourceLoader->document()->securityOrigin()->canRequest(response.url());
> +            if (error.isNull())
> +                requestAllowed = globalCachedResourceLoader->document()->securityOrigin()->canRequest(response.url());

I think that this introduces an incorrect behavior in the following scenario:
1. A cross-origin redirect occurs.
2. The resource starts to load, and then connection is dropped. If this happens at an appropriate time, the data could still be a well-formed XML document.

As error is not null, we don't do the canRequest check, and proceed using the data.

The function is structured strangely, so I'm not sure if we can do good error handling here (and we don't report more common errors anyway already). Please add "else data.clear();", and post a patch for EWS to run tests with that.
Comment 13 Myles C. Maxfield 2014-05-08 13:01:54 PDT
Created attachment 231093 [details]
Patch
Comment 14 Myles C. Maxfield 2014-05-08 15:04:21 PDT
http://trac.webkit.org/changeset/168498
Comment 15 WebKit Commit Bot 2014-05-08 16:34:00 PDT
Re-opened since this is blocked by bug 132714
Comment 16 Alexey Proskuryakov 2014-05-08 17:04:04 PDT
What was the breakage?
Comment 17 Myles C. Maxfield 2014-05-09 22:52:33 PDT
Created attachment 231217 [details]
Patch
Comment 18 Myles C. Maxfield 2014-05-10 01:28:05 PDT
Mavericks WK2 had the unmodified test output. This latest patch marks it as such.
Comment 19 Alexey Proskuryakov 2014-05-10 10:40:01 PDT
I'm still a bit confused. The new results that you add appear to be correct, and cross-platform results in fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt are incorrect.

Shouldn't we have correct results in the cross-platform file, and let platforms that fail land custom results? Spraying the same correct results over many port directories is inconvenient.
Comment 20 Myles C. Maxfield 2014-05-12 20:21:13 PDT
Created attachment 231355 [details]
Patch
Comment 21 Alexey Proskuryakov 2014-05-12 22:25:07 PDT
Comment on attachment 231355 [details]
Patch

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

> Source/WebCore/ChangeLog:10
> +        synchronous XHR. In addition, this test removes one place that is
> +        sensitive to such a manufactured response.

Is it still one place?

> Source/WebCore/loader/DocumentThreadableLoader.cpp:426
> -    if (requestURL != response.url() && !isAllowedRedirect(response.url())) {
> +    if (error.isNull() && requestURL != response.url() && !isAllowedRedirect(response.url())) {
>          m_client->didFailRedirectCheck();
>          return;
>      }

This change is new in this version of the patch. I agree that this place looks like it needs to be fixed too, but the fix looks very confusing.

Above, there is a comment about how "if we have an HTTP response, then it wasn't a network error in fact." Doesn't it become obsolete with your changes? Even considering that we have the quirk for local files, perhaps something like this would be less confusing?

if (!error.isNull() {
    if (requestURL.isLocalFile()) {
        // We don't want XMLHttpRequest to raise an exception for file:// resources, see <rdar://problem/4962298>.
        // FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp.
        didReceiveResponse(identifier, ResourceResponse());
        didFinishLoading(identifier, 0.0);
        return;
    }
    m_client->didFail(error);
    return;
    }
}

// FIXME: FrameLoader::loadSynchronously() does not tell us whether a redirect happened or not, so <...>
if (requestURL != response.url() && !isAllowedRedirect(response.url())) {
    m_client->didFailRedirectCheck();
    return;
}

... normal success case
Comment 22 Alexey Proskuryakov 2014-05-12 22:31:34 PDT
Not sure where our check for http:// resources not being allowed to redirect to file:// is, my proposed snippet might change the behavior in this case.
Comment 23 Myles C. Maxfield 2014-05-16 14:47:21 PDT
(In reply to comment #22)
> Not sure where our check for http:// resources not being allowed to redirect to file:// is, my proposed snippet might change the behavior in this case.

Looks like it is done in SecurityOrigin::canRequest() which is called from isAllowedRedirect()
Comment 24 Myles C. Maxfield 2014-05-16 15:50:57 PDT
Created attachment 231599 [details]
Patch
Comment 25 Alexey Proskuryakov 2014-05-16 19:38:29 PDT
Comment on attachment 231599 [details]
Patch

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

r=me assuming there is a good response to the question below. Otherwise, please remove the httpStatusCode check.

> Source/WebCore/loader/DocumentThreadableLoader.cpp:413
> +    // If we have an HTTP response, then it wasn't a network error (even if !error.isNull()).

Why? I don't see how this can happen.
Comment 26 Myles C. Maxfield 2014-05-22 20:42:06 PDT
Comment on attachment 231599 [details]
Patch

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

>> Source/WebCore/loader/DocumentThreadableLoader.cpp:413
>> +    // If we have an HTTP response, then it wasn't a network error (even if !error.isNull()).
> 
> Why? I don't see how this can happen.

Turns out you added it yourself in https://bugs.webkit.org/show_bug.cgi?id=14704
Comment 27 Myles C. Maxfield 2014-05-22 20:56:27 PDT
Comment on attachment 231599 [details]
Patch

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

>>> Source/WebCore/loader/DocumentThreadableLoader.cpp:413
>>> +    // If we have an HTTP response, then it wasn't a network error (even if !error.isNull()).
>> 
>> Why? I don't see how this can happen.
> 
> Turns out you added it yourself in https://bugs.webkit.org/show_bug.cgi?id=14704

http/tests/appcache/fallback.html relies on it.
Comment 28 Myles C. Maxfield 2014-05-22 20:59:59 PDT
http://trac.webkit.org/changeset/169243
Comment 29 Alexey Proskuryakov 2014-05-22 21:04:52 PDT
> Turns out you added it yourself in https://bugs.webkit.org/show_bug.cgi?id=14704

Yes, but doesn't this change make it impossible? I thought that it did.

> http/tests/appcache/fallback.html relies on it.

Even after this change? I'm curious about the mechanism of this dependence.
Comment 30 Myles C. Maxfield 2014-05-23 13:32:54 PDT
(In reply to comment #29)
> > Turns out you added it yourself in https://bugs.webkit.org/show_bug.cgi?id=14704
> 
> Yes, but doesn't this change make it impossible? I thought that it did.
> 
> > http/tests/appcache/fallback.html relies on it.
> 
> Even after this change? I'm curious about the mechanism of this dependence.

Yes, even after this change. Appcache seems to have it's own logic about what to return.

I started reading the test but couldn't immediately find the cause (and I had other work to do), so I left it at that. At some point I'd like to remove this check.