mirror of https://github.com/keeweb/keeweb
tightened content security policy to prevent browser extension from adding scripts to KeeWeb
parent
5f4f007b31
commit
dcc477acbc
|
@ -8,7 +8,7 @@
|
|||
content="
|
||||
default-src 'self';
|
||||
font-src data:;
|
||||
script-src 'self' blob: 'unsafe-eval';
|
||||
script-src 'self' 'unsafe-eval';
|
||||
style-src 'self' blob:;
|
||||
connect-src 'self' ws: https:;
|
||||
child-src 'self' blob:;
|
||||
|
|
|
@ -373,25 +373,27 @@ class Plugin extends Model {
|
|||
};
|
||||
text = `(function(require, module){${text}})(window["${jsVar}"].require,window["${jsVar}"].module);`;
|
||||
const ts = this.logger.ts();
|
||||
const blob = new Blob([text], { type: 'text/javascript' });
|
||||
const objectUrl = URL.createObjectURL(blob);
|
||||
const elId = 'plugin-js-' + name;
|
||||
const el = this.createElementInHead('script', elId, {
|
||||
src: objectUrl
|
||||
});
|
||||
el.addEventListener('load', () => {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
setTimeout(() => {
|
||||
delete global[jsVar];
|
||||
if (this.module.exports.uninstall) {
|
||||
this.logger.debug('Plugin script installed', this.logger.ts(ts));
|
||||
this.loadPluginSettings();
|
||||
resolve();
|
||||
} else {
|
||||
reject('Plugin script installation failed');
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
||||
// Note that here we're calling eval to run the plugin code,
|
||||
// previously it was loaded as 'blob:' scheme (see the code below), however:
|
||||
// 1. we need to have eval enabled in our CSP anyway for WASM,
|
||||
// see https://github.com/WebAssembly/content-security-policy/issues/7
|
||||
// 2. we would like to prevent Chrome extensions from injecting scripts to our page,
|
||||
// which is possible to do if we have 'blob:', but they can't call eval
|
||||
// Previous implementation with 'blob:' can be found in git, if we ever need to restore it.
|
||||
|
||||
// eslint-disable-next-line no-eval
|
||||
eval(text);
|
||||
setTimeout(() => {
|
||||
delete global[jsVar];
|
||||
if (this.module.exports.uninstall) {
|
||||
this.logger.debug('Plugin script installed', this.logger.ts(ts));
|
||||
this.loadPluginSettings();
|
||||
resolve();
|
||||
} else {
|
||||
reject('Plugin script installation failed');
|
||||
}
|
||||
}, 0);
|
||||
} catch (e) {
|
||||
this.logger.error('Error installing plugin script', e);
|
||||
reject(e);
|
||||
|
|
|
@ -41,12 +41,12 @@ module.exports = function (grunt) {
|
|||
|
||||
let htmlStr = html.toString('latin1');
|
||||
for (const [type, digests] of Object.entries(hashes)) {
|
||||
const cspIndex = htmlStr.indexOf(`${type}-src`);
|
||||
const cspIndex = htmlStr.indexOf(`${type}-src 'self'`);
|
||||
if (cspIndex < 0) {
|
||||
grunt.warn(`Not found: ${type}-src`);
|
||||
}
|
||||
const digestsList = digests.map((digest) => `'${algo}-${digest}'`).join(' ');
|
||||
htmlStr = htmlStr.replace(`${type}-src`, `${type}-src ${digestsList}`);
|
||||
htmlStr = htmlStr.replace(`${type}-src 'self'`, `${type}-src ${digestsList}`);
|
||||
}
|
||||
|
||||
grunt.log.writeln(
|
||||
|
|
|
@ -8,6 +8,7 @@ Release notes
|
|||
`+` better Touch ID error messages
|
||||
`-` legacy auto-type removed
|
||||
`-` fixed a crash after disabling USB devices on Linux
|
||||
`+` tightened content security policy
|
||||
|
||||
##### v1.17.6 (2021-04-09)
|
||||
`+` team drives support in Google Drive
|
||||
|
|
Loading…
Reference in New Issue