[tor-dev] Browser-based proxies for circumvention

David Fifield david at bamsoftware.com
Thu Dec 22 18:30:00 UTC 2011

On Wed, Dec 21, 2011 at 11:37:21PM -0800, Jacob Appelbaum wrote:
> On 12/21/2011 09:31 PM, David Fifield wrote:
> > This is our overview and demo page. Down at the bottom of the page is a
> > flash proxy badge.
> > 	https://crypto.stanford.edu/flashproxy/
> > 
> > It's called a "flash proxy," and the implementation happens to be in
> > Flash, but the "flash" should rather make you think "quick." I'm pretty
> > sure the same thing can be done with WebSockets or other technologies.
> > 
> That was my read at first - has anyone tried the basic concept with
> WebSockets?

Thank you for giving it a try! That means a lot to me.

No one has tried it, as far as I know. The only vaguely tricky part is
that you need a shim at both ends to convert the WebSocket into a normal
socket. On the client side, we would build it into the connector. On the
relay side, there would have to be some tiny proxy to receive the
WebSocket connection and forward it to Tor. A similar shim is needed
when using Flash sockets--you have to serve a "crossdomain policy" or
Flash will refuse to connect. connector.py and crossdomain.py do this.

> > == Howto
> > 
> > You can easily but slightly artificially test the flash proxy transport
> > with this command:
> > 	$ tor UseBridges 1 Bridge Socks4Proxy tor-facilitator.bamsoftware.com:9999
> > (Make sure a flash proxy is running somewhere, and wait about 30 seconds
> > for a connection.) What's artificial about this example is that the
> > service at tor-facilitator.bamsoftware.com:9999 (the "connector") is
> > something you would normally run on your own computer. We run one on the
> > Internet for the ease of demos like this. See the instructions in the
> > README for how to test it more realistically.
> > 
> That worked for me as expected:
> Dec 21 23:29:08.000 [notice] new bridge descriptor '3VXRyxz67OeRoqHn'
> (fresh): $7C03D29CA58BE8EED5F483F31A2DEDF6FD7CC444~3VXRyxz67OeRoqHn at

Something I should mention is that the "" actually has no
meaning in this case. You can substitute any address. The connector,
acting as a SOCKS proxy, is going to throw that address away and you get
connected to wherever you get connected to--the local Tor just thinks
that the bridge is at

> Thanks for ensuring that this works with Free Software!
> > == Architecture
> > 
> > Most of the architecture is dictated by a limitation of web socket
> > technologies, namely that they can only make outgoing TCP connections,
> > and cannot receive connections. This leads to a funny model where the
> > proxy connects to the client, instead of the other way around.
> > 
> This all reduces to a very time limited set of bridges - they provide
> availability and nothing more.

Yes, that's a good way to think about it. Rather than creating new
full-fledged bridges, we create disposable addresses by which they may
be accessed.

> > A sample session goes like this:
> > 1. The user starts a connector and a Tor client. The connector sends its
> >    address to the facilitator, so that a proxy will know where to
> >    connect to. (We call this step "rendezvous.")
> > 2. A flash proxy appears in a browser and asks the facilitator for an
> >    address.
> > 3. The facilitator sends a remembered client address to the proxy.
> > 4. The proxy connects to the client address. The client's connector
> >    receives the connection.
> > 5. The proxy connects to a Tor relay, then begins copying data between
> >    its two sockets.
> Where is the list of all facilitators?

There is only one (not that there couldn't be more), and its address is
hardcoded into the proxy badge.

> > Something to note is that the flash proxy doesn't do any crypto. It is
> > just a dumb pipe for ciphertext. There are still three relay hops after
> > the proxy. (But the proxy effectively gets to pick the first hop.)
> > 
> Perhaps TLS or HTTP would be a good idea? If the blocking of bridges is
> done by protocol fingerprinting, I worry that this will also be
> automatically blocked.

I hadn't thought of that. I recall looking up whether Flash can do TLS
sockets a few months ago, and it couldn't then, at least not in Flash
Player in a browser. But I just found this beta reference for the newest
Flash Player:

> > == Next steps
> > 
> > Here are the next things I'd like to accomplish:
> > 
> > * Get the proxy installed on more blogs and web pages. Currently it's
> >   only on the demo page and on my web site, which only provide enough
> >   proxies to have service about 60% of the time.
> I think the demo text is missing some bytes?

Do you mean the 'src="//crypto.st..."'? That just means to use http on
http pages, and https on https, so you don't get mixed-content warnings.
Though I guess just fixing https would also do that.

> > * Implement a bona fide rendezvous protocol. Though this is somewhat
> >   separable from flash proxies themselves, it's essential for a complete
> >   working system. We have done a couple of limited prototypes; please
> >   ask me if you are interested in or have knowledge of this.
> Do you mean something similar to the way GNUnet does nat punching?

Not exactly; NAT punching is related but different. While we were
designing this I did some reading on GNUnet and pwnat (I think that's
what you're referring to) and thought it wouldn't work for us. The
problem is that the "client" (a flash proxy) can't use raw sockets to
craft the time exceeded message.

By "rendezvous" we mean: How does a client send a request for service
out through the censor? (More generally, it's any way by which clients
and bridges get to know one another, for example I think of BridgeDB as
a rendezvous mechanism.)

I can give you an idea of ideas we've thought of or tried:
* Writing client registrations to append-only volumes on
  multiple cloud storage providers. The facilitator (which alone has
  read access) polls from these.
* Encrypting a message of the form "register X.X.X.X" and embedding it
  in a session cookie or other random field to a friendly web server.
  The server, if it is able to decrypt the cookie intelligibly,
  registers X.X.X.X in the background and returns whatever web page it
  was going to return. This requires having enough friendly web servers
  that they can't just be blocked. With identity-based encryption,
  clients don't have to know a server's private key in advance.
* A similar idea that uses the cooperation of ISPs rather than web
  servers is Telex (https://telex.cc/). I think this could also be used
  for rendezvous.

> > * Try a plain JavaScript proxy.
> I like that idea very much - I don't use Adobe anything and while I'd
> like to try it with Gnash, I'm not sure that Gnash is ready, is it?

I tried Gnash and Lightspark early on, but I couldn't make them work. (I
think they didn't support sockets, or didn't support ActionScript 3, or
something.) I think a JavaScript implementation would obviate the need
for Flash Player better than a port to Gnash or similar.

ActionScript source code (the source code for Flash programs) is
basically JavaScript with some funny type suffixes and a different
standard library. So maybe a port wouldn't be too difficult.
In fact if you go way back in the git history, you'll find my first
prototype called jscat, which used the Rhino JS engine.

David Fifield

More information about the tor-dev mailing list