Closed
Bug 1195167
Opened 9 years ago
Closed 9 years ago
Use channel->asyncOpen2 in FetchDriver.cpp
Categories
(Core :: DOM: Security, defect)
Core
DOM: Security
Tracking
()
RESOLVED
FIXED
mozilla44
Tracking | Status | |
---|---|---|
firefox44 | --- | fixed |
People
(Reporter: ckerschb, Assigned: sicking)
References
()
Details
Attachments
(6 files, 2 obsolete files)
15.70 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
6.32 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
1.94 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
5.82 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
6.69 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
31.37 KB,
patch
|
bkelly
:
review+
|
Details | Diff | Splinter Review |
No description provided.
Comment 1•9 years ago
|
||
Please note that I've found a problem with FetchDriver's current use of nsCORSListenerProxy in bug 1184607. Mainly, it should not use nsCORSListenerProxy if mRequest.Mode() != RequestMode::Cors. This is because the proxy overwrites the CorsMode flag which prevents us from correctly doing fetch(url, {mode: 'same-origin'}).
If we end up setting REQUIRE_SAME_ORIGIN_* in the security flags in mRequest.Mode() is RequestMode::Same_origin, then it may be ok to still use the proxy.
Can you flag me for feedback on the patch when you have it ready?
Reporter | ||
Comment 2•9 years ago
|
||
(In reply to Ben Kelly [:bkelly] from comment #1)
> Please note that I've found a problem with FetchDriver's current use of
> nsCORSListenerProxy in bug 1184607. Mainly, it should not use
> nsCORSListenerProxy if mRequest.Mode() != RequestMode::Cors. This is
> because the proxy overwrites the CorsMode flag which prevents us from
> correctly doing fetch(url, {mode: 'same-origin'}).
>
> If we end up setting REQUIRE_SAME_ORIGIN_* in the security flags in
> mRequest.Mode() is RequestMode::Same_origin, then it may be ok to still use
> the proxy.
Thanks for the update.
> Can you flag me for feedback on the patch when you have it ready?
Will do, but might take a few more days.
Assignee | ||
Comment 3•9 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=1f7b6ec7bd4d
Passes the dom/tests/mochitest/fetch mochitests locally, but still needs some work.
Assignee: mozilla → jonas
Summary: Use channel->ascynOpen2 dom/fetch/FetchDriver.cpp → Use channel->asyncOpen2 in FetchDriver.cpp
Assignee | ||
Comment 4•9 years ago
|
||
Assignee | ||
Comment 5•9 years ago
|
||
Attachment #8675197 -
Flags: review?(bkelly)
Assignee | ||
Comment 6•9 years ago
|
||
Attachment #8675198 -
Flags: review?(bkelly)
Assignee | ||
Comment 7•9 years ago
|
||
Attachment #8675199 -
Flags: review?(bkelly)
Assignee | ||
Comment 8•9 years ago
|
||
Attachment #8675200 -
Flags: review?(bkelly)
Assignee | ||
Comment 9•9 years ago
|
||
Attachment #8675201 -
Flags: review?(bkelly)
Assignee | ||
Comment 10•9 years ago
|
||
Attachment #8675202 -
Flags: review?(bkelly)
Assignee | ||
Comment 11•9 years ago
|
||
Ben, Ehsan, feel free to divide up the reviews between you. I wasn't sure who to assign to, so I assigned to Ben since I've chatted more with him about this code lately.
Assignee | ||
Comment 12•9 years ago
|
||
Slightly updated version. Hopefully you haven't started reviewing yet?
Attachment #8675202 -
Attachment is obsolete: true
Attachment #8675202 -
Flags: review?(bkelly)
Assignee | ||
Updated•9 years ago
|
Attachment #8675266 -
Flags: review?(bkelly)
Comment 13•9 years ago
|
||
I'll review this on Monday. I'd like to take it since I've been looking at the tainting stuff recently. Thanks.
Comment 14•9 years ago
|
||
Comment on attachment 8675197 [details] [diff] [review]
Part 1: Let necko handle all protocols
Review of attachment 8675197 [details] [diff] [review]:
-----------------------------------------------------------------
r=me with comments addressed.
It seems all the effected protocols (about:, blob:, and data:) are tested in here:
https://dxr.mozilla.org/mozilla-central/source/dom/tests/mochitest/fetch/test_fetch_basic.js
But a test for about: protocol content-length is missing. Can you add one? It seems there should be no content-length header for about: pages.
Also, it seems that this change is going to enable file:, ftp:, and other schemes. The fetch spec has some weasel words for file: and ftp:
https://fetch.spec.whatwg.org/#concept-basic-fetch
But it says other protocols should fail.
Is it worth blocking these other protocol schemes?
::: dom/fetch/FetchDriver.cpp
@@ +209,5 @@
>
> nsresult
> FetchDriver::BasicFetch()
> {
> + return HttpFetch();
Since all protocols are going through the channel AsyncOpen(), can you please remove the unnecessary dispatch in FetchDriver::Fetch()?
https://dxr.mozilla.org/mozilla-central/source/dom/fetch/FetchDriver.cpp?case=true&from=FetchDriver.cpp#89
And then you can dupe bug 1206079 to here.
Attachment #8675197 -
Flags: review?(bkelly) → review+
Comment 15•9 years ago
|
||
Comment on attachment 8675198 [details] [diff] [review]
part 2: Remove redundant aCORSFlag argument and instead use mCORSFlagEverSet
Review of attachment 8675198 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/fetch/FetchDriver.h
@@ -126,5 @@
> // Utility since not all cases need to do any post processing of the filtered
> // response.
> nsresult FailWithNetworkError();
> nsresult SucceedWithResponse();
> - nsresult DoesNotRequirePreflight(nsIChannel* aChannel);
Removing this seems unrelated to this patch. Is the intention that AsyncOpen2() will handle this logic for us? (Or we should put the call to the this back in the redirect callback.)
Attachment #8675198 -
Flags: review?(bkelly) → review+
Comment 16•9 years ago
|
||
Comment on attachment 8675199 [details] [diff] [review]
part 3: Remove more scheme-specific handling from FetchDriver
Review of attachment 8675199 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/fetch/FetchDriver.cpp
@@ -140,4 @@
>
> - // request's current url's origin is request's origin and the CORS flag is unset
> - // request's current url's scheme is "data" and request's same-origin data-URL flag is set
> - // request's current url's scheme is "about"
Why drop the spec language? Its a helpful landmark when trying to trace through both the spec and our implementation.
Attachment #8675199 -
Flags: review?(bkelly) → review+
Comment 17•9 years ago
|
||
Comment on attachment 8675200 [details] [diff] [review]
part 4: Remove FetchDriver::BasicFetch since it is empty
Review of attachment 8675200 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/fetch/FetchDriver.cpp
@@ +138,5 @@
> if (!mCORSFlagEverSet &&
> (NS_IsAboutBlank(requestURI) ||
> NS_SUCCEEDED(mPrincipal->CheckMayLoad(requestURI, false /* report */,
> true /*allowIfInheritsPrincipal*/)))) {
> + return MainFetchOp(HTTP_FETCH, false /* cors */, false /* preflight */);
Please add a comment here that what the spec calls "basic fetch" is handled within our necko channel code. Therefore everything goes through HTTP Fetch. (Might be less confusing if got rid of the name HTTP_FETCH at some point...)
Also please add the comment at the other BASIC_FETCH you removed in this method.
Attachment #8675200 -
Flags: review?(bkelly) → review+
Assignee | ||
Comment 18•9 years ago
|
||
> It seems all the effected protocols (about:, blob:, and data:) are tested in
> here:
>
>
> https://dxr.mozilla.org/mozilla-central/source/dom/tests/mochitest/fetch/
> test_fetch_basic.js
>
> But a test for about: protocol content-length is missing. Can you add one?
> It seems there should be no content-length header for about: pages.
All about: pages except about:blank should fail, right? Shouldn't about:blank have a Content-Length: 0 header? I think that's what happens now.
> But it says other protocols should fail.
>
> Is it worth blocking these other protocol schemes?
I don't think it's worth blocking other protocols. Generally speaking other protocols that addons are explicitly choosing to expose, which I hope that the fetch spec doesn't forbid. And if it does, addons are essentially proxy for the user, and user overrides spec.
> ::: dom/fetch/FetchDriver.cpp
> @@ +209,5 @@
> >
> > nsresult
> > FetchDriver::BasicFetch()
> > {
> > + return HttpFetch();
>
> Since all protocols are going through the channel AsyncOpen(), can you
> please remove the unnecessary dispatch in FetchDriver::Fetch()?
Parts 4 and 6 clean this up, but they do leave the async thread dispatch. Without that we risk synchronously reenter the caller through mObserver. Is that safe?
Maybe we should discuss in bug 1206079?
Assignee | ||
Comment 19•9 years ago
|
||
> > - nsresult DoesNotRequirePreflight(nsIChannel* aChannel);
>
> Removing this seems unrelated to this patch. Is the intention that
> AsyncOpen2() will handle this logic for us? (Or we should put the call to
> the this back in the redirect callback.)
DoesNotRequirePreflight is never called anywhere. So this was just dead code removal.
Assignee | ||
Comment 20•9 years ago
|
||
(In reply to Ben Kelly [:bkelly] from comment #16)
> Comment on attachment 8675199 [details] [diff] [review]
> part 3: Remove more scheme-specific handling from FetchDriver
>
> Review of attachment 8675199 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: dom/fetch/FetchDriver.cpp
> @@ -140,4 @@
> >
> > - // request's current url's origin is request's origin and the CORS flag is unset
> > - // request's current url's scheme is "data" and request's same-origin data-URL flag is set
> > - // request's current url's scheme is "about"
>
> Why drop the spec language? Its a helpful landmark when trying to trace
> through both the spec and our implementation.
I generally didn't know what to do with a bunch of the spec related comments when the code that they relate to went away. Generally feels like most of the comments belong inside necko rather than in FetchDriver since this is moving us to using Necko's fetch implementation.
Happy to leave whatever comments you want in whatever place you want though. I'll put this one back for now.
Comment 21•9 years ago
|
||
Comment on attachment 8675201 [details] [diff] [review]
part 5: Make FetchDriver use AsyncOpen2
Review of attachment 8675201 [details] [diff] [review]:
-----------------------------------------------------------------
Overall this looks good, but I think credentials handling is not right for no-cors requests.
Note, I have some unlanded tests in another bug that could be adapted to check this condition.
::: dom/fetch/FetchDriver.cpp
@@ +208,5 @@
> // new cookies sent by the server from being stored. This value will
> // propagate across redirects, which is what we want.
> + const nsLoadFlags credentialsFlag =
> + mRequest->GetCredentialsMode() == RequestCredentials::Omit ?
> + nsIRequest::LOAD_ANONYMOUS : 0;
I think this breaks the "no-cors" mode with "same-origin" credentials case. If the initial URL is cross-origin we need to set LOAD_ANONYMOUS for that case here.
@@ -791,5 @@
>
> // HTTP Fetch Step 9, "redirect status". We only unset this for spec
> // compatibility. Any actions we take on mRequest here do not affect what the
> //channel does.
> - mRequest->UnsetSameOriginDataURL();
Can you amend the comment to indicate where this is handled now?
@@ +810,5 @@
>
> + if (RequirePreflight()) {
> + // We can't handle redirects that require preflight yet.
> + // This is especially true for no-cors requests, which much always be
> + // blocked if they require preflight.
This comment is a bit confusing. Preflights are a CORS thing and don't apply to no-cors. You should be able to assert that mode == "cors" here. It should not be possible to generate a no-cors request with a non-simple method or unsafe header.
I'm ok just returning failure here, though. I'd just like to adjust the comment.
@@ +826,2 @@
> if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
> + mRequest->Mode() == RequestMode::No_cors) {
The makes us set LOAD_ANONYMOUS on a same-origin redirect for no-cors requests. I don't think thats what we want. It should only set the LOAD_ANONYMOUS on cross-origin redirect. I think we lack a test case for no-cors redirects like this.
Attachment #8675201 -
Flags: review?(bkelly) → review-
Comment 22•9 years ago
|
||
Comment on attachment 8675266 [details] [diff] [review]
part 6: Some code simplification since necko handles fetch recursion
Review of attachment 8675266 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/fetch/FetchDriver.cpp
@@ +82,4 @@
>
> + nsCOMPtr<nsIRunnable> r =
> + NS_NewRunnableMethod(this, &FetchDriver::ContinueFetch);
> + return NS_DispatchToCurrentThread(r);
Please just call ContinueFetch() or move the code from ContinueFetch() into here. I don't think we need this async dispatch any more. See my comment from P1.
@@ +673,4 @@
> // We proceed as usual here, since we've already created a successful response
> // from OnStartRequest.
> + }
> + else {
nit: style for else on same line as preceding bracket
Attachment #8675266 -
Flags: review?(bkelly) → review+
Assignee | ||
Comment 23•9 years ago
|
||
> Is it worth blocking these other protocol schemes?
I do think that we do have a few more protocols that we do actually expose to content right now. Primarily a few of our about: pages are loadable by content I think. But I don't think they are more important to block in the fetch() API than in <img>, <iframe> or XMLHttpRequest. So lets work on them separately, and remove them from being content exposed in general instead.
Comment 24•9 years ago
|
||
(In reply to Jonas Sicking (:sicking) from comment #18)
> All about: pages except about:blank should fail, right? Shouldn't
> about:blank have a Content-Length: 0 header? I think that's what happens now.
Maybe its a spec bug, but Basic Fetch currently says this for about:blank:
"return a response whose header list consist of a single header whose name is `Content-Type`"
> Parts 4 and 6 clean this up, but they do leave the async thread dispatch.
> Without that we risk synchronously reenter the caller through mObserver. Is
> that safe?
>
> Maybe we should discuss in bug 1206079?
Hmm, I wasn't aware of the issue with mObserver. We can handle later in bug 1206079.
Assignee | ||
Comment 25•9 years ago
|
||
> > + return MainFetchOp(HTTP_FETCH, false /* cors */, false /* preflight */);
>
> Please add a comment here that what the spec calls "basic fetch" is handled
> within our necko channel code. Therefore everything goes through HTTP
> Fetch. (Might be less confusing if got rid of the name HTTP_FETCH at some
> point...)
>
> Also please add the comment at the other BASIC_FETCH you removed in this
> method.
I'll do this in Part 5 since this function is dramatically rewritten there.
Assignee | ||
Comment 26•9 years ago
|
||
(In reply to Ben Kelly [:bkelly] from comment #21)
> ::: dom/fetch/FetchDriver.cpp
> @@ +208,5 @@
> > // new cookies sent by the server from being stored. This value will
> > // propagate across redirects, which is what we want.
> > + const nsLoadFlags credentialsFlag =
> > + mRequest->GetCredentialsMode() == RequestCredentials::Omit ?
> > + nsIRequest::LOAD_ANONYMOUS : 0;
>
> I think this breaks the "no-cors" mode with "same-origin" credentials case.
> If the initial URL is cross-origin we need to set LOAD_ANONYMOUS for that
> case here.
Great catch!!
> @@ +810,5 @@
> >
> > + if (RequirePreflight()) {
> > + // We can't handle redirects that require preflight yet.
> > + // This is especially true for no-cors requests, which much always be
> > + // blocked if they require preflight.
>
> This comment is a bit confusing. Preflights are a CORS thing and don't
> apply to no-cors. You should be able to assert that mode == "cors" here.
> It should not be possible to generate a no-cors request with a non-simple
> method or unsafe header.
>
> I'm ok just returning failure here, though. I'd just like to adjust the
> comment.
Ooh, this is also a really great catch. The code is actually wrong here since RequirePreflight only returns 'true' for mode==cors. But we need to block no-cors requests that are unsafe.
I guess maybe we don't *have* to if code elsewhere ensures that no-cors requests can't use unsafe methods or headers. But it seems like a good idea to enforce that here too.
> @@ +826,2 @@
> > if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
> > + mRequest->Mode() == RequestMode::No_cors) {
>
> The makes us set LOAD_ANONYMOUS on a same-origin redirect for no-cors
> requests. I don't think thats what we want. It should only set the
> LOAD_ANONYMOUS on cross-origin redirect. I think we lack a test case for
> no-cors redirects like this.
Yup. I forgot to add a check for mHasBeenCrossSite.
Assignee | ||
Comment 27•9 years ago
|
||
Attachment #8675201 -
Attachment is obsolete: true
Attachment #8675882 -
Flags: review?(bkelly)
Comment 28•9 years ago
|
||
Comment on attachment 8675882 [details] [diff] [review]
part 5: Make FetchDriver use AsyncOpen2
Review of attachment 8675882 [details] [diff] [review]:
-----------------------------------------------------------------
Thanks!
::: dom/fetch/FetchDriver.cpp
@@ +163,2 @@
> }
> +
nit: trailing whitespace
@@ +226,5 @@
> + const nsLoadFlags credentialsFlag =
> + (mRequest->GetCredentialsMode() == RequestCredentials::Omit ||
> + (mHasBeenCrossSite &&
> + mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
> + mRequest->Mode() == RequestMode::No_cors)) ?
I think checking for opaque tainting:
mRequest->GetResponseTainting() !=InternalRequest::RESPONSETAINT_OPAQUE)
is simpler than the multi-variable:
(mHasBeenCrossSite && mRequest->Mode() == RequestMode::No_cors)
But I guess they should be equivalent.
I think it might be nice to one day remove mHasBeenCrossSite, though. It seems its information is fully subsumed within the tainting value.
@@ +442,5 @@
> +bool
> +FetchDriver::IsUnsafeRequest()
> +{
> + return mHasBeenCrossSite &&
> + (mRequest->Mode() == RequestMode::Cors_with_forced_preflight ||
I thought we removed Cors_with_forced_preflight. Maybe those patches haven't landed yet.
@@ +840,5 @@
>
> + // Possibly set the LOAD_ANONYMOUS flag on the channel.
> + if (mHasBeenCrossSite &&
> + mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
> + mRequest->Mode() == RequestMode::No_cors) {
Please write a follow-up bug to write tests for no-cors fetch() with credentials set to same-origin.
Attachment #8675882 -
Flags: review?(bkelly) → review+
Assignee | ||
Comment 29•9 years ago
|
||
Assignee | ||
Comment 30•9 years ago
|
||
> I think checking for opaque tainting:
>
> mRequest->GetResponseTainting() !=InternalRequest::RESPONSETAINT_OPAQUE)
>
> is simpler than the multi-variable:
>
> (mHasBeenCrossSite && mRequest->Mode() == RequestMode::No_cors)
>
> But I guess they should be equivalent.
I prefer the former since I think that more directly maps to the reason why we're setting the flag. I.e. we're removing cookies because cookies has been requested for same-site only, and this request is going cross origin, and the CORS code isn't clearing the cookies.
To me that was more direct than understanding that that happened to coincide with the request getting opaque tainted.
I agree that it's more code, but since it's security related I favored clarity over anything else.
Hope that's ok?
> I think it might be nice to one day remove mHasBeenCrossSite, though. It
> seems its information is fully subsumed within the tainting value.
Definitely. I have a plan, but I'd like to understand your plan with regards to tainting before I start writing patches.
> @@ +442,5 @@
> > +bool
> > +FetchDriver::IsUnsafeRequest()
> > +{
> > + return mHasBeenCrossSite &&
> > + (mRequest->Mode() == RequestMode::Cors_with_forced_preflight ||
>
> I thought we removed Cors_with_forced_preflight. Maybe those patches
> haven't landed yet.
Bug 1215746. The patch there sits on top of these patches, so I'll land them together.
Assignee | ||
Comment 31•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/ede755bf408567d1ff919e5e5c9fc20e7bff7a73
Bug 1195167 part 1: Let necko handle all protocols. r=bkelly
https://hg.mozilla.org/integration/mozilla-inbound/rev/d0e57a128d0d6953a426d7938089314c4d95927d
Bug 1195167 part 2: Remove redundant aCORSFlag argument and instead use mCORSFlagEverSet. r=bkelly
https://hg.mozilla.org/integration/mozilla-inbound/rev/17c8f6d7d1d2cd7d851de8c983917be02fddebbb
Bug 1195167 part 3: Remove more scheme-specific handling from FetchDriver. r=bkelly
https://hg.mozilla.org/integration/mozilla-inbound/rev/ddfafcf06abf092811ed9960147e1b6de45b5aa9
Bug 1195167 part 4: Remove FetchDriver::BasicFetch since it is empty. r=bkelly
https://hg.mozilla.org/integration/mozilla-inbound/rev/82ab1c1e478dabd3ed9f18f00c0956ef8976c8d6
Bug 1195167 part 5: Make FetchDriver use AsyncOpen2. r=bkelly
https://hg.mozilla.org/integration/mozilla-inbound/rev/d90d10c6e134eb8f924860141c9fd86269d30447
Bug 1195167 part 6: Some code simplification since necko handles fetch recursion. r=bkelly
Comment 32•9 years ago
|
||
Can you file that follow-up for the no-cors credentials tests?
Assignee | ||
Comment 33•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/dc567e5e1576845e45bdc4abfda4e32a8343b37c
Bug 1195167: Followup to fix test which I forgot to change
Comment 34•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/ede755bf4085
https://hg.mozilla.org/mozilla-central/rev/d0e57a128d0d
https://hg.mozilla.org/mozilla-central/rev/17c8f6d7d1d2
https://hg.mozilla.org/mozilla-central/rev/ddfafcf06abf
https://hg.mozilla.org/mozilla-central/rev/82ab1c1e478d
https://hg.mozilla.org/mozilla-central/rev/d90d10c6e134
https://hg.mozilla.org/mozilla-central/rev/dc567e5e1576
Status: NEW → RESOLVED
Closed: 9 years ago
status-firefox44:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla44
Comment 35•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/ede755bf4085
https://hg.mozilla.org/mozilla-central/rev/d0e57a128d0d
https://hg.mozilla.org/mozilla-central/rev/17c8f6d7d1d2
https://hg.mozilla.org/mozilla-central/rev/ddfafcf06abf
https://hg.mozilla.org/mozilla-central/rev/82ab1c1e478d
https://hg.mozilla.org/mozilla-central/rev/d90d10c6e134
https://hg.mozilla.org/mozilla-central/rev/dc567e5e1576
You need to log in
before you can comment on or make changes to this bug.
Description
•