This question already has an answer here:
Chrome Extension With Background Page Not Working With Manifest Version 2
(1 answer)
Closed 7 years ago.
I am trying to use Socket.io in my Chrome extension, but for some reason I can't get it to work. The following is the code I have in my background.html:
<!doctype html>
<html>
<head>
<script src='socket.io.js'></script>
<script>
var socket = io.connect('http://localhost:8080/');
chrome.browserAction.onClicked.addListener(function(tab) {
socket.send('hi');
});
</script>
</head>
<body>
</body>
And my manifest.json I have the following for loading the background page and some permissions:
"permissions": [
"http://*/",
"http://*/*"
],
"background": {
"page": "background.html"
},
This does not work however. When the extension is loaded, it should connect to the Socket.io server, but it doesn't. I am unable to figure out what is causing this. This works perfectly when I simply run the background.html file. Any help is greatly appreciated!
According to the Manifest v2 "migration guidelines" you should "remove JS code contained within tags and place it within an external JS file".
Inline JS is not executed at all, so place it in external JS files and then either import them in background.html or use the scripts attribute of the background attribute in manifest, e.g.:
"background": {
"scripts": [
"socket.io.js",
"background.js"
]
}
Try Using its CDN - https://cdn.socket.io/socket.io-1.0.6.js, and in the manifest.json file add
"content_security_policy": "script-src 'self' https://cdn.socket.io; object-src 'self'"
Worked for me.
socket.io.js isn't a file on the filesystem, it's supposed to be served by the server of your choosing. In your case, localhost:8080.
Related
Chrome extension V3 : Refused to load the script 'https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
I want to add google translate to translate popup extension but i got that error
my html
<!DOCTYPE html>
<html lang="en-US">
<body>
<h1>My Web Page</h1>
<p>Hello everybody!</p>
<p>Translate this page:</p>
<div id="google_translate_element"></div>
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'en'}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
</body>
</html>
error
https://user-images.githubusercontent.com/78076796/201490254-8194ba99-2238-462f-843c-8f45be54b68d.png
I really can't find any example of this error for chrome extension v3. help me pls :((
i tried to find extension_pages and sandbox ; but it always fails
manifest V2
In Chrome extension with manifest V2 you can do it like this:
manifest.json
"content_security_policy": "script-src 'self' https://translate.google.com;
manifest V3
Remotely hosted code
In Manifest V3, all of your extension's logic must be bundled with the extension. You can no longer load and execute a remotely hosted file. A number of alternative approaches are available, depending on your use case and the reason for remote hosting.
source: https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#remotely-hosted-code
I'm trying to make an extension for Chrome to make new tabs load a local HTML file. I have partially succeeded in this, by adding a .json file to the main directory with the following code:
{
"name": "Extension Name",
"description": "Extension description",
"version": "0.1",
"incognito": "split",
"chrome_url_overrides": {
"newtab": "start.html"
},
"manifest_version": 2
}
This sort of works. Opening a new tab loads the HTML file, but the majority of the css doesn't work and none of the images load.
I don't want to install an extension from the web store to do this for me, as I would like to be able to distribute this in the future.
I have no experience at all with Google Chrome extensions, and I couldn't find anything relating to this specific issue elsewhere. Does anyone know what I'm doing wrong? Do I need to be do something else? Is this possible? Any help would be greatly appreciated.
let me share I've made shortly.
This is the same manifest file you'd mentioned above
{
"name": "Extension Name",
"description": "Extension description",
"version": "0.1",
"incognito": "split",
"chrome_url_overrides": {
"newtab": "start.html"
},
"manifest_version": 2
}
I created a folder named assets in the root directory of chrome extension (that has the manifest.json file), where I created style.css and added an image file img.jpg.
.content p {
font-size: 26px;
}
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
</head>
<body>
<div class="content">
<p>Hello world</p>
<img src="assets/image.jpg">
</div>
</body>
</html>
This works on my end.
I hope it would give you a hind on what went wrong there.
Thanks,
I want to load some external scripts in a sandbox page and then on event page uses message passing to communicate with the sandbox page to use those scripts. I am basically following these two documentations:
https://developer.chrome.com/extensions/sandboxingEval
https://developer.chrome.com/extensions/manifest/sandbox
This is the manifest.json I use with the sandbox and event page config:
{
"manifest_version": 2,
"name": "Diver",
"description": "Diver",
"version": "0.0.1",
"devtools_page": "devtools.html",
"minimum_chrome_version" : "57",
"background": {
"page": "eventpage.html",
"persistent": false
},
"sandbox": {
"pages": ["sandbox.html"]
}
}
This is the eventpage.html, which loads the sandbox.html in an iframe:
<!doctype html>
<html>
<body>
<iframe id="sandboxFrame" src="sandbox.html"></iframe>
</body>
</html>
This is the sandbox.html, which loads an external script:
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/5.2.3/ajv.min.js"></script>
</head>
<body>
</body>
</html>
When I try it I am getting an error saying the loading of the external script is blocked by content security policy. So looks like this is not allowed according to the doc:
"Starting in version 57, Chrome will no longer allow external web content (including embedded frames and scripts) inside sandboxed pages. Please use a webview instead"
"Also, the CSP you specify may not allow loading external web content inside sandboxed pages."
The doc asks me to use webview but webview is only available in Chrome App. Next I upload sandbox.html into a cdn and replace it in the eventpage.html:
<!doctype html>
<html>
<body>
<iframe id="sandboxFrame" src="https://www.somecdn.com/sandbox.html"></iframe>
</body>
</html>
The external script loads this time, probably because that external page doesn't have the CSP blocking the script.
I don't understand why the same script is blocked when used in sandbox.html in the extension but not when sandbox.html is loaded from an external domain. I know it's because of CSP, but why do Chrome decided to block it this way. I tested it in Chrome 56 and it's not blocked. Only after Chrome 57 it's blocked.
I wish to wrap my web app inside a Chrome Packaged App.
My ultimate goals are as follows:
Mask the URL to hide my generic (second-tier) domain (e.g., http://my-app.big-company.com).
Mask the browser to give the appearance of a native desktop app.
Leverage whatever mobile conversion that Chrome Apps for Mobile might provide to allow me to use a single codebase and set of web assets (HTML, CSS & JS) to deploy my app to the mobile app stores for Android and iOS.
Here is what I have so far:
manifest.json
{
"name": "Hello World!",
"description": "My first Chrome App",
"version": "0.1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"]
}
},
"icons": { "16": "icon-16.png", "128": "icon-128.png" }
}
background.js
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('window.html', {
'outerBounds': {
'width': 400,
'height': 500
}
});
});
window.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<iframe src="http://example.com/"></iframe>
</body>
</html>
I suspect, at a minimum, there is a problem in the window.html. Specifically, I doubt I should be using an <iframe> to fetch my web app content.
Here is the documentation I have been following.
Please help.
You can do this, but you need another tag; specifically, <webview> tag instead of <iframe>. See linked documentation for all the possibilities of that tag. It also requires the "webview" permission.
Do note that this does not work well with the "should behave like a native app" philosophy, but it is possible.
This documentation suggests the OP's approach will not work and, instead, you need to package and install all the assets locally.
Chrome 18 Dev/Canary has just been released, and content_security_policy will be needed in the manifest for certain extensions.
I'm trying to get a CSP working for inline scripting, but I don't know if I'm doing something wrong or if this is a Chrome 18 bug.
manifest.json:
{
"name": "CSP Test",
"version": "1.0",
"manifest_version": 2,
"options_page": "test.html",
"content_security_policy": "default-src 'unsafe-inline'"
}
test.html:
<html><head>
<script type="text/javascript">
alert("hello");
</script>
</head></html>
In Chrome 18, this unpacked extension fails to load, displaying an error:
If I change 'unsafe-inline' to 'self', the extension loads fine, but alert() does not work, and the option page's console contains an error:
Refused to execute inline script because of Content-Security-Policy.
In Chrome 16, using 'unsafe-inline' lets the extension load fine and alert() works, too. However, in Chrome 16, replacing 'unsafe-inline' with 'foo' lets the extension load, but of course does not let alert() work, so perhaps Chrome 18 is stricter than 16, but...
Is default-src 'unsafe-inline' actually invalid, or is this a bug? What CSP value can I use to make alert() work in Chrome 18?
Based on the accepted answer below, inline scripts no longer work in extensions in Chrome 18. alert() will need to be placed in its own JavaScript file.
For recent versions of Chrome (46+), the previously accepted answer is no longer true. unsafe-inline still has no effect (in the manifest and in meta header tags), but per the documentation, you can use the technique described here to relax the restriction.
Hash usage for <script> elements
The script-src directive lets developers whitelist a particular inline script by specifying its hash as an allowed source of script.
Usage is straightforward. The server computes the hash of a particular script block’s contents, and includes the base64 encoding of that value in the Content-Security-Policy header:
Content-Security-Policy: default-src 'self';
script-src 'self' https://example.com 'sha256-base64 encoded hash'
Example
Consider the following:
manifest.json:
{
"manifest_version": 2,
"name": "csp test",
"version": "1.0.0",
"minimum_chrome_version": "46",
"content_security_policy": "script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='",
"background": {
"page": "background.html"
}
}
background.html:
<!DOCTYPE html>
<html>
<head></head>
<body>
<script>alert('foo');</script>
</body>
</html>
Result:
Further investigation
I also tested putting the applicable directive in a meta tag instead of the manifest. While the CSP indicated in the console message did include the content of the tag, it would not execute the inline script (in Chrome 53).
new background.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='">
</head>
<body>
<script>alert('foo');</script>
</body>
</html>
Result:
Appendix: Generating the hashes
Here are two methods for generating the hashes:
Python (pass JS to stdin, pipe it somewhere else):
import hashlib
import base64
import sys
def hash(s):
hash = hashlib.sha256(s.encode()).digest()
encoded = base64.b64encode(hash)
return encoded
contents = sys.stdin.read()
print(hash(contents))
In JS, using the Stanford Javascript Crypto Library:
var sjcl = require('sjcl');
// Generate base64-encoded SHA256 for given string.
function hash(s) {
var hashed = sjcl.hash.sha256.hash(s);
return sjcl.codec.base64.fromBits(hashed);
}
Make sure when hashing the inline scripts that the whole contents of the script tag are included (including all leading/trailing whitespace). If you want to incorporate this into your builds, you can use something like cheerio to get the relevant sections. Generically, for any html, you can do:
var $ = cheerio.load(html);
var csp_hashes = $('script')
.map((i, el) => hash($(el).text())
.toArray()
.map(h => `'sha256-${h}'`)
.join(' ');
var content_security_policy = `script-src 'self' 'unsafe-eval' ${csp_hashes}; object-src 'self'`;
This is the method used in hash-csp, a gulp plugin for generating hashes.
The following answer is true for older versions of Chrome (<46). For more recent ones, please check #Chris-Hunt answer https://stackoverflow.com/a/38554505/422670
I just posted a very similar answer for the question https://stackoverflow.com/a/11670319/422670
As is said, there's no way to relax the inline security policy in v2 extensions. unsafe-inline simply does not work, intentionally.
There really is no other way than moving all your javascript into js files and point to them with a <script src>.
There's, though, the option to do Eval and new Function inside a sandboxed iframe, for instance with the following lines in the manifest:
"sandbox": {
"pages": [
"page1.html",
"directory/page2.html"
]
},
A sandboxed page will not have access to extension or app APIs, or direct access to non-sandboxed pages (it may communicate with them via postMessage()). You can further restrict the sandbox rights with a specific CSP
There's now a full example from the Google Chrome team on the github eval in iframe on how to circumvent the problem by communicating with a sandboxed iframe, as well as a short analytics tutorial
Thanks to Google, there's a lot of extension rewriting in the lineup :(
EDIT
It is possible relax the security policy for REMOTE scripts. But not for inlines.
The policy against eval() and its relatives like setTimeout(String), setInterval(String), and new Function(String) can be relaxed by adding 'unsafe-eval' to your policy:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
However, we strongly recommend against doing this. These functions are notorious XSS attack vectors.
this appeared in the trunk documentation and is discussed in the thread "eval re-allowed"
inline scripts will not be back though:
There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includes 'unsafe-inline' will have no effect.
Hash usage for inline scripts is permitted in Content Security Policy Level 2. From the example in the spec:
Content-Security-Policy:
script-src 'sha512-YWIzOWNiNzJjNDRlYzc4MTgwMDhmZDlkOWI0NTAyMjgyY2MyMWJlMWUyNjc1ODJlYWJhNjU5MGU4NmZmNGU3OAo='
An alternative is the nonce, again from the examples:
Content-Security-Policy: script-src 'self' 'nonce-$RANDOM';
then
<script nonce="$RANDOM">...</script>
<script nonce="$RANDOM" src='save-because-nonce'></script>
These appears supported in Chrome 40+, but I am uncertain what luck one would have with other browsers at the moment.
Afaik, this is a bug.
"default-src 'self' https://ssl.google-analytics.com"
works, while
"default-src 'self' http://ssl.google-analytics.com"
doesnt.
It's really bleeding edge technology, check http://code.google.com/p/chromium/issues/detail?id=105796 for details.
Update: http://code.google.com/p/chromium/issues/detail?id=107538 refers to this issue.