Possible alternative implementation proof of concept

Currently torcheck relies on the exitlist being up to date to get a good guess as to whether the user is on the Tor network or not.

My proposal is to use attributes of the network itself to verify if the user is on Tor or not. To do this the server should host two services. One will be a hidden service which is only accessible through the Tor client on localhost (needs to be inaccessible from the network) and the other will be setup as publicly accessible as usual through nginx or apache.

The user will hit the torcheck webpage (over https), on this initial request, a buffered channel will be created and mapped to a randomly generated (should be unique) key. The server will render a page with two iframes in the page.

One of the iframes will load the same website with the key in the querystring, the server will hang the request until it receives a message on the channel or until a timeout passes (Note, this is not a spinlock, it's very lightweight) After the timeout or receiving on the channel this iframe will provide the user feedback of success or failure. (currently provides info to the user when the server is still waiting -- it's using five 10 second timeouts)

The other iframe will load the same request but to the hidden service (key in the querystring), if the server receives this request then it sends a message on the channel mentioned above which will unhang the other iframe's server process which will then provide the user with a success page. This iframe will probably be hidden, the request is the only important part.

This is all possible without Javascript, but of course if the user has js enabled we can use that to make it clearer for the user.

The benefits of this service would be that it's extremely lightweight and should be able to handle many clients, it is also not dependant on an exit list being up to date which should reduce false positive/negatives. Assuming both torcheck and the hidden service are accessed over https it should be almost impossible for someone to intercept and forge the request to the hidden service with appropriate key. (An attacker would know the domain being hit, but not the querystring)

My main concern would be that if the user is not on Tor, the .onion iframe will be a dns leak? I'm not sure how much of a concern that is considering if the user isn't on Tor then torcheck is also a dns leak.

Other than that the main trade off is that the client waits longer to get their confirmation if they have just connected to the Tor network (as initial hidden service connections are slow). This is easily masked by Javascript with loading animations and perhaps some 'how to use Tor safely' text for users to read for 10 seconds.

To test, build & run with `make` and then access the webserver via 127.0.0.1:8080.