I am building one chrome extension which uses a JavaScript library customized to a specific web domain. It is a restriction of that library to be called only from that specific domain (license issues actually).
I want to load that js library into my chrome extension, but the extension gives a Content Security Policy error as the library to be used comes from a HTTP (not HTTPS) URL. I searched StackOverflow for this and the only options I see are either to load that file locally or through message passing.
Can someone please tell what code should I have in my background.js and content.js and what permission to add in my manifest.json?
The website to get that js library is, e.g., http://library.com/js/xy.js.
I know there should be something else like some piece of code in content.js. How can I load the code from that domain?
manifest.json:
{
"manifest_version": 2,
"name": "abc",
"version": "0.2",
"description": "abc",
"content_security_policy": "script-src 'self'; object-src 'self'",
"browser_action": {
"default_icon": "MM_logo_2009.png",
"default_popup": "tab/popup.html"
},
"background": {
"scripts": ["event.js"],
"persistent": false
},
"permissions": [
"http://library.com/js/xy.js",
"bookmarks",
"tabs",
"storage",
"http://*/*",
"https://*/*"
]
}
event.js:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://library.com/js/xy.js", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// innerText does not let the attacker inject HTML elements.
document.getElementById("resp").innerText = xhr.responseText;
}
}
xhr.send();
If this is really the only way you can do this (loading code over HTTP), then you have to resort to allowing eval:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
and then
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://library.com/js/xy.js", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
eval(xhr.responseText);
}
}
xhr.send();
Since it's HTTP, there is no guarantee whatsoever of the identity of the sender or the integrity of the script.
Don't be surprised if this code gets rejected by Chrome Web Store!
Fortunately, there is a way to at least partially mitigate the risk.
There's even a whole guide on it in the docs, "Using eval in Chrome Extensions. Safely."
You then do the same, but in a sandboxed page (e.g., an <iframe> in your event/background page), and communicate with it using postMessage. This way, you can validate the communication and not provide any direct access to extension API for the code being evaluated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With