diff --git a/app/index.html b/app/index.html
index f556a310..a20ffa13 100644
--- a/app/index.html
+++ b/app/index.html
@@ -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:;
diff --git a/app/scripts/plugins/plugin.js b/app/scripts/plugins/plugin.js
index 71ec2f28..9787e4a8 100644
--- a/app/scripts/plugins/plugin.js
+++ b/app/scripts/plugins/plugin.js
@@ -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);
diff --git a/build/tasks/grunt-csp-hashes.js b/build/tasks/grunt-csp-hashes.js
index 1e05982d..fa49889d 100644
--- a/build/tasks/grunt-csp-hashes.js
+++ b/build/tasks/grunt-csp-hashes.js
@@ -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(
diff --git a/release-notes.md b/release-notes.md
index 2cc5f6dd..9c633fe0 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -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