How to detect "forged" SSL certificates from the webserver end
The only way I can see is to open a XMLHTTPRequest over SSL and pull the certificate out of that connection:
- MDN: How to check the security state of an XMLHTTPRequest over SSL (archive)
This doesn't work from a web-page, but is required to be run from an extension.
As already pointed out the proxy can easily change the javascript to kill this.
If the server uses certificate-based client authentication (i.e. the client also has a certificate and uses his private key to authenticate itself), then the server will detect the interceptor -- because in that case the client signs a hash value computed over the previously received handshake messages, which include the server certificate as seen by the client. In the presence of the interceptor, the client signs the wrong value, and the interceptor cannot correct that.
An alternate solution is to use TLS with SRP, in which authentication is not certificate-based but password-based and mutual.
Otherwise, no.
If I understand the question correctly you are asking if it's possible to detect (on the server end of a HTTPS-connection) whether the connection is coming from a proxy-server or an actual client (a browser)?
(I initially failed to see how the certificate would provide any valuable information, but realize now what I missed before. What was suggested is to provide the user with a javascript, trigger it through the HTML-code and have the user send back the extracted data from the SSL-certificate as it would be the certificate provided by the proxy. Yeah, that should work and it seems somewhat unlikely that the proxy-server would filter such "actions" from the javascript. Clever suggestion!)
Analyzing the following may help discover the originator of a connection:
- HTTP-header ordering
- Non-browser specific HTTP-headers
- HTTP-cookie values
- HTTP behavior
HTTP-header ordering - Detecting the originator of the connection should theoretically be possible by analyzing the order of HTTP headers. Browsers tend to structure their HTTP-headers in specific "patterns", utilizing this knowledge it may be possible to:
- Create a unique fingerprint for the proxy by determining how the proxy arranges HTTP-headers.
- By "in-advance" knowing how common browsers order their HTTP-headers and compare this to the ordering of the current request. (Clearly not the greatest idea...)
Non-browser specific HTTP-headers - It may be possible that the proxy-server includes specific HTTP-headers that a browser wouldn't. These might be for load-balancing, or request type redirections and so forth.
HTTP-cookie values - It's also concievable that the proxy would insert a specific cookie value to drect a connection to a specific server if load-balancing or clustering is used.
HTTP behavior - While not exactly easy to implement it may be possible to detect the presence of a proxy by initiate a number of HTTP-specific return codes and analyze how the "client" responds to the requests. Perhaps this may allow for the detection of an unusual behavior that would be considered uncommon for regular browsers.
Assuming an Apache HTTP-server it may be possible to use mod_security rules to achieve some of the above.
Some other, probably unlikely and unreliable, ways of detecting the origin of a connection would be to inspect protocol specific (IP/TCP) fields such as time stamps, IP-options. These may change in particular ways assuming a proxy-server origin.
It may also be possible to determine origin based on timings despite that they would be subjected to quite a bit of jitter and noise, it theoretically could be determined if a proxy intercepts the connection. I'm not suggesting this would at all be reliable or even possible, but quite a bit can be determined through timings.