New issue
Advanced search Search tips

Issue 914442 link

Starred by 2 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Chrome , Mac
Pri: 2
Type: Bug



Sign in to add a comment

WebRequest API does not log blocked mixed-content requests

Reported by seoi...@weeblrpress.com, Dec 12

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0

Steps to reproduce the problem:
I am building a web extension that uses the webRequest API to check - among other things - for mixed-content requests and signal them to the user.

This is working fine on Firefox but it seems mixed-content requests that are blocked by Chrome (ie active mixed-content like script) do not appear at all when listening to webRequest events.

chrome.webRequest.onCompleted.addListener(
      (details) => {
          console.log('ON COMPLETED')
          console.log(details)
      },
      {
          urls: ['*://*/*'],
          types: ['font', 'image', 'media', 'script', 'stylesheet', 'sub_frame', 'xmlhttprequest']
      }
    )

does not list any blocked mixed-content request in Chrome while it does in Firefox. Note that these requests are listed in the chrome dev tools.

Similar code for other events have the same behavior. I tested onBeforeRequest and onBeforeSendHeaders

The only events that "works" is onErrorOccurred:

chrome.webRequest.onErrorOccurred.addListener(
      (details) => {
          console.log('ON ERROR OCCURED')
          console.log(details)
      },
      {
          urls: ['*://*/*'],
          types: ['font', 'image', 'media', 'script', 'stylesheet', 'sub_frame', 'xmlhttprequest']
      }
    )

This code will list the blocked requests but unfortunately without enough information to be useful. In the case of a request to an http resource blocked and showing as blocked in the chrome dev tools, the details provided by onErrorOccured are:

error: "net::ERR_ABORTED"
frameId: 0
fromCache: false
initiator: "https://www.zdnet.fr"
method: "GET"
parentFrameId: -1
requestId: "1227"
tabId: 18
timeStamp: 1544624802114.908
type: "script"
url: "https://www.zdnet.fr/actualites/https//js.sddan.com/GS.d?pa=22360&si=1&u=https%3A%2F%2Fwww.zdnet.fr%2Factualites%2Fdes-sites-malveillants-profitent-d-un-bug-de-firefox-vieux-de-11-ans-39877807.htm&r=&rand=1544624801997"

2 problems here:

1 - the error (net::ERR_ABORTED) seems generic as it is also showing for a couple more requests that are NOT showing in the chrome dev tools. It's also reported in the case of 404s for instance.

2 - More importantly, the "url" property shows an https:// target. Meaning that I am not able to detect that this was a mixed-content request and report it to user.

Can anyone shed some light here? how can I get access to blocked mixed-content requests in chrome in a reliable manner?

Many thanks

What is the expected behavior?
Blocked active mixed-content requests should be available with enough information to identify them?

What went wrong?
Maybe me? This might be "as designed" for some reason but is different from other implementation and prevent us from presenting a valid page analysis to users of our extensions.

Did this work before? N/A 

Does this work in other browsers? Yes

Chrome version: Version 71.0.3578.80 (Official Build) (64-bit)  Channel: stable
OS Version: 10.0
Flash Version: 

Maybe I'm approaching this the wrong way? any suggestion welcome to grab blocked mixed-content requests from a web extension and properly identify them as such.
 
Labels: Needs-Triage-M71
Cc: vamshi.kommuri@chromium.org
Components: Platform>Extensions>API
Labels: Triaged-ET Needs-Feedback
Thanks for filing the issue!

@Reporter: Could you please share a sample test extension/test file which helps us to triage this further in a better way. Any further inputs from your end may be helpful.
Hi

Please find attached a simple web extension that implement the code above.

chrome.webRequest.onErrorOccurred.addListener(
    (details) => {
        console.log('ON ERROR OCCURED')
        console.log(details)
    },
    {
        urls: ['*://*/*'],
        types: ['font', 'image', 'media', 'script', 'stylesheet', 'sub_frame', 'xmlhttprequest']
    }
)

1 - Unzip the file
2 - "Load unpacked" the extension
3 - Inspect the background.html view from chrome://extensions
4 - Open this page: https://www.zdnet.fr. It has one blocked request for mixed content (as of right now)

Mixed Content: The page at 'https://www.zdnet.fr/actualites/' was loaded over HTTPS, but requested an insecure script 'http://www.zdnet.fr/actualites/https//js.sddan.com/GS.d/?pa=22360&si=1&u=https%253A%252F%252Fwww.zdnet.fr%252Factualites%252F&r=&rand=1544693013911'. This request has been blocked; the content must be served over HTTPS.

5 - In the background.html view, you'll get the details:

error: "net::ERR_ABORTED"
frameId: 0
fromCache: false
initiator: "https://www.zdnet.fr"
method: "GET"
parentFrameId: -1
requestId: "5387"
tabId: 56
timeStamp: 1544693014073.453
type: "script"
url: "https://www.zdnet.fr/actualites/https//js.sddan.com/GS.d?pa=22360&si=1&u=https%3A%2F%2Fwww.zdnet.fr%2Factualites%2F&r=&rand=1544693013911"

As you can see, the URL is reported as https://www.zdnet.fr/actualites/https//js.sddan.com.... instead of the http:// request shown in the chrome dev tools, which caused the request to be blocked. Likewise, the error is a generic "net::ERR_ABORTED"

So we are unable to identify this request as blocked because of mixed content.

Best regards

blocked-requests.zip
2.8 KB Download
Project Member

Comment 4 by sheriffbot@chromium.org, Dec 13

Labels: -Needs-Feedback
Thank you for providing more feedback. Adding the requester to the cc list.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Components: Blink>SecurityFeature
I believe mixed content gets blocked before where WebRequest hooks in (from the net stack's perspective, the requests simply never happened), so this is probably working as intended, but adding Blink folks in case they think otherwise.
Hi

That's a bit unfortunate as it prevents us from reporting those requests. As it seems to work in Firefox, is it something that's not well defined by the webRequest specification?

As a side note, I think I noticed requests made by service workers are also not visible.

Best regards

Labels: -Hotlist-Interop
A use case for passing mixed content requests through the webRequest API is for an extension to upgrade a request to HTTPS in some cases, of return a secure (or insecure) response of other kinds (for example, it replaces all of the insecure images with an "Insecure! Too bad..." image, or a more informative image).
Hi @phistuck@gmail.com

Another use case, our use case, is for an extension to signal to the web developers building the site, or to the web owner managing their content some issue with mixed content while they browse their own site.

As a side note - guess it deserves its own bug report, I now have the same issue with requests made by service workers: they do not seem to be visible in any way by the webRequest API which causes the same sort of issue.

Best regards

#9 - regarding the side note, there is a bug for that already, I believe. Try searching.

Your use case can possibly be fulfilled without an extension (I think there is a reporting API for those, not sure).
Hi,

> Your use case can possibly be fulfilled without an extension (I think there is a reporting API for those, not sure).

But the point is to use an extension. Whether it's doable otherwise does not matter. The idea is that a web developer has an "Info" extension that reports issues (and provide useful non-issue information on the page) as they check on pages they are building. If getting this information requires:

- a script running on a page
- or fetching data from API

then it does not solve the problem.

FYI, here is current version of the extension: https://chrome.google.com/webstore/detail/seoinfo/ppbdklaincgliegpfolkjjfncpgobneb

I'll do another search about the service worker question.

Best regards

#11 - though if this can be fulfilled using a web API, an extension can be created that makes use of that web API. It might be less convenient, but the functionality is not infeasible.
#12 - Not really. For instance, that would not work when offline.

Best regards

Comment 14 Deleted

Comment 15 Deleted

#13 - not sure how that changes things, but you discussing this is not the place, especially since I am not 100% sure there is such an API or mechanism.

(Sorry for triple posting :()
#16 - you said it'd be feasible without an extension and I just commented that it was not because using API is not possible when the user has no internet access which is not that uncommon.

For reference, the discussion about service workers and webRequest is seems to be here: https://bugs.chromium.org/p/chromium/issues/detail?id=897060

Back to the current discussion indeed, I think it's important that those blocked-request do get through extension, at onErrorOccurred and totally makes sense.

My current problem is that I cannot identify them because the URL value is incorrect, it has https instead of http. Or is this the browser attempting to upgrade to blocked request?

Best regards



Comment 18 by mkwst@chromium.org, Yesterday (44 hours ago)

Cc: rdevlin....@chromium.org davidben@chromium.org
Labels: OS-Chrome OS-Linux OS-Mac
Status: Available (was: Unconfirmed)
At the moment, we block mixed content in Blink, before even creating a request. We have vague plans to move that blocking behavior to the browser process for better security guarantees. I could imagine moving it all the way into the network service so that the check could happen after extensions have a chance to manipulate the request. There aren't any concrete plans to do so that I know of (and it would be a lot of work).

+davidben@ might have opinions about that kind of change to //net. +Devlin might as well from an extensions perspective.

Comment 19 by seoi...@weeblrpress.com, Yesterday (44 hours ago)

Hi all,

So it looks like this won't happen before a while, if ever. However, one important thing that did not get any comment is that requests are actually listed, under the onErrorOccurred event.

The issue here is that the event does not have the original URL, only the one that was upgraded to https (see copy/paste below of part of my first message). If I was able to access the original URL, that'd be enough for my purpose which is to signal to user/developer that mixed-content is happening.

Or maybe what this onErrorOccured is only for the updgraded request? ie Chrome first tried the original HTTP request, blocked it without any error event and then triggered an upgraded request automatically (but that domain does not have HSTS) Then that request is processed normally and appears at onErrorOccured? But why with the message net::ERR_ABORTED then?

Best regards

>>
The only events that "works" is onErrorOccurred:

chrome.webRequest.onErrorOccurred.addListener(
      (details) => {
          console.log('ON ERROR OCCURED')
          console.log(details)
      },
      {
          urls: ['*://*/*'],
          types: ['font', 'image', 'media', 'script', 'stylesheet', 'sub_frame', 'xmlhttprequest']
      }
    )

This code will list the blocked requests but unfortunately without enough information to be useful. In the case of a request to an http resource blocked and showing as blocked in the chrome dev tools, the details provided by onErrorOccured are:

error: "net::ERR_ABORTED"
frameId: 0
fromCache: false
initiator: "https://www.zdnet.fr"
method: "GET"
parentFrameId: -1
requestId: "1227"
tabId: 18
timeStamp: 1544624802114.908
type: "script"
url: "https://www.zdnet.fr/actualites/https//js.sddan.com/GS.d?pa=22360&si=1&u=https%3A%2F%2Fwww.zdnet.fr%2Factualites%2Fdes-sites-malveillants-profitent-d-un-bug-de-firefox-vieux-de-11-ans-39877807.htm&r=&rand=1544624801997"

2 problems here:

1 - the error (net::ERR_ABORTED) seems generic as it is also showing for a couple more requests that are NOT showing in the chrome dev tools. It's also reported in the case of 404s for instance.

2 - More importantly, the "url" property shows an https:// target. Meaning that I am not able to detect that this was a mixed-content request and report it to user.

Comment 20 by davidben@chromium.org, Today (12 hours ago)

Cc: mmenke@chromium.org
+mmenke for the high-level //net question in comment #18. I'm fairly out of date on that layer at this point.

Comment 21 by mmenke@chromium.org, Today (11 hours ago)

I'm not sure what change to net is being suggested?  Even if this is moved to the network service, I don't think this really belongs in net/, since it's pretty tangential to HTTP.

Comment 22 by rdevlin....@chromium.org, Today (11 hours ago)

Cc: karandeepb@chromium.org
@mmenke, @davidben please also see #19.  I think that having the request aborted before it gets to the webRequest API is acceptable.  Though I fully acknowledge there are valid use cases for ensuring extensions can see/manipulate it, I think they are, largely, lower priority.  However, the fact that the URLRequest in the error message has https is a little strange.  From 19:

> Or maybe what this onErrorOccured is only for the updgraded request? ie Chrome first tried the original HTTP request, blocked it without any error event and then triggered an upgraded request automatically (but that domain does not have HSTS) Then that request is processed normally and appears at onErrorOccured? But why with the message net::ERR_ABORTED then?

This would be my guess - http is silently blocked, and https just fails.  ERR_ABORTED is used for many different errors, and so if the request just fails with a 404 (not found), that might be what's happening.  mmenke@, davidben@, can you confirm?

@seoinfo, you may also be able to verify if this is the issue by checking the "Network" tab in dev tools - that might have some additional information.

Comment 23 by mmenke@chromium.org, Today (11 hours ago)

ERR_ABORTED means the consumer (Not the network stack) cancelled a request, for reasons unknown.

A 404 response is not a network error, it's an HTTP error, so it's treated as a successful response by the network stack.  Only certain magic HTTP error status codes that need to be handled by network magic are treated as network errors by net - like auth challenges.

Comment 24 by rdevlin....@chromium.org, Today (11 hours ago)

If that's the case, any idea why the URL in the URLRequest (from which the details for onErrorOccurred are generated) is https instead of http?

Comment 25 by mmenke@chromium.org, Today (11 hours ago)

No clue.  Do these even make it to the network stack?  If not, network stack folks aren't the right ones to ask.  Is the server using HSTS?

Comment 26 by karandeepb@chromium.org, Today (11 hours ago)

It seems correct to me that the original request is not reported to the web request api (The api is meant to be an abstraction of the network stack and should report actual network requests). I remember us closing a similar bug for CSP violations not being reported through the api.

I didn't know that we exposed the actual net error code to the api. Maybe we can expose a more granular error (using a different net error code). That said, the API docs do have this to say for the "error" field:

"This string is not guaranteed to remain backwards compatible between releases. You must not parse and act based upon its content."


Sign in to add a comment