mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 06:44:13 +00:00
Modifying content security policy
This commit is contained in:
parent
4008e1811c
commit
7d4c6e926e
6 changed files with 76 additions and 4 deletions
9
browser-extension/package-lock.json
generated
9
browser-extension/package-lock.json
generated
|
@ -15918,6 +15918,15 @@
|
|||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
|
||||
},
|
||||
"rewire": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rewire/-/rewire-4.0.1.tgz",
|
||||
"integrity": "sha512-+7RQ/BYwTieHVXetpKhT11UbfF6v1kGhKFrtZN7UDL2PybMsSt/rpLWeEUGF5Ndsl1D5BxiCB14VDJyoX+noYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint": "^4.19.1"
|
||||
}
|
||||
},
|
||||
"rgb-regex": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
"enzyme-adapter-react-16": "^1.14.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^24.8.0",
|
||||
"rewire": "^4.0.1",
|
||||
"sinon": "^7.3.2",
|
||||
"style-loader": "^0.23.1",
|
||||
"web-ext-webpack-plugin": "github:hiikezoe/web-ext-webpack-plugin",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'webextension-polyfill';
|
||||
import {MESSAGE_TYPES} from './app/commons/postMan';
|
||||
import {MESSAGE_TYPES} from '../app/commons/postMan';
|
||||
import normalizeUrl from 'normalize-url';
|
||||
import {processCSPHeader} from './utils';
|
||||
|
||||
chrome.browserAction.onClicked.addListener(activeTab => {
|
||||
const newURL = chrome.runtime.getURL(`/app/index.html?url=${activeTab.url}`);
|
||||
|
@ -13,7 +14,15 @@ function onHeadersReceived(details) {
|
|||
console.log('currentUrls', currentUrls, details.url, details.responseHeaders && currentUrls[details.url], details.responseHeaders, currentUrls[details.url]);
|
||||
const normalizedUrl = normalizeUrl(details.url);
|
||||
if (details.responseHeaders && currentUrls[normalizedUrl]) {
|
||||
const newHeaders = removeHeader(details.responseHeaders, 'X-Frame-Options');
|
||||
const extensionURL = chrome.runtime.getURL('/');
|
||||
const CSPHeader = getHeader(details.responseHeaders, 'Content-Security-Policy');
|
||||
const newCSPHeaderValue = processCSPHeader(CSPHeader, extensionURL);
|
||||
let newHeaders = removeHeader(details.responseHeaders, 'Content-Security-Policy');
|
||||
newHeaders = addHeader(newHeaders, 'Content-Security-Policy', newCSPHeaderValue);
|
||||
newHeaders = removeHeader(newHeaders, 'X-Frame-Options');
|
||||
/*console.log('After X-frameOptions removal', newHeaders)
|
||||
newHeaders = addHeader(newHeaders, 'x-frame-options', `allow-from ${extensionURL}`)
|
||||
*/
|
||||
console.log('newHeaders', newHeaders);
|
||||
return { responseHeaders: newHeaders };
|
||||
}
|
||||
|
@ -25,10 +34,21 @@ function removeHeader(headers, headerToRemove) {
|
|||
return headers.filter(({ name }) => name.toLowerCase() != headerToRemove);
|
||||
}
|
||||
|
||||
function addHeader(headers, name, value) {
|
||||
headers.push({name, value});
|
||||
return headers;
|
||||
}
|
||||
|
||||
function getHeader(headers, headerToFind) {
|
||||
headerToFind = headerToFind.toLowerCase();
|
||||
return headers.filter(({name}) => name.toLowerCase() === headerToFind)[0];
|
||||
}
|
||||
|
||||
chrome.webRequest.onHeadersReceived.addListener(
|
||||
onHeadersReceived,
|
||||
{
|
||||
urls: ["<all_urls>"],
|
||||
types: ["main_frame", "sub_frame"]
|
||||
},
|
||||
['blocking', 'responseHeaders']
|
||||
);
|
15
browser-extension/src/background/utils.js
Normal file
15
browser-extension/src/background/utils.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
export function processCSPHeader(header, extensionURL) {
|
||||
const defaultFrameAccessor = `frame-ancestors ${extensionURL}`;
|
||||
if (!header || !header.value) {
|
||||
return defaultFrameAccessor;
|
||||
}
|
||||
const directives = header.value.split(';').map(value => value.trim()).filter(value => value.length);
|
||||
const frameAccessorDirective = directives.filter(directive => directive.indexOf('frame-ancestors') === 0)[0];
|
||||
if (!frameAccessorDirective) {
|
||||
return [...directives, defaultFrameAccessor].join('; ');
|
||||
}
|
||||
const frameAccessorDirectiveValues = frameAccessorDirective.split(' ').map(value => value.trim()).filter(value => value.length);
|
||||
frameAccessorDirectiveValues.push(extensionURL);
|
||||
const nonFrameAccessorDirectives = directives.filter(directive => directive.indexOf('frame-ancestors') === -1);
|
||||
return [...nonFrameAccessorDirectives, frameAccessorDirectiveValues.join(' ')].join('; ');
|
||||
}
|
27
browser-extension/src/background/utils.test.js
Normal file
27
browser-extension/src/background/utils.test.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import {expect} from 'chai';
|
||||
import {processCSPHeader} from './utils';
|
||||
|
||||
describe('background/utils', () => {
|
||||
describe('processCSPHeader', () => {
|
||||
const extensionURL = 'chrome-extension://ahichoemcjmdgdojboecnokgfolkmfmo/';
|
||||
|
||||
it('should return the frame-accessor director if the response header is null', () => {
|
||||
const result = processCSPHeader(null, extensionURL);
|
||||
expect(result).to.be.equals(`frame-ancestors ${extensionURL}`);
|
||||
});
|
||||
|
||||
it('should return the frame-accessor directive in addition to the existing directives', () => {
|
||||
const oldValue = "default-src 'self';"
|
||||
const result = processCSPHeader({name: 'Content-Security-Policy', value: oldValue}, extensionURL);
|
||||
expect(result).to.be.equals(`${oldValue} frame-ancestors ${extensionURL}`);
|
||||
});
|
||||
|
||||
it('should append the current source the existing frame-accessor directive', () => {
|
||||
const oldValue = "upgrade-insecure-requests; frame-ancestors 'self' https://stackexchange.com"
|
||||
const result = processCSPHeader({name: 'Content-Security-Policy', value: oldValue}, extensionURL);
|
||||
expect(result).to.be.equals(`${oldValue} ${extensionURL}`);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
@ -4,7 +4,7 @@ const path = require('path');
|
|||
|
||||
module.exports = {
|
||||
entry: {
|
||||
background: ['./src/background.js'],
|
||||
background: ['./src/background'],
|
||||
app: ['./src/app/index.js']
|
||||
},
|
||||
output: {
|
||||
|
@ -32,7 +32,7 @@ module.exports = {
|
|||
options: {
|
||||
modules: {
|
||||
mode: 'local',
|
||||
localIdentName: '[path][name]__[local]--[hash:base64:5]',
|
||||
localIdentName: '[name]__[local]--[hash:base64:5]',
|
||||
},
|
||||
/* importLoaders: 1,
|
||||
sourceMap: true,
|
||||
|
|
Loading…
Reference in a new issue