繁体   English   中英

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,而CSP可能会为您与之交互的站点造成安全问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM