[tor-bugs] #29347 [Obfuscation/meek]: Rewrite meek-http-helper as a WebExtension

Tor Bug Tracker & Wiki blackhole at torproject.org
Wed Feb 6 04:26:10 UTC 2019


#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


More information about the tor-bugs mailing list