webRequest.onHeadersReceived modified headers are cached and cannot be further modified
Categories
(WebExtensions :: Request Handling, defect, P3)
Tracking
(firefox70 fixed)
Tracking | Status | |
---|---|---|
firefox70 | --- | fixed |
People
(Reporter: April, Assigned: mixedpuppy)
References
(Blocks 1 open bug)
Details
(Whiteboard: [webRequest])
Attachments
(3 files)
Reporter | ||
Updated•8 years ago
|
Reporter | ||
Updated•8 years ago
|
Updated•8 years ago
|
Assignee | ||
Comment 1•8 years ago
|
||
Assignee | ||
Comment 3•7 years ago
|
||
Reporter | ||
Comment 5•7 years ago
|
||
Updated•7 years ago
|
Updated•7 years ago
|
Comment 6•7 years ago
|
||
Assignee | ||
Comment 7•6 years ago
•
|
||
Revisiting CSP issues, I just wrote tests on this. The header is indeed changed and/or updated on cached requests, so webrequest itself seems to be doing the right thing. However, the cached headers themselves are not updated.
I'll post the test patch, the second test fails on the 3rd request.
request 1: initial request, initial header value set, passes
request 2: cached request, header value is modified, passes
request 3: cached request, header value is not modified again,
fails because the header value is that set in request 1 rather than the modified header from request 2.
In the platform layer I am unsure about:
- should httpchannel update the cache with the modified header from request 2?
- Should httpchannel just invalidate the cache entry if a modification like this happens?
- when is the csp applied to the document, assuming that the header is request 2 is not actually used (I haven't tested for that yet)
Assignee | ||
Comment 8•6 years ago
|
||
Assignee | ||
Updated•6 years ago
|
![]() |
||
Comment 10•6 years ago
|
||
The test is missing in the patch.
![]() |
||
Comment 11•6 years ago
|
||
Few questions in return:
webRequest.onHeadersReceived
is (also) called from "http-on-examine-merged-response" notification? (we call it for 304 and 206 responses)- how is header modification performed by
webRequest.onHeadersReceived
behaving for non-cached responses? - is this web-ext notification also called for non-cached responses from "http-on-examine-response"?
If the first and the last question answer is 'yes', then I know why we don't accept header modification on cached responses. For 200 network responses, we first call "http-on-examine-response" and only after that we call AddCacheEntryHeaders
(from InitCacheEntry()
) which stores the whole response head (with provided modification via SetResponseHeader()
) as "response-head" metadata on the cache entry. For cached responses we first store "response-head" meta and then we call the notification leading onHeaderReceived. After that, we don't store "response-head" on the cache entry again, so modifications are lost. Note that the UpdateHeaders
call just selectively merges headers from the new response (nothing web-ext should worry about at all, tho.)
I think moving AddCacheEntryHeaders call below OnExamineMergedResponse
call and adding one after the notification in ProcessPartialContent would fix this bug.
I also think we can just remove SetMetaDataElement("response-head", head.get());
few lines above as those are duplicated (fix bug 1372961).
Assignee | ||
Comment 12•6 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #10)
The test is missing in the patch.
ugh, sorry, I've attached it now.
Assignee | ||
Comment 13•6 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #11)
Few questions in return:
webRequest.onHeadersReceived
is (also) called from "http-on-examine-merged-response" notification? (we call it for 304 and 206 responses)
It is called for all on-examine notifications.
- how is header modification performed by
webRequest.onHeadersReceived
behaving for non-cached responses?
As one would expect. Actually the failure in the test file also illustrates that the header set in the non-cached response is what is cached.
- is this web-ext notification also called for non-cached responses from "http-on-examine-response"?
Yes, per above.
If the first and the last question answer is 'yes', then I know why we don't accept header modification on cached responses.
I'll write up a patch and see if your suggestions work.
Thansk!
Assignee | ||
Comment 14•6 years ago
|
||
Honza, the actual notification that my test was triggering is on-examine-cached-response rather than merged-response. The patch includes changes that make the test pass, but there are likely still issues with the patch. Could you take a look? See my comment in the phab comments.
Assignee | ||
Comment 15•6 years ago
|
||
Honza, something that is also ticking in the back of my mind, do we actually want to modify headers in cache based on extension handlers?
![]() |
||
Comment 16•6 years ago
|
||
(In reply to Shane Caraveo (:mixedpuppy) from comment #15)
Honza, something that is also ticking in the back of my mind, do we actually want to modify headers in cache based on extension handlers?
we probably don't. but my understand was that it was expected to see the modified headers in the next response, which happens to be fully read from the cache. so I'm a bit puzzled what is expected.
Assignee | ||
Comment 17•6 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #16)
(In reply to Shane Caraveo (:mixedpuppy) from comment #15)
Honza, something that is also ticking in the back of my mind, do we actually want to modify headers in cache based on extension handlers?
we probably don't. but my understand was that it was expected to see the modified headers in the next response, which happens to be fully read from the cache. so I'm a bit puzzled what is expected.
Well, there are two issues in this bug. One stating that changing headers in onHeadersReceived on a cached response doesn't modify the headers. It appears based on my test that those headers are indeed modified. However, we were not waiting on that notification to finish asynchronously (fixed in patch) so the headers may not have been modified prior to them being used.
The second issue is about CSP, and whether the CSP header modified on a cached request is actually used. I can probably write a test for that here as well.
If we don't have to modify the cache, then I think we can leave that part out and document the behavior. It would mean an extension would have to always watch for and modify the headers (again) on cached requests.
Reporter | ||
Comment 18•6 years ago
|
||
If we don't have to modify the cache, then I think we can leave that part out and document the behavior. It would mean an extension would have to always watch for and modify the headers (again) on cached requests.
I think this is okay, right? It's an event firing and a small piece of JavaScript code, and I wouldn't have any problems modifying every request that way.
Assignee | ||
Comment 19•6 years ago
|
||
April, the latest patch has a test for the CSP per commen 0, and passes without any changes. Can you look at the test and see if it is covering your original issue? Can you otherwise validate the problem?
Reporter | ||
Comment 20•6 years ago
|
||
Is it nightly, or do I need to build the patch?
Assignee | ||
Comment 21•6 years ago
|
||
The patch it test-only, so you don't need it.
Assignee | ||
Updated•6 years ago
|
Updated•6 years ago
|
Reporter | ||
Comment 23•6 years ago
|
||
Hmm, I'll try to take a look at it today! Thanks!
Reporter | ||
Comment 24•6 years ago
•
|
||
I disabled the "cache busting" code inside Laboratory:
https://addons.mozilla.org/en-US/firefox/addon/laboratory-by-mozilla/
I then started by forcing this CSP with the extension on mozilla.org:
default-src *; img-src 'none'
And force refreshed the page. Sure enough, no images. Perfect. Then I turned off the custom CSP as seen by Laboratory, refresh the page (not forced refreshed) and the results I got back were truly bizarre:
- HTTP code: 200
- Transferred in dev tools: cached
- CSP in response header, which shows that it allows images: img-src 'self' *.mozilla.net *.mozilla.org *.mozilla.com data: mozilla.org www.googletagmanager.com www.google-analytics.com adservice.google.com adservice.google.de adservice.google.dk creativecommons.org ad.doubleclick.net; script-src 'self' *.mozilla.net *.mozilla.org *.mozilla.com 'unsafe-inline' 'unsafe-eval' www.googletagmanager.com www.google-analytics.com tagmanager.google.com www.youtube.com s.ytimg.com; connect-src 'self' *.mozilla.net *.mozilla.org *.mozilla.com www.googletagmanager.com www.google-analytics.com https://accounts.firefox.com/ https://accounts.firefox.com.cn/; style-src 'self' *.mozilla.net *.mozilla.org *.mozilla.com 'unsafe-inline'; frame-src www.googletagmanager.com www.google-analytics.com www.youtube-nocookie.com trackertest.org www.surveygizmo.com accounts.firefox.com accounts.firefox.com.cn www.youtube.com; default-src 'self' *.mozilla.net *.mozilla.org *.mozilla.com; child-src www.googletagmanager.com www.google-analytics.com www.youtube-nocookie.com trackertest.org www.surveygizmo.com accounts.firefox.com accounts.firefox.com.cn www.youtube.com
- Page display: no images
- The Laboratory event handler that would inject the CSP is -not- firing, so it's definitely not changing the CSP
All in all, Firefox's behavior is pretty bizarre unless it was secretly returning the cached headers. I'll attach a screenshot of everything happening.
Reporter | ||
Comment 25•6 years ago
|
||
Assignee | ||
Comment 26•6 years ago
|
||
Using this extension the following str works just fine for me:
- new profile
- load mozilla.org
- install extension
- reload mozilla.org
expect: images are not loaded
- uninstall extension
- reload mozilla.org
expect: images are loaded
Comment 27•6 years ago
|
||
![]() |
||
Comment 28•6 years ago
|
||
bugherder |
Updated•6 years ago
|
Comment 29•6 years ago
|
||
When using example extension from bug 1376060 https://ftp.mozilla.org/favicon.ico still appears as image on soft refresh.
Build ID 20190813095543
Comment 30•6 years ago
|
||
Hello,
Using the STR and extension provided in Comment 26, on Nightly (70.0a1/20190901214807) under Windows 10 Pro 64-bit and macOS High Sierra 10.13.6, the following results were obtained:
- with the extension installed, images are not loaded upon page reload
- after the extension is uninstalled, the images are loaded once the page is reloaded
Can you please confirm these are the proper STR to test the issue, as well as the expected results of the fix? Thanks !
Comment 31•6 years ago
|
||
Modify extension from comment 26 to work on thezdi.com
:
urls: ["*://www.thezdi.com/*"],
- new profile
- load https://www.thezdi.com/blog/2017/12/20/invariantly-exploitable-input-an-apple-safari-bug-worth-revisiting
- install extension
- reload https://www.thezdi.com/blog/2017/12/20/invariantly-exploitable-input-an-apple-safari-bug-worth-revisiting
expect: images are not loaded
- uninstall extension
- reload https://www.thezdi.com/blog/2017/12/20/invariantly-exploitable-input-an-apple-safari-bug-worth-revisiting
expect: images are loaded
actual: images are not loaded
Version 71.0a1
Build ID 20190903094847
Comment 32•6 years ago
|
||
Other uBlock Origin feature, HTML filtering, which internally uses webRequest.filterResponseData
is also suffering because of cache issues. From my experience It's also easier to reproduce. For example:
- fresh profile
- add
github.com##^#user\[login\]
to uBlockO "My filters" - open github.com
field under "Username" will be missing - good
- middle click on refresh button to clone tab
"Username" field is now present - bad
I'm not sure it's strictly related to this Issue (although proposed workaround from comment 0 is working) should I maybe create new one?
Comment 33•6 years ago
|
||
I forgot to mention in comment 32 - workaround in uBO advanced setting cachecontrolforfirefox1376932
must be set to unset
to reproduce.
Description
•