#29347: Rewrite meek-http-helper as a WebExtension ------------------------------+-------------------------- Reporter: dcf | Owner: dcf Type: enhancement | Status: assigned Priority: Medium | Milestone: Component: Obfuscation/meek | Version: Severity: Normal | Resolution: Keywords: webextension | Actual Points: Parent ID: | Points: Reviewer: | Sponsor: ------------------------------+--------------------------
Comment (by dcf): The basic domain fronting option seems to be possible. You can't override the Host header in a [https://developer.mozilla.org/en- US/docs/Web/API/Fetch_API fetch] or [https://developer.mozilla.org/en- US/docs/Glossary/XHR_(XMLHttpRequest) XMLHttpRequest] because Host is a [https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name forbidden header name]. I tried it, and any changes I made to Host were silently ignored. However you can set Host in [https://developer.mozilla.org/en-US/docs/Mozilla/Add- ons/WebExtensions/API/webRequest/onBeforeSendHeaders webRequest.onBeforeSendHeaders], at least in Firefox 65, on which I was testing. The following extension prints out the expected "I’m just a happy little web server." in the `--jsconsole`. manifest.json {{{ { "manifest_version": 2, "name": "Domain fronting demo", "version": "1.0", "background": { "scripts": ["main.js"] }, "permissions": [ "https://*/*", "webRequest", "webRequestBlocking" ] } }}} main.js {{{ // https://developer.mozilla.org/en-US/docs/Mozilla/Add- ons/WebExtensions/API/webRequest/onBeforeSendHeaders browser.webRequest.onBeforeSendHeaders.addListener( function(details) { let requestHeaders = details.requestHeaders.filter( h => h.name.toLowerCase() !== "host" ); requestHeaders.push({name: "Host", value: "meek.azureedge.net"}); return {requestHeaders: requestHeaders}; }, {"urls": ["*://*/*"]}, ["blocking", "requestHeaders"] ); // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch let resp = fetch("https://ajax.aspnetcdn.com/") .then(resp => resp.text()) .then(text => console.log(text)); }}} It's a bit awkward because the listeners like `onBeforeSendHeaders` are global, not belonging to any single request. Ideally the extension will be able to handle different Host headers for different requests: we need a way to communicate from the outer code where we call `fetch` to the inner code where we modify the header. One way to do this would be to encode any per-request settings in a magic header or other metadata, which we strip and interpret in the callback. Another way would be to put a lock around the whole `fetch`–`onBeforeSendHeaders` so that there can only be one in progress at a time, and use a global variable as shared memory. I don't think it would hurt performance because `onBeforeSendHeaders` is called before anything hits the network; i.e., it should happen almost immediately after `fetch` and then we can release the lock. -- Ticket URL: <https://trac.torproject.org/projects/tor/ticket/29347#comment:2> Tor Bug Tracker & Wiki <https://trac.torproject.org/> The Tor Project: anonymity online
_______________________________________________ tor-bugs mailing list tor-bugs@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-bugs