Modifying content-security-policy response headers using declarativeNetRequest and Manifest V3 - content-security-policy

I am trying to upgrade a Chrome extension to Manifest V3. Our current application makes use of webRequest and webRequestBlocking to modify the content-security-policy directives in order to inject resources from another application into a frame.
Since webRequestBlocking is no longer supported in Manifest V3, I have been trying to utilize declarativeNetRequest to modify the response headers, but keep running into the following errors:
Refused to send form data to 'https://securesite.com' because it violates the following Content Security Policy directive: "form-action 'self' *.example.com".
Refused to frame 'https://securesite.com' because it violates the following Content Security Policy directive: "frame-src 'self' *.example.com".
I have tried to operations "append", "set", and "remove" and have not had success with any. I also do see that the rules are being trigger onRuleMatchedDebug. Any insight would be helpful!
manifest.json
{
"manifest_version": 3,
"permissions": [
"activeTab",
"webRequest",
"declarativeNetRequest",
"browsingData",
"storage",
"tabs",
"scripting"
],
"host_permissions": [
"http://*/*",
"https://*/*"
],
"declarative_net_request": {
"rule_resources": [{
"id": "csp_rules",
"enabled": true,
"path": "cspRules.json"
}]
},
"background": {
"service_worker": "background.js"
}
}
cspRules.json
[
{
"id": 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"responseHeaders": [
{
"header": "content-security-policy",
"operation": "append",
"value": "script-src https://securesite.com http://localhost:3000; style-src https://secure.alphasights.com http://localhost:3000; img-src https://secure.alphasights.com http://localhost:3000; form-action https://secure.alphasights.com http://localhost:3000; frame-src https://secure.alphasights.com http://localhost:3000; connect-src https://secure.alphasights.com http://localhost:3000"
}
]
},
"condition": {
"urlFilter": "example.com",
"resourceType": ["main_frame", "sub_frame"]
}
}
]

I think you also need to specify the "domain" property that tells the browser which site you are setting the rule for.

Related

Why is the background script not loading on Firefox add-on (works on Chrome)?

I'm developing a cross-browser extension which works in Chrome but not in Firefox - the background script is not loading.
I tried console.log in background.js and sending a message to the content script and logging message there.
background.js
browser.action.onClicked.addListener(async function (tab) {
console.log("clicked on extension icon");
browser.tabs.sendMessage(tab.id, { text: "toggle_overlay" })
});
js/content.js
...
browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
console.log("message received", msg)
});
Content script works as expected on all code that's not depended on background.js
Folder structure
manifest.json (had to downgrade to v2 because Firefox doesn't support v3 yet)
{
"name": "Dev Mode",
"description": "Dev Mode",
"version": "0.0.1",
"manifest_version": 2,
"icons": {
"16": "./imgs/icon-16-dark.png",
"48": "./imgs/icon-48.png",
"128": "./imgs/icon-128.png"
},
"permissions": [
"activeTab",
"contextMenus",
"bookmarks",
"scripting",
"storage",
"<all_urls>"
],
"background": {
"scripts": ["background.js"],
"persistent": false // <-- also tried without, same result - background script doesn't lod
},
"browser_action": {
"default_icon": "./imgs/icon-16-dark.png",
"default_title": "Default Title"
},
"commands": {
"save-page": {
"suggested_key": {
"default": "Ctrl+Shift+S",
"mac": "Command+Shift+S"
},
"description": "some description"
}
},
"content_security_policy": "script-src 'self'; object-src 'self'; sandbox allow-scripts; script-src 'self' https://apis.google.com https://www.gstatic.com https://www.googleapis.com https://securetoken.googleapis.com; object-src 'self'",
"web_accessible_resources": [ "imgs/*.png", "overlay.html"],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"/js/content.js"
],
"run_at": "document_end",
"all_frames": false
}
]
}
I'm testing the Firefox extension with web-ext run to test the extension locally.
The correct API for this in Manifest v2 is browserAction instead of action that is only available in MV3.
So to fix it, in your background.js, switch to
browser.browserAction.onClicked.addListener
browser.action in Firefox is available in MV3. Your extension uses MV2 i.e. "manifest_version": 2,
Note: This API is available in Manifest V3 or higher.
Note: MV3 support is very limited in Firefox at the moment.

Chrome Extension - declarativeNetRequest remove requestHeader "origin" not working

I am trying to remove requestHeader 'origin' using declarativeNetRequest. It's not working as the origin is still being sent with SharePoint rest api call. How do we ensure the rule is being triggered or not? How can we troubleshoot the issue?
Here is my manifest.json and rules.json
{
"short_name": "SPO Helper",
"name": "SPO Helper",
"icons": {
"16": "favicon.ico",
"48": "logo192.png",
"128": "logo512.png"
},
"manifest_version": 3,
"version": "0.0.1",
"background": {
"service_worker": "./static/js/background.js"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content.js"
],
"all_frames": false,
"run_at": "document_end"
}
],
"action": {
"default_title": "SPO Helper"
},
"declarative_net_request": {
"rule_resources": [
{
"id": "ruleset_1",
"enabled": true,
"path": "./rules.json"
}
]
},
"permissions": [
"tabs",
"activeTab",
"cookies",
"scripting",
"declarativeNetRequest",
"declarativeNetRequestFeedback"
],
"host_permissions": [
"https://*.sharepoint.com/"
],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
}
rules.json
[
{
"id": 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{
"header": "origin",
"operation": "remove"
}
]
},
"condition" : {
"domains": ["cbgbfoeehbjllcimibeojmpgeoncgjcl"],
"resourceTypes" : ["main_frame", "sub_frame"]
}
}
]
using onRuleMatchedDebug you can check if your rule is being triggered.
you must add the declarativeNetRequestFeedback permission in your manifest.json and add this in your service worker:
chrome.declarativeNetRequest.onRuleMatchedDebug.addListener(function (o) {
console.log('rule matched:', o);
});

Refused to load the script: https://apis.google.com/js/api.js

I'm trying to implement firebase authentication for a chrome extension. I can sign in using email and password, but I can't get the social logins to work (google and facebook)
here is the error message:
Refused to load the script 'https://apis.google.com/js/api.js?onload=__iframefcb541553' because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem: chrome-extension-resource:". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
manifest.json
{
"manifest_version": 2,
"name": "...",
"description": "...",
"version": "0.0.0.1",
"icons": {},
"background": {
"scripts": [
"event.js"
],
"persistent": true
},
"permissions": ["tabs", "https://*/*","activeTab"],
"browser_action": {
"default_title": "...",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"css": [],
"js": ["content.js"]
}
],
"content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self';"
}
signin
handleSocialLogin(provider) {
return () => {
auth
.signInWithPopup(provider)
.then(user => {
this.props.onUserChange(user)
localStorage.setItem('user', JSON.stringify(user))
})
.catch(error => this.setState({ error }))
}
}

Extension refused to load the font in manifest.json.1

Following is my manifest.json:
{
"name": "gitvote",
"version": "1.0",
"manifest_version": 2,
"description": "for git vote",
"icons": {
"128": "icons/icon.png"
},
"permissions": [
"https://github.com/*",
"https://gitlab.com/*",
"storage"
],
"optional_permissions": [
"<all_urls>"
],
"background": {
"scripts": [ "background.js" ],
"persistent": false
},
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}
When I run it as a chrome extension, an error:
'Refused to load the font 'data:font/woff;base64,d09GRgABAAAAAJd6ABIAAAABdegAAAAAAACWIAAAAVoAAAKDAAAAA…SYUnjpYfcSDw49uhYFPVe8dHZcYGS7Cfk4MMJ7zwjznvGw3PMA2Oo6+tf/wpSdPlSR/ADe7uPx' because it violates the following Content Security Policy directive: "font-src assets-cdn.github.com".' in manifest.json.1 occurs.
I don't understand why the error occurs in manifest.json.1.
Thank you.

Unchecked runtime.lastError while running tabs.executeScript: Cannot access contents of url "data:text/html,chromewebdata"

I'm getting this error:
extensions::lastError:133 Unchecked runtime.lastError while running tabs.executeScript: Cannot access contents of url "data:text/html,chromewebdata". Extension manifest must request permission to access this host.
I'm getting this error after disabling internet so that I can take action when the page load fails(due to heavy load) or internet down.
I've checked all similar questions and this almost similar but still unable to make it work. Another very similar one with comment that Chrome does not allow hijack of internal pages
My permissions looks like:
"permissions": [
"tabs","unlimitedStorage", "notifications", "history", "activeTab", "storage", "webRequest", "webRequestBlocking", "*://*/*", "http://*/*", "https://*/*"
],
I get the error when I run this code:
chrome.tabs.executeScript(null, {file: "showbacklink.js"});
or
chrome.tabs.executeScript(details.tabId, {file: "showbacklink.js"});
where details.tabId is the active tab.
What am I missing?
Edited manifest.json
{
"name": "",
"options_page": "options.html",
"description": "",
"version": "1.0",
"icons": {
"16": "icons/logo16.png",
"48": "icons/logo48.png",
"128": "icons/logo128.png"
},
"permissions": [
"tabs","unlimitedStorage", "notifications", "history", "activeTab", "storage", "webRequest", "webRequestBlocking", "http://*/*", "https://*/*"
],
"background": {
"scripts": [
"showbacklink.js",
"client_server_common.js",
"common.js",
"background.js"
],
"persistent": true
},
"content_security_policy": "script-src 'self'; object-src 'self'",
"manifest_version": 2,
"content_scripts": [
{
"run_at": "document_end",
"all_frames": true,
"matches": ["https://*/*"],
"css": [//REMOVED],
"js": [ //other files REMOVED
"myscript.js",
]
},
],
"web_accessible_resources": [ //REMOVED
]
}
Indeed, the "Offline" page, or any other error page shown is treated as a Chrome internal page instead of its "original" URL. As such, you can't inject into such pages to change them for security reasons. Imagine for a moment that an extension would be able to interact with SSL warning pages - you really, really don't want that.
If your goal is to provide some sort of alternative error page, you need to hook a listener for such navigation errors and redirect to your own page.
I would recommend looking at webNavigation and webRequest API.

Resources