Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

The company I work for sometimes intercepts employees ssl connections to https websites by making the ssl connection on their behalf from a proxy, and then using the own generated certificate to send the page to the user. Obviously this only works because they installed their own root certificate on the employees PCs but you can tell when you go to a https website and look at the certificate and find that it's signed by [company] and not by one of the usual CAs/

Now I don't intend to get into the morality or legality of this practice here even though I have opinions on it :P

My question is, is there any way to detect that this is happening from the webserver and refuse to deliver the page if it's being intercepted like this?

I was thinking that maybe some javscript on the webpage could find out which certificate the page was signed with and issue a warning if it was wrong - but there doesn't seem to be any way I can find to check the certificate from javascript. (I realise that if the company could modify the certificate they could modify the javascript too, but I'm assuming they wouldn't write custom code for each website)...

Is there any other trick I can use to do this?

share|improve this question
    
Good question! Obviously the actual SSL connection without client authentication does not differ from actual browsers - but perhaps somebody comes up with a funky trick that would catch most of the cases somehow... –  Nakedible Jul 30 '11 at 8:13

4 Answers 4

up vote 4 down vote accepted

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:

  1. Create a unique fingerprint for the proxy by determining how the proxy arranges HTTP-headers.
  2. 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.

share|improve this answer
    
If the proxy simply forwards (and maybe logs) the connection from the browser, I see no reason that the HTTP header and such would be different. –  Paŭlo Ebermann Jul 30 '11 at 17:30
    
Since it's an SSL-connection I doubt (although I can't substantiate my thought) that the proxy-server would simply forward the connection attempt. A new SSL-connection would be negotiated with the remote server, and I would argue it's more likely that the proxy-server would differ from the browser in regards to HTTP-header ordering. Unless of course the proxy-server copies all headers from the browser, and settle for only negotiating the SSL-connection. –  Christoffer Jul 30 '11 at 21:48
2  
Okay, we should say it so: If the proxy wants to hide itself from the real server, it certainly can do so. The SSL connection is on a lower level than the HTTP requests/responses which are transported over it - each can be independently modified or not. –  Paŭlo Ebermann Jul 30 '11 at 22:07
1  
"provide the user with a javascript [...] and have [it] send back the extracted data from the SSL-certificate" - Unfortunately, as far as I know, there is no way for Javascript running on the browser to find out what server certificate was used on the current connection. Therefore, this doesn't work. –  D.W. Aug 1 '11 at 3:46

The only way I can see is to open a XMLHTTPRequest over SSL and pull the cert out of that connection: https://developer.mozilla.org/En/How_to_check_the_security_state_of_an_XMLHTTPRequest_over_SSL

As already pointed out the proxy can easily change the javascript to kill this.

share|improve this answer
    
I didn't know you could get the certificate parameters from XMLHTTPRequest. I believe this is what the original poster wanted. –  Nakedible Jul 30 '11 at 11:24
    
This looks very interesting, so +1, however it looks like it's mozilla only as far as I can tell –  JohnB Jul 30 '11 at 13:39
1  
Does this actually work for ordinary web pages? Have you tried it? The web page you link to says "This code requires elevated privileges to run; you can only call it from a browser extension [..]", which seems to suggest an ordinary web page cannot use this. –  D.W. Aug 1 '11 at 3:44
    
You are right, not pretty, the question is why can't you get this information from an ordinary webpage? It's not like it's that sensitive, unless it exposes the private keys, in which case, still, why not just not expose the private keys? –  ewanm89 Aug 1 '11 at 20:39

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.

share|improve this answer
    
Mutual authentication is the only sure way, but there tends to need some user interaction for it to work. –  ewanm89 Aug 1 '11 at 20:41

By convention, a standard proxy should include the X-Forwarded-For HTTP request header, even though it's not in the RFC it is considered defacto standard.

That said, if the proxy wants to hide it's existance, there is no problem to simply ignore putting this header in.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.