Subject Name replaced with IP address in SSL certificate

4,288 views
Skip to first unread message

Siddarth Adukia

unread,
Mar 28, 2012, 12:11:26 PM3/28/12
to httpf...@googlegroups.com
Hello,

I've been experiencing some problems with HTTPS decryption in Fiddler2 lately. The Subject Name field of the SSL certificate created by Fiddler gets replaced by the IP address of the host I'm attempting to connecting, causing clients to reject the certificate. This is the warning I get in Fiddler for https://gmail.com

<error>
The remote server (74.125.226.245) presented a certificate that did not validate, due to RemoteCertificateNameMismatch.

SUBJECT: CN=mail.google.com, O=Google Inc, L=Mountain View, S=California, C=US
ISSUER: CN=Thawte SGC CA, O=Thawte Consulting (Pty) Ltd., C=ZA
EXPIRES: 9/30/2013 7:59:59 PM
</error>

On the client side, the SN of the certificate is filled with "CN=74.125.226.245" (and O/OU as fiddler do not trust).

This is on an Android client, with the Fiddler root certificate installed in it's root store, if that helps. For local browser proxy on the same machine as Fiddler, I encounter no such error.

I assume at some point Fiddler does a DNS lookup for the site being connected to, and compares to the CN in the SSL certificate, sees that it doesn't match, and replaces the (correct) CN with the IP address of the server.

TL;DR: Is there a way to prevent Fiddler from messing with the CN of the certificate presented by the remote server?

EricLaw

unread,
Mar 28, 2012, 1:42:51 PM3/28/12
to httpf...@googlegroups.com
You're confused in a few ways. :-)
 
First, Fiddler has always behaved like this.
 
Second, I'm betting that you got your Android to send traffic to Fiddler using iptables or some other hack on the device? The problem with doing that is that the request sent off the device doesn't have a proper Host in the CONNECT request; it instead uses the IP address of the target. By default, Fiddler presents a certificate bearing the CN = the host that it was asked to CONNECT to. Since the iptables hack doesn't provide Fiddler with that hostname, you get the name mismatch.
 
Now, there are two name mismatches to consider: 1: Fiddler's displayed error, which it shows because the server didn't present a certificate that matched the Host of the request. 2: The Android displayed error, which it shows because Fiddler presented a certificate that didn't match the host that the Android browser thought it was making.
 
Fixing #1 is pretty simple, you can just ignore the warning.
 
For #2, fortunately, someone else reported this issue to me a while ago, and so you have some options depending on which Android build you're using.
 
If the Android build is current enough, you can set the fiddler.network.https.SetCNFromSNI preference to True, which will cause Fiddler to generate the SubjectCN using the server name indicator from the client's TLS handshake instead of using the HOST field from the CONNECT. If the client is properly using SNI, you won't get any errors.
 
If the client isn't sending SNI, you can fix mismatches on a one-off basis:
  if (oSession.HTTPMethodIs("CONNECT") && oSession.HostnameIs("74.125.71.84")){
    oSession.oFlags["x-OverrideCertCN"] = "hostnameToUseInCertificate.com";
  }
 
Now, some folks wonder: "Why can't Fiddler just use whatever CN the server used?" The answer is that Fiddler's handshake with the client occurs before the handshake with the server, because the client's CONNECT request might be for a WebSocket tunnel rather than a HTTPS tunnel, and if Fiddler were to blindly HTTPS handshake with the server before handshaking with the client, the WebSocket scenario would be broken.

Siddarth Adukia

unread,
Mar 29, 2012, 11:41:44 AM3/29/12
to httpf...@googlegroups.com
Thanks for the help! 

I tried to fix the proxy in Android first - you're right, it is kind of hacked-up, no official proxy support yet. Failed to rectify this.

Unfortunately, the Android version I'm targeting doesn't seem to set SNI in the handshake. I had to statically set the hostname instead, which is working fine.


As an aside, I wasn't aware of the differences in the WebSocket scenario, and took a quick glance at the RFC: it seems that for proxy aware applications, and HTTP: upgrade header is added, and for non-proxy aware applications, no HTTPS CONNECT message is sent (which would be the case in hacked up proxies, like in the case for Android). Wouldn't headers in the initial handshake still give away the fact that the connection is a WebSocket tunnel (e.g. "upgrade" or any of the other WS headers)? Is the upgrade flag added to HTTPS CONNECT messages? Or do implementations differ from the RFC? (Which I'm sure never happens, right?).

Not a change request, I'm just curious about the differences - I'm sure I'll have to deal with this somewhere down the line.

EricLaw

unread,
Mar 29, 2012, 12:14:08 PM3/29/12
to httpf...@googlegroups.com
Unfortunately, the Upgrade header is only added to the traffic inside the CONNECT tunnel, it's not on the CONNECT itself.

EricLaw

unread,
Mar 8, 2013, 10:52:15 AM3/8/13
to
Great question, thanks for asking. Please try this and let me know how it goes:
 
2. Click Rules > Customize Rules. Scroll to OnBeforeRequest
3. Add the following code inside the function:
 
   if (oSession.HTTPMethodIs("CONNECT")) {
     oSession["X-UseCertCNFromServer"] = "AndroidTesting";
     oSession["X-IgnoreCertCNMismatch"] = "ImplicitlyTrustingServerCN";
   }
 
4. Save the script.
 
Please give it a try and let me know if it works for you.
 
thanks,
Eric
Reply all
Reply to author
Forward
0 new messages