This is with Chrome 70 and Firefox 63.
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.
ie: such code:
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
Many thanks
Related
I use sandbox pages in my extension to render a Vue.js app to have a less strict CSP rules than a non-sandboxed extension pages.
All works great except I can't find way how to communicate with the background service worker. chrome APIs are not available in the sandbox context so I can't use them directly the same way I use it in the content scripts.
I also tried injecting a content script with message event listener to all pages and communicate with the background script via it (using postMessage on the page side and chrome.runtime.sendMessage on the content script side), but the content script is injected everywhere except my sandboxed extension page.
manifest.ts
const manifest = (): chrome.runtime.Manifest => ({
...
manifest_version: 3,
...
background: {
service_worker: 'src/background/background.js',
type: 'module',
},
...
...
sandbox: {
pages: ['web/index.html'],
},
content_scripts: [
// injected everywhere, but not to the sandboxed page ^^^
{
matches: ['<all_urls>'],
js: ['src/content-scripts/inject.js'],
run_at: 'document_start',
}
],
});
export default manifest;
chrome.runtime API is not available in the sandbox page context
When i debug javaScript on devtool.
chrome.runtime
see "http://www.qq.com",it show:
chrome.runtime is undefined. see http preview.
But when i debug it on https site (https://www.qq.com ).it work fine. see https preview.
tips: all script run on top frame.
Can i change "chorme:flags" to enable it ?
i got why now.
"chrome.runtime.sendMessage" not exist when no extension installed.---since chrome 66+.
see:https://bugs.chromium.org/p/chromium/issues/detail?id=835287
Comment 29 by rdevlin....#chromium.org, Apr 25 For at least some of
these cases from the duped bugs, I think this was caused by revision
39f8939309fe39bccc17fa1280b6c7f25c411947. This modified the
externally_connectable property of the cryptotoken component extension
(automatically built into Chrome) to only accept incoming connections
from https URLs, whereas previously it was all URLs. When it was set
to all URLs, chrome.runtime.sendMessage would always be available
because any URL could potentially send a message to the cryptotoken
component extension.
However, this is working as intended. The cryptotoken extension only
accepts connections from https origins (so any others would be
ignored), and sending a message to any other extension would require
the receiving extension to list the URL in the externally_connectable
options. Additionally, this means that before, any extension relying
on this behavior would likely have failed to send the message, but
done so asynchronously (once the message failed to find an appropriate
receiver) rather than synchronously (since runtime is undefined). If
the extension lists the URL in externally_connectable, then
chrome.runtime should still be present. If the extension does not
list the site in externally_connectable, then chrome.runtime not being
available is intended behavior.
Is there any case in which chrome.runtime is undefined for
non-sandboxed chrome-extension:// pages, or for web pages where an
installed extension specifies that web page's URL in the
externally_connectable field of the manifest? If so, please attach an
extension that demonstrates this issue. If not, this sounds like it's
WAI.
fix: add one extionsion with:manifest.
"externally_connectable": {
"ids": [
"*"
],
"matches": [
"http://test.yoursite.in:9090/*",
"*://*.chromium.org/*"
]
},
thinks all.
I'm trying to make a Chrome Extension which scrapes some details from Pull Requests on Github using the Fetch API, and then displays them elsewhere. I'm running into some problems when I try to use this with a non-public repository on Github. I believe this is related to CSRF protection, and the rules that govern Chrome extensions having access to session cookies.
I have the following in my extension's manifest.json:
"content_scripts": [{
"matches": [
"*://github.com/*/*/pulls"
],
"js": ["script/underscore-1.8.3.min.js", "script/content.js"]
}],
"permissions": [
"tabs",
"activeTab",
"*://github.com/*",
"webNavigation"
]
But when I run the following from within my script/content.js:
fetch('/redacted/redacted/pull/4549', {credentials: 'same-origin'}).then((response) => {
return response.text();
}).then((text) => {
// do cool stuff
})
This produces a 404 response from Github. Inspecting this request with Chrome Inspector's network tab, I can see it is not sending my GitHub session header with the request.
If I make the very same request using the Javascript prompt in the Inspector, I can see a 200 response, and I can see that it is sending my session cookies.
My understanding was that specifying the Github domain in my manifest.json would mean my extension would have access to my session data in my content scripts, is this not correct? What should I be doing to make a valid request to this protected content?
According to Chrome blog, to include cookies you need credentials: 'include' instead of credentials: 'same-origin'.
Specifying github in the permissions only gives access to the host, its there to limit damage if the extension/app is compromised by malware (source).
Its not indicated in the content script documentation that session data can be retrieved in content scripts, just their DOMs. I think it would be better if you use and incorporate the official Github API in the chrome extension project you're creating.
I am trying to develop a chrome extension that would set the "host" header on certain requests. But the documentation is contradicting as to if the "host" header can be modified or not.
Both of these issues indicate that a) it should not be possible and b) it is impossible
https://code.google.com/p/chromium/issues/detail?id=154900
https://code.google.com/p/chromium/issues/detail?id=158073
Yet multiple extensions in the gallery state they do modify the "host" header.
e.g.
https://chrome.google.com/webstore/detail/header-hacker/phnffahgegfkcobeaapbenpmdnkifigc?hl=en
https://chrome.google.com/webstore/detail/change-http-request-heade/ppmibgfeefcglejjlpeihfdimbkfbbnm
Is it possible to modify the "host" header in the windows version of chrome, and if so how?
Background: I want to be able to test load balanced web instances hitting each host directly via ip address. The "hosts" file is to cumbersome for a large number of hosts. At the moment I use curl to pass the modified "host" header, but I really need the solution in the browser and available for others.
#kzahel was right, and the note about redirection was spot on, here is my basic working code.
chrome.webRequest.onBeforeSendHeaders.addListener(function (details) {
if (details.url.indexOf('toast.txt') <= -1)
return;
details.requestHeaders.push({
name: 'Host',
value: 'testhost:80'
});
return { requestHeaders: details.requestHeaders };
}, {
urls: ['http://*/*']
}, ['requestHeaders', 'blocking']);
chrome.webRequest.onBeforeRequest.addListener(function (details) {
if (details.url.indexOf('sauce') <= -1)
return;
var url = 'http://127.0.0.1/toast.txt';
return { redirectUrl: url };
}, {
urls: ['http://*/*']
}, ['blocking']);
Admittedly a slightly odd example but it goes like this.
My local IIS has a site created that points to a folder that has a file "toast.txt", which is bound to "testhost".
Windows can no way of knowing about "testhost" e.g. cannot ping it.
With the extension running.
Enter the address http://testhost/sauce
The extension notes the "sauce" in the "onBeforeRequest" method and redirects to "http://127.0.0.1/toast.txt" which in turn is picked up on by the "onBeforeSendHeaders" method where the "Host" header is added containing "testhost:80". All this occurs before the request leaves Chrome.
Now IIS receives the request "/toast.txt" that by itself would result in a 404, but because the "Host" header is set it pushes the request to the new website that is bound to "testhost" which then returns the "toast.txt" file.
Phew!
It looks like you shouldn't have difficulty doing this. Use onBeforeRequest
onBeforeRequest: Fires when a request is about to occur. This event is sent before any TCP connection is made and can be used to cancel or redirect requests.
Since this is triggered before any connection to the server is made, you should be able to modify the host header then [edit: if host header is not available, then use a redirect]. Make sure you have the "requestHeaders" permission in the manifest or else you won't see the request headers at all.
I'm writing an extension that requests XML content from a server and displays data in a popup/dialog window. I've added the website to my manifest.json permissions like so:
"permissions": [
"http://*/*"
],
Later I added the following code to my background page:
function loadData() {
var url = "http://www.foo.com/api/data.xml";
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
...
xhr.send();
the problem is, that I get the cross-site security error "Origin chrome-extension://kafkefhcbdbpdlajophblggbkjloppll is not allowed by Access-Control-Allow-Origin. "
The thing is, with "http:///" in the permissions I can request "http://www.foo.com/api", but I can't find any way to allow "http://www.foo.com/api/data.xml".
I've tried both "http:////*" and http://www.foo.com/api/data.xml" in the "permissions". What else should I be doing?
This should work (SOP doesn't apply to chrome extensions),so there are three possibilities:
There is some mistake somewhere
Just to make sure use add <all urls> permission and check that extension really have this permission. (e.g. execute chrome.runtime.getManifest() in console when inspecting background page )
Server itself is checking Origin header and is rejecting request if origin value is unexpected
You can quickly check this by using some http tester and sending request manually (for example Dev Http Client for chrome, since I'm one of the developers). If it shows the same error, it means that the server is really checking origin header.
To fix this you will have to make server somehow accept your origin , or you can use chrome.webRequest to set valid origin header to all the requests sent to the target server (standard XHR api doesn't allow modification of Origin header)
Chrome bug
Well in this case you can only report this error and wait for the best