2017-08-21 3 views
1

Ich schreibe eine Privacy Extension, die erfordert, dass ich die User-Agent-Eigenschaft des Browsers alias navigator.userAgent spoof (ja, ich kenne bereits den User-Agent HTTP-Header und habe schon damit umgegangen) .Browser leckt immer noch Real User Agent

Mein Problem ist, dass eine Seite nicht nur einen Hauptrahmen sondern auch eine Variable über Iframes hat. In meiner Manifest-Datei verwende ich all_frames: true, um mein Inhaltsskript in alle Frames zu injizieren und match_about_blank: true, um Frames mit einer URL von "about: blank" einzufügen.

Ich benutze BrowserLeaks, um meine Erweiterung zu testen, es scheint den Benutzer-Agent korrekt mit der Fensteroption zu fälschen, aber bei Verwendung der iframe.contentWindow-Methode zeigt es den echten Benutzer-Agent.

Ich glaube, es könnte sein, weil der Iframe Sandboxed ist und Sie nicht in Sandboxed Iframes injizieren dürfen. Dies wäre ein großes Problem, da Websites Erweiterungen umgehen und ihnen den Zugriff auf einen Sandbox-Iframe verweigern könnten.

Dies ist der Fehler, den ich auf Chromium erhalten:

Blockierte Skriptausführung in ‚about: blank‘, weil der Rahmen des Dokuments Sandbox ist und die Genehmigung ist ‚allow-Skripte‘ nicht gesetzt.

Von Chrome Developer

match_about_blank:

Optional. Ob das Inhaltsskript in etwa eingefügt werden soll: blank und about: srcdoc. Inhaltsskripts werden nur auf Seiten eingefügt, wenn ihre vererbte URL mit einem der deklarierten Muster im Übereinstimmungsfeld übereinstimmt. Die vererbte URL ist die URL des Dokuments, das den Rahmen oder das Fenster erstellt hat. Inhaltsskripts können nicht in Sandbox-Rahmen eingefügt werden. Standardeinstellung ist false.

Oder vielleicht läuft das Skript in allen Iframes einschließlich der Sandboxed, aber das Skript läuft nicht schnell genug, d. H. Nicht run_at: document_start.

Von MDN

match_about_blank:

match_about_blank wird in Firefox ab Version 52 unterstützt Hinweis, dass in Firefox, Content-Skripte wird nicht in leere iframes bei "document_start" injiziert werden, auch wenn Sie diesen Wert angeben in run_at.

Mein Titel sagt Chrome-Erweiterung, aber es wird auch für Firefox sein. Ich habe Dokumentation sowohl von MDN als auch von Chrome gepostet, da ihre Formulierung anders ist. Auf Chrome, wenn ich dies auf sagen github.com teste ich bekomme Fehler in Bezug auf Sandboxing auf iframe aber auf Firefox bekomme ich keine Fehler, aber es spoof noch nicht die Eigenschaft innerhalb der iframe wie ich es will. Irgendwelche Ideen?

manifest.json

{ 
    "name": "Shape Shifter", 
    "version": "0.0.1", 
    "description": "Anti browser fingerprinting web extension. Generates randomised values for HTTP request headers and javascript API's.", 
    "manifest_version": 2, 
    "icons": { 
     "16": "icons/crossed_eye_16x16.png", 
     "32": "icons/crossed_eye_32x32.png", 
     "48": "icons/crossed_eye_48x48.png", 
     "128": "icons/crossed_eye_128x128.png" 
    }, 
    "background": { 
     "persistent": true, 
     "scripts": ["js/background.js"] 
    }, 
    "browser_action": { 
     "default_title": "Shape Shifter", 
     "default_icon": { 
      "16": "icons/crossed_eye_16x16.png", 
      "32": "icons/crossed_eye_32x32.png" 
     }, 
     "default_popup": "html/popup.html" 
    }, 
    "content_scripts": [ 
     { 
      "all_frames": true, 
      "match_about_blank": true, 
      "run_at": "document_end", 
      "matches": ["<all_urls>"], 
      "js": ["js/inject.js"] 
     } 
    ], 
    "permissions": [ 
     "webRequest", 
     "webRequestBlocking", 
     "<all_urls>" 
    ], 
    "web_accessible_resources": [ 
     "js/lib/seedrandom.min.js", 
     "js/random.js", 
     "js/api/document.js", 
     "js/api/navigator.js", 
     "js/api/canvas.js", 
     "js/api/history.js", 
     "js/api/battery.js", 
     "js/api/audio.js", 
     "js/api/element.js" 
    ] 
} 

inject.js (My Content-Skript)

console.log("Content Script Running ..."); 

function inject(filePath, seed) { 
    // Dynamically create a script 
    var script = document.createElement('script'); 

    // Give the script a seed value to use for spoofing 
    script.setAttribute("data-seed", seed); 

    // Give the script a url to the javascript code to run 
    script.src = chrome.extension.getURL(filePath); 

    // Listen for the script loading event 
    script.onload = function() { 
    // Remove the script from the page so the page scripts don't see it 
    this.remove(); 
    }; 

    // Add the script tag to the DOM 
    (document.head || document.documentElement).appendChild(script); 
} 

function getSeed(origin) { 
    // Get a Storage object 
    var storage = window.sessionStorage; 

    // Try to get a seed from sessionStorage 
    var seed = storage.getItem(origin); 

    // Do we already have a seed in storage for this origin or not? 
    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 seed = getSeed(window.location.hostname); 

inject("js/lib/seedrandom.min.js", seed); 
console.log("[INFO] Injected Seed Random ..."); 

inject("js/random.js", seed); 
console.log("[INFO] Injected Random ..."); 

inject("js/api/document.js", seed); 
console.log("[INFO] Injected Document API ..."); 

inject("js/api/navigator.js", seed); 
console.log("[INFO] Injected Navigator API ..."); 

inject("js/api/canvas.js", seed); 
console.log("[INFO] Injected Canvas API ..."); 

inject("js/api/history.js", seed); 
console.log("[INFO] Injected History API ..."); 

inject("js/api/battery.js", seed); 
console.log("[INFO] Injected Battery API ..."); 

inject("js/api/audio.js", seed); 
console.log("[INFO] Injected Audio API ..."); 

inject("js/api/element.js", seed); 
console.log("[INFO] Injected Element API ..."); 
+0

Wenn Sie eine Seite Objekt fälschen Sie eine Seite Skript ausführen, kein Content-Skript, weshalb die iframe Sandbox Einschränkungen gelten. Ich denke, du kannst nichts dagegen tun. – wOxxOm

+0

@wOxxOm Das ist wirklich bedauerlich. Wenn also eine Seite den tatsächlichen Wert des Benutzeragenten abrufen möchte, kann sie nur einen iframe-Sandkasten erstellen, und dann kann meine Erweiterung nichts dagegen tun. Das macht meine Verlängerung sinnlos. Gibt es keinen Weg dazu? Zuvor mit alten Firefox-Addons konnten Sie einfach den userAgent-Präferenzwert setzen, aber mit den neuen Web-Erweiterungen können Sie dies nicht mehr tun. Ich denke, eine Privacy-Erweiterung mit Web-Erweiterungen wird ein Albtraum sein. – Snapper26

+0

Bitte bearbeiten Sie die Frage zum Thema: fügen Sie ein [mcve] ein, das das Problem dupliziert. Bei Chrome-Erweiterungen oder Firefox-WebExtensions bedeutet dies fast immer, dass Sie * manifest.json * und einige der Hintergrund-, Inhalts- und/oder Popup-Skripts/HTML einfügen. Fragen, die Debugging-Hilfe suchen ("Warum funktioniert dieser Code nicht so, wie ich will?") ​​Muss Folgendes enthalten: (1) das gewünschte Verhalten, (2) ein spezifisches Problem oder einen Fehler und (3) den kürzesten Code, der für die Reproduktion erforderlich ist * in der Frage selbst *. Bitte beachten Sie auch: [Was kann ich hier fragen?] (Http://stackoverflow.com/help/on-topic) und [fragen]. – Makyen

Antwort

0

ich in der Lage war um diese Probleme in der folgenden Art und Weise zu erhalten:

Von meinem Content-Skript ...

var UAScript = "document.addEventListener('DOMContentLoaded', function(event) { var iFrames = document.getElementsByTagName('iframe'); "+ 
       "for (i=0; i<iFrames.length; i++) try { Object.defineProperty(iFrames[i].contentWindow.clientInformation, 'userAgent', { value:'Custom' }); } catch(e) {} }); "+ 
       "try { Object.defineProperty(clientInformation, 'userAgent', { value:'Custom' }); } catch(e) {}"; 
var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.textContent = UAScript; 
document.documentElement.appendChild(script); 

Dies ändert sich sowohl die Useragent auf dem Dokument sowie die iFrames nach dem DOMContentLoaded auslöst.

Frage ist ..., gibt es eine bessere Möglichkeit, dies zu tun?

(Weil Sie durch Hinzufügen eines iframe in einem Iframe um diese Parodie immer noch kann, etc.)