Loading a local HTML file with javascript files - google-chrome-extension

I'm building my first chrome extension, and I'm running into a very basic problem.
My extension has a background script running all the time, that redirects the url of a webpage to a local web page if certain conditions are met.
chrome.tabs.update(e.tabId,
{url: "popup.html"});
Popup.html is loaded into the tab. This works fine, but I want to include some javascript in popup.html.
I'm able to include a popup.js file, but trying document.addEventListener doesn't work, because document is null.
Also, when I try to include jquery.js, I get
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".
I tried updating the manifest file properties to this, but it didn't seem to help:
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["background.js", "jquery.min.js", "popup.js"]
}
],
"permissions": [
"tabs", "http://*/*", "https://*/*",
"webNavigation"
],
"background": {
"scripts": ["background.js", "popup.js", "jquery.min.js"]
}
I looked into this document http://developer.chrome.com/stable/extensions/contentSecurityPolicy.html but it didn't have any solution. Any ideas?

I, that error says you are running a inline script directly in a tag in your HTML document, or in a event handler like onclick="myCode();". Content Security Policy prevent you to do so.
I don't know if it's you who wrote that script, or if it is some external framework. Nevertheless, you should assure you don't have inline code in popup.html, or you should relax your Content Security Policy allowing inline scripts with 'unsafe-inline'.
Remember that when relaxing security policy, you are relaxing SECURITY, and your code is more vulnerable to attacks. Do it with debug purpose, but try to remove it from your release version.

Related

Include a third-party library as a content script without violating CSP & Intercepting headers

I am currently writing a browser extension that supports Manifest-v2 and v3 which requires the CashJS library (lightweight version of JQuery) for convenience. I would like my content script content/index.js to be able to use this library content/cash.min.js but I get a CSP violation stating:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-wThdlNeRf1Fp3UGuX3Ch9caqVJ8S7Wn41fdlaVxsRDE='), or a nonce ('nonce-...') is required to enable inline execution.
Here is my manifest.json (for v3):
...
"content_scripts": [{
...
"js": [
"content/cash.min.js",
"content/index.js"
]
}],
...
I have tried using content_security_policy in various ways (hashes & enabling unsafe-inline) but Chrome refuses it:
"content_security_policy": "script-src 'self' 'sha256-wThdlNeRf1Fp3UGuX3Ch9caqVJ8S7Wn41fdlaVxsRDE='; object-src 'self';"
It gives the error Invalid value for 'content_security_policy'. when attempting to load the extension. I have read this page from Mozilla as well as other posts discussing this issue but haven't found a solution that fits my needs.
This article from Chrome's documentation mentions using their sandboxing feature but it only seems to work for webpages, not the scripts themselves.
I really don't want to intercept the headers as proposed here.
Any help would be much appreciated!

Chrome extension stylesheet (.css) is not being loaded after navigation

My extension is supposed to work with https://web.whatsapp.com/:
"content_scripts": [
{
"matches": ["https://web.whatsapp.com/"],
"js": ["entry/content-script/cs.js"],
"css": ["entry/content-script/zen-mode-ui.css"]
}
],
When I load web.whatsapp.com directly, in a new tab - all is fine: the stylesheet is injected like it's supposed to:
But! If I first go to whatsapp.com and there click the link to Whatsapp Web - when web.whatsapp.com loads, the css is NOT injected:
There is no injected stylesheet snippet.
Although, the content script loads just fine.
If I then refresh the page - all is good.
Is it a bug in chrome extensions engine itself?
Setting "matches": ["https://web.whatsapp.com/*"] (note the final asterisk) have fixed it.
Looks like a bug in Chrome. Track here.

How to set Permissions and Content Security Policy for Chrome extension

I'm trying to get my Chrome extension approved and want to understand how I should properly fill in the "permissions" and "csp" sections of the manifest.json. Those parts looks as follows:
...
"permissions": [
"storage",
"http://api.openweathermap.org/data/2.5/weather*"
],
"content_security_policy": "default-src 'self' http://api.openweathermap.org/data/2.5/weather*; script-src 'self'"
...
And that got rejected.
I'm using only:
localStorage to store info about weather;
Openweathermap API to get weather info (JSON).
I don't use any remote scripts.
So, my questions are:
Do I really need a "storage" string if I use localStorage (not a chrome.storage)?
What is a proper way to set a CSP in my case?

Chrome extension injection blocked by sandbox CSP

I am currently working on a Chrome extension which has a script that needs to access global properties of the page. To do so, I came up with an approach very similar to Method 1 in this Stack Overflow answer, the only difference being that instead of inserting a new script element directly in the document, the extension creates an ìframe with a src attribute pointing to a HTML document that already contains such a script tag. This approach is convenient in my use case as this newly created iframe and HTML document are also used for other purposes, but this is not relevant to the minimal reproducible example showcased here.
Here's the code responsible for creating the iframe, executed via a content script content.js:
const iframe = document.createElement("iframe");
iframe.setAttribute("src", chrome.runtime.getURL("inject.html"));
document.body.insertBefore(iframe, document.body.firstChild);
Here is a simplified version of inject.html:
<!DOCTYPE html>
<html>
<body>
<script src="inject.js"></script>
</body>
</html>
Here is inject.js (which in reality contains code accessing the global properties of the page):
console.log("Loaded!");
Finally, manifest.json sets both inject.js and inject.html as web accessible resources and injects content.js in all pages:
{
"name": "Example",
"version": "0.0.1",
"author": "Pyves",
"content_scripts": [
{
"all_frames": true,
"matches": [
"<all_urls>"
],
"js": [
"content.js"
]
}
],
"web_accessible_resources": [
"inject.html",
"inject.js"
],
"manifest_version": 2
}
The extension is in particular targeting GitHub raw pages (for instance https://raw.githubusercontent.com/PyvesB/JavAssembly/master/README.md), which happen to have a sandbox Content Security Policy. So far this setup has been working like a charm, however since updating my Chromium-based browsers from version 63 to 64 earlier this month, the extension is no longer fully functional. inject.js is blocked, with the following error message in the browser's console:
Blocked script execution in 'chrome-extension://xxxx/inject.html' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.
Am I missing something here? How can I once again inject extension scripts in sandboxed frames in Chromium 64+?

Chrome Extensions: You do not have permission to use blocking webRequest listeners

I am writing an extension and have this call in my background page:
chrome.webRequest.onBeforeRequest.addListener(function(details) {console.log(details)}, {urls: ["<all_urls>"]}, ["blocking"]);
However whenever I run it I get this error in the dev tools for the background page:
Error during webRequestInternal.addEventListener: You do not have permission to use blocking webRequest listeners. Be sure to declare the webRequestBlocking permission in your manifest.
Even though my permissions in my manifest look like so:
"permissions": [
"cookies",
"http://*/*",
"https://*/*",
"tabs",
"history",
"webRequest",
"webRequestBlocking"
]
What the heck is going on here? Here's the web request docs http://developer.chrome.com/stable/extensions/webRequest.html.
Works good for me with following code, why do you want to do it in a background page in specific?
Screen Shot
Manifest.json
{
"name":"My First App",
"description":"This is First App",
"version":"1",
"manifest_version":2,
"permissions": [
"cookies",
"http://*/*",
"https://*/*",
"tabs",
"history",
"webRequest",
"webRequestBlocking"
],
"icons":{"16":"icon.jpg"},
"background":{
"scripts": ["background.js"]
},
"browser_action":{
"default_popup":"popup.html",
"default_icon":"icon.jpg"
}
}
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
chrome.webRequest.onBeforeRequest.addListener(function(details) {
console.log(details);
}, {urls: ["<all_urls>"]}, ["blocking"]);
Background.js
function doNothing(){
}
I had a similar problem when I was writing my first Chrome extension:
My solution was to remove the extension, fix the manifest.json and add the extension again. Just deactivating it and re-activating it won't do the trick.
I loaded the extension into Chrome and started to debug. When I found an error in the code, I deactivated the extension, fixed the bug an activated the extension again. This worked fine to fix code errors. But when I tried to use the webrequest module in a blocking fashion I always got "Error during webRequestInternal.addEventListener: You do not have permission to use blocking webRequest listeners. Be sure to declare the webRequestBlocking permission in your manifest.". No matter how I changed the manifest.json.
Going to manifest version 2 instead of 3 fixed this issue for me.

Resources