Chrome extension injection blocked by sandbox CSP - google-chrome-extension

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+?

Related

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.

open all the links on a web page with a single click on Chrome Extensions

I want open all the links on a web page with a single click on Chrome Extensions. I try for that وbut I did not get any results. please help me ...
my manifist.json file :
{
"name": "Open Links in New Tabs",
"version": "1.0",
"description": "open all link in page on new tabs with one click",
"background_page" : "background.html",
"browser_action": {
"default_icon": "icon.png"
},
"permissions":
["tabs"],
"manifest_version": 2
}
background.html file :
<!doctype html>
<html>
<head>
<script src="background.js"></script>
</head>
<body>
</body>
</html>
background.js file :
for(i = 0; i < document.links.length; i++)
{ chrome.tabs.create({active: true, url: document.links[i].href});}
Please explain any problems. thanks
When you access the document object in background.js, you're looking at background page, not the currently active tab.
To access the DOM contents of the open page, you will need a content script. It can then send a message to the background script (which has access to chrome.tabs) with the list of links to open.
Please take a moment to read this excellent overview of extension architecture. Also, read on messaging to pass the list.
Actually, if you're going to be injecting the script programmatically via chrome.tabs.executeScript, you can ditch messaging and just use the callback of executeScript.
As a side note, since you don't have any HTML in the background page, you can replace it with an auto-generated script page like this:
manifest.json
"background": {
scripts": ["background.js"]
},
in place of "background_page"
Lastly, consider minimal permissions that you need.
If your extension is supposed to trigger on click on the extension button (wrapped in a chrome.browserAction.onClicked listener), you can inject a script "for free" with activeTab permission, no need for tabs/host pemission.
Same goes to chrome.tabs.create, you don't need the mighty and scary "tabs" permission.
There are quite a few.
A background script doesn't have access to the page DOM of a tab. The only DOM it can access directly is the DOM of the background.html. You should use a content script and message passing.
background_page is an option of Manifest Version 1, you are using Manifest Version 2, for which the option is called background. Usually you provide the background.js directly as a script (see https://developer.chrome.com/extensions/background_pages). You should return after you implemented those suggestions

Loading a local HTML file with javascript files

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.

chrome extension - manifest version 2

I have a chrome extension that has a reference to the jquery file.
this is my popup html (only the head tag):
<head>
<title>My Extention</title>
<script type="text/javascript" src="http://www.MySite.com/Resources/JS/JQuery/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="MyExtensionScript.js"></script>
</head>
so in "MyExtensionScript.js" i thought i could use jquery but apparently the $ function is not defined.
This is my manifest.json file:
{
"name": "My Test Extension",
"version": "1.0",
"manifest_version": 2,
"description": "Test version of My Extension",
"browser_action": {
"default_icon": "test.ico",
"default_popup": "Test.html"
},
"permissions": [
"cookies",
"tabs",
"<all_urls>"
]
}
in version 1 of the manifest it worked, but now it doesn't. I tried to use the "web_accessible_resources" and add to them "http://www.MySite.com/Resources/JS/JQuery/jquery-1.7.2.min.js" but that didn't work also. any ideas?
also, i have a script injected to the current page and returning me a message (in my case some html source of the current page), will this behavior be affected by the transition to manifest version 2?
Thanks all :)
EDIT: I have a web application that enables cross domain scripting (using JSONP). In my extension i had a script calling a web service in my site with $.getJSON. now it doesn't work. i'm pretty sure that it has to do with the new manifest version but how can i enable again the cross domain scripting?
You need to use a jQuery file stored locally in your extension, rather than referenced from your site.
This is due to Chrome's strict Content Security Policy that only allows local scripts to be executed, with no inline code.
Web Accessible Resources are files inside your extension that may be accessed from the web, rather that resources your extension can access that are on the web. For example, if you wanted to change the background image of a page using an image stored in the extension, you have to add that image to the list in web_accessible_resouces in your manifest.
The change of manifest version should not affect your content scripts, unless they do something that is no longer allowed. You can see what else has changed from the Chrome manifestVersion docs.
I just include jquery in my content scripts. just make sure to load it before your script.
{
"manifest_version": 2,
"default_title": "Babble",
"version": "1.2",
"description": "Chat in your language with friends in their language",
"default_locale": "en",
"default_icons": {
"16": "img/icon16.png",
"48": "img/icon48.png",
"128": "img/icon128.png"
},
"content_scripts":[
{
"matches": ["http://mail.google.com/*", "https://mail.google.com/*"],
"css" : ["css/style.css"],
"js" : ["js/jquery.js" , "js/translate.js" , "js/jquery.cookie.js"]
}
]
}

Using sandboxed pages in chrome extensions

Manifest version 2 of chrome extensions will no longer support use of eval or new Function on regular extension pages. My chrome extension uses a UI Framework (Kendo UI) on the options page that makes use of these mechanisms and therefore I'm looking for a solution.
According to this session from IO 2012 the idea is to put the corresponding page into a sandbox and load it into the extension via an iframe.
Here is a simplified example what I'm trying to do: https://gist.github.com/3058943
manifest.json:
{
"name": "Sandbox test",
"manifest_version": 2,
"options_page": "main.html",
"sandbox": {
"pages": [ "index.html" ]
}
}
main.html:
<html>
<head></head>
<body>
<iframe id="iframe" src="index.html" ></iframe>
</body>
</html>
index.html:
<html>
<head></head>
<body>
<h1>Inside the sandbox</h1>
</body>
</html>
When I load the options page in this example, I'm getting the error message:
Denying load of chrome-extension://fahdnpkbgfjkocogbjlljfbhnljcehoh/index.html. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by web pages.
I don't think that each sandboxed page is also supposed to be a web_accessible_resources.
But even when I try to define the sandboxed pages also as web_accessible_resources in the manifest file, then the sandboxed page gets loaded but use of new Function inside the iframe is still blocked.
The above described error message occurs on Chrome 20.0.1132.47.
I tested with the dev channel version 21.0.1180.15 and here the sandboxed iframe loads without problems.

Resources