Chrome 扩展将具有动态值的脚本注入到具有严格 CSP 的页面中
Chrome extension inject script with dynamic value into page with strict CSP
我正在创建隐私扩展,运行是 document_start 上的内容脚本。
内容脚本需要为每个不同的来源注入一个具有动态值的脚本,例如google.com、twitter.com等等等等
这是我的内容脚本:
console.log("Content Script Running ...");
console.log("Window origin: " + window.location.href);
function inject(filePath) {
var script = document.createElement('script');
script.src = chrome.extension.getURL(filePath);
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
}
function injectText(text) {
var script = document.createElement('script');
script.textContent = text;
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
}
function getSeed(origin) {
// Get a Storage object
var storage = window.sessionStorage;
// Do we already have a seed in storage for this origin or not?
var seed = storage.getItem(origin);
if (seed === null) {
// Initialise a 32 byte buffer
seed = new Uint8Array(32);
// Fill it with cryptographically random values
window.crypto.getRandomValues(seed);
// Save it to storage
storage.setItem(origin, seed);
}
return seed;
}
var origin = window.location.hostname;
var seed = getSeed(origin);
injectText("var seed = '" + seed + "';");
console.log("[INFO] Injected Seed ...");
inject("js/lib/seedrandom.min.js");
console.log("[INFO] Injected Seed Random ...");
inject("js/random.js");
console.log("[INFO] Injected Random ...");
inject("js/api/document.js");
console.log("[INFO] Injected Document API ...");
inject("js/api/navigator.js");
console.log("[INFO] Injected Navigator API ...");
inject("js/api/canvas.js");
console.log("[INFO] Injected Canvas API ...");
inject("js/api/history.js");
console.log("[INFO] Injected History API ...");
inject("js/api/battery.js");
console.log("[INFO] Injected Battery API ...");
inject("js/api/audio.js");
console.log("[INFO] Injected Audio API ...");
inject("js/api/element.js");
console.log("[INFO] Injected Element API ...");
在具有严格 CSP 的网站上尝试 运行 此扩展程序时,例如github.com,我的具有动态种子值的脚本被阻止,我的其他依赖于该值的脚本最终引用了一个未定义的值。关于如何解决这个问题的任何想法。
使用 src 属性加载的脚本是可以的,因为它们在 .js 文件中并且是从扩展中加载的,但是具有动态值 aka var seed = ... 的脚本被阻止,因为它被注入使用 textContent 属性。
我需要在页面上的任何其他脚本 运行 之前同步 运行 同步此代码,因此我在 document_start 上有内容脚本 运行。
有什么想法吗?
我解决了这个问题。我遇到的主要问题是试图注入具有以下内容的内联文本脚本:
var seed = $(value that changes depending on the page)
这会被某些具有限制性内容安全策略的网站阻止,例如 twitter.com 和 github.com。
我的解决方案是在内容脚本中执行以下操作:
var filePath = // Get filepath to script
var seed = // Get seed value in content script
var script = document.createElement('script');
script.setAttribute("data-seed", seed);
script.src = chrome.extension.getURL(filePath);
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
这将像这样在页面中创建一个脚本
<script data-seed="$(DATA-SEED-VALUE)" src="$(SRC-VALUE)"></script>
然后从现在 运行 作为页面脚本(在网页内容中)的脚本中:
var seed = document.currentScript.getAttribute("data-seed");
哪个得到种子。此解决方案更整洁、更简单,并且不需要更改 CSP,否则可能会为您正在交互的站点带来安全问题。
我正在创建隐私扩展,运行是 document_start 上的内容脚本。
内容脚本需要为每个不同的来源注入一个具有动态值的脚本,例如google.com、twitter.com等等等等
这是我的内容脚本:
console.log("Content Script Running ...");
console.log("Window origin: " + window.location.href);
function inject(filePath) {
var script = document.createElement('script');
script.src = chrome.extension.getURL(filePath);
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
}
function injectText(text) {
var script = document.createElement('script');
script.textContent = text;
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
}
function getSeed(origin) {
// Get a Storage object
var storage = window.sessionStorage;
// Do we already have a seed in storage for this origin or not?
var seed = storage.getItem(origin);
if (seed === null) {
// Initialise a 32 byte buffer
seed = new Uint8Array(32);
// Fill it with cryptographically random values
window.crypto.getRandomValues(seed);
// Save it to storage
storage.setItem(origin, seed);
}
return seed;
}
var origin = window.location.hostname;
var seed = getSeed(origin);
injectText("var seed = '" + seed + "';");
console.log("[INFO] Injected Seed ...");
inject("js/lib/seedrandom.min.js");
console.log("[INFO] Injected Seed Random ...");
inject("js/random.js");
console.log("[INFO] Injected Random ...");
inject("js/api/document.js");
console.log("[INFO] Injected Document API ...");
inject("js/api/navigator.js");
console.log("[INFO] Injected Navigator API ...");
inject("js/api/canvas.js");
console.log("[INFO] Injected Canvas API ...");
inject("js/api/history.js");
console.log("[INFO] Injected History API ...");
inject("js/api/battery.js");
console.log("[INFO] Injected Battery API ...");
inject("js/api/audio.js");
console.log("[INFO] Injected Audio API ...");
inject("js/api/element.js");
console.log("[INFO] Injected Element API ...");
在具有严格 CSP 的网站上尝试 运行 此扩展程序时,例如github.com,我的具有动态种子值的脚本被阻止,我的其他依赖于该值的脚本最终引用了一个未定义的值。关于如何解决这个问题的任何想法。
使用 src 属性加载的脚本是可以的,因为它们在 .js 文件中并且是从扩展中加载的,但是具有动态值 aka var seed = ... 的脚本被阻止,因为它被注入使用 textContent 属性。
我需要在页面上的任何其他脚本 运行 之前同步 运行 同步此代码,因此我在 document_start 上有内容脚本 运行。
有什么想法吗?
我解决了这个问题。我遇到的主要问题是试图注入具有以下内容的内联文本脚本:
var seed = $(value that changes depending on the page)
这会被某些具有限制性内容安全策略的网站阻止,例如 twitter.com 和 github.com。
我的解决方案是在内容脚本中执行以下操作:
var filePath = // Get filepath to script
var seed = // Get seed value in content script
var script = document.createElement('script');
script.setAttribute("data-seed", seed);
script.src = chrome.extension.getURL(filePath);
script.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
这将像这样在页面中创建一个脚本
<script data-seed="$(DATA-SEED-VALUE)" src="$(SRC-VALUE)"></script>
然后从现在 运行 作为页面脚本(在网页内容中)的脚本中:
var seed = document.currentScript.getAttribute("data-seed");
哪个得到种子。此解决方案更整洁、更简单,并且不需要更改 CSP,否则可能会为您正在交互的站点带来安全问题。