proxy

When I launched Chrome on Thursday, I saw something unexpected:

SSLKeyLogfile

While most users probably would have no idea what to make of this, I happened to know what it means– Chrome is warning me that the system configuration has instructed it to leak the secret keys it uses to encrypt and decrypt HTTPS traffic to a stream on the local computer.

Looking at the Chrome source code, this warning was newly added last week. More surprising was that I couldn’t find the SSLKeyLogFile setting anywhere on my system. Opening a new console showed that it wasn’t set:

C:\WINDOWS\system32>set sslkeylogfile
Environment variable sslkeylogfile not defined

…and opening the System Properties > Advanced > Environment Variables UI showed that it wasn’t set for either my user account or the system at large. Weird.

Fortunately, I understood from past investigations that a process can have different environment variables than the rest of the system, and Process Explorer can show the environment variables inside a running process. Opening Chrome.exe, we see that it indeed has an SSLKEYLOGFILE set:

SSLKeyLogfileEB

The unusual syntax with the leading \\.\ means that this isn’t a typical local file path but instead a named pipe, which means that it doesn’t point to a file on disk (e.g. C:\temp\sslkeys.txt) but instead to memory that another process can see.

My machine was in this state because earlier that morning, I’d installed Avast Antivirus to attempt to reproduce a bug a Chrome user encountered. Avast is injecting the SSLKEYLOGFILE setting so that it can conduct a monster-in-the-browser attack (MITB) and see the encrypted traffic going into Chrome.

Makers of antivirus products know that browsers are one of the primary vectors by which attackers compromise PCs, and as a consequence their security products often conduct MITB attacks in order to scan web content. Antivirus developers have two common techniques to scan content running in the browser:

  1. Code injection
  2. Network interception

Code Injection

The code injection technique relies upon injecting security code into the browser process. The problem with this approach is that native code injections are inherently fragile– any update to the browser might move its functions and data structures around such that the security code will fail and crash the process. Browsers discourage native code injection, and the bug I was looking at was related to a new feature, RendererCodeIntegrity, that directs the Windows kernel to block loading of any code not signed by Microsoft or Google into the browser’s renderer processes.

An alternative code-injection approach relies upon using a browser extension that operates within the APIs exposed by the browser– this approach is more stable, but can address fewer threats.

Even well-written code injections that don’t cause stability problems can cause significant performance regressions for browsers– when I last looked at the state of the industry, performance costs for top AV products ranged from 20% to 400% in browser scenarios.

Network Interception

The Network interception technique relies upon scanning the HTTP and HTTPS traffic that goes into the browser process. Scanning HTTP traffic is straightforward (a simple proxy server can do it), but scanning HTTPS traffic is harder because the whole point of HTTPS is to make it impossible for a network intermediary to view or modify the plaintext network traffic.

Historically, the most common mechanism for security-scanning HTTPS traffic was to use a monster-in-the-middle (MITM) proxy server running on the local computer. The MITM would instruct Windows to trust a self-signed root certificate, and it would automatically generate new interception certificates for every secure site you visit. I spent over a decade working on such a MITM proxy server, the Fiddler Web Debugger.

There are many problems with using a MITM proxy, however. The primary problem is that it’s very very hard to ensure that it behaves exactly as the browser does and that it does not introduce security vulnerabilities. For instance, if the MITM’s certificate verification logic has bugs, then it might accept a bogus certificate from a spoof server and the user would not be warned– Avast used to use a MITM proxy and had exactly this bug; they were not alone. Similarly, the MITM might not support the most secure versions of protocols supported by the browser and server (e.g. TLS/1.3) and thus using the MITM would degrade security. Some protocol features (e.g. Client Certificates) are incompatible with MITM proxies. And lastly, some security features (specifically certificate pinning) are fundamentally incompatible with MITM certificates and are disabled when MITM certificates are used.

Given the shortcomings of using a MITM proxy, it appears that Avast has moved on to a newer technique, using the SSLKeyLogFile to leak the secret keys HTTPS negotiates on each connection to encrypt the traffic. Firefox and Chromium support this feature, and it enables decryption of TLS traffic without using the MITM certificate generation technique. While browser vendors are wary of any sort of interception of HTTPS traffic, this approach is generally preferable to MITM proxies.

There’s some worry that Chrome’s new notification bar might drive security vendors back to using more dangerous techniques, so this notification might not make its way into the stable release of Chrome.

When it comes to browser architecture, tradeoffs abound.

-Eric

PS: I’m told that Avast may be monetizing the data they’re decrypting.

Appendix: Peeking at the Keys

If we point the SSLKeyLog setting at a regular file instead of a named pipe:

chrome --ssl-key-log-file=C:\temp\sslkeys.txt

…we can examine the file’s contents as we browse to reveal the encryption keys:

ExportedKeys

This file alone isn’t very readable for a human (even if you read Mozilla’s helpful file format documentation), but you can configure tools like Wireshark to make use of it and automatically decrypt captured TLS traffic back to plaintext.

Every few weeks for the last six or so years, I see someone complain on Twitter or in forums that the entire Internet seems to think they’re running an old version of IE. For instance, an IE11 user on Windows 8.1 might see the following warning on Facebook:

image

These warnings typically occur when the browser is using Compatibility View mode for a site and the site demands a browser that supports modern standards. Many customers used to find themselves accidentally in this state because they were overzealously clicking the “Compatibility View” button (back when IE had one) or clicking the “Display all sites in Compatibility View” checkbox (back when IE had it).

Since IE11 has cleaned that mess up (by hiding Compatibility View), you might wonder how a user could end up in such a broken state.

The answer is both complicated and interesting, deeply intertwined with nearly 15 years of subtle Internet Explorer behaviors.

When I ask the affected IE11 user to visit my User-Agent string test page, they see IE7’s Compatibility View user-agent string:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Win64; x64; Trident/7.0; .NET4.0E; .NET4.0C; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)

But why?

Since IE no longer shows the Zone in the status bar, you must right-click the page and choose Properties to get your next clue:

image

Wait, what?!? Why is some random site on the Internet in the privileged Local Intranet security zone?

Next the user does the same test on Facebook.com and finds that it too is in the Intranet Zone. In fact, the whole web is getting zoned as Intranet!

This represents a significant security hole, and the user has only discovered it because, by default, Tools > Compatibility View Settings has Display Intranet sites in Compatibility View set, and the unwanted CompatView causes sites like Facebook to complain.

So what’s going on here!?!

Click Tools > Internet Options > Connections > LAN Settings, and observe that the settings are the defaults:

image

Wait… what exactly does that Automatically detect settings option do?

Why, it allows a computer on your network to decide what proxy server your client should use through a process called WPAD. The server in question gets to supply a proxy configuration script that implements a function FindProxyForUrl(). That function returns either a proxy (e.g. “PROXY myproxy:8080” or “DIRECT” to indicate that the request should be sent directly to the origin server and bypass the proxy.

And now we’re getting somewhere. Take a look at the checkboxes inside Tools > Internet Options > Security > Local Intranet > Custom Level, specifically the second checkbox:

image

Yup, that’s right—if a proxy script returns DIRECT for a given site, IE defaults to treating that site as a part of the Local Intranet Zone, giving it additional privileges and also defaulting it to CompatView. Oops.

You might think: “well, surely a network proxy administrator would never make that mistake!”

Back in 2011, the IE team started getting email from all over the company complaining that “IE is broken. It doesn’t support HTML5!” Guess why not? Oops.

Recommendations

Unless you’re running IE on a Corporate Network that requires support for things like Negotiate Authentication and the like, you should untick the Automatically detect intranet network checkbox and all of the checkboxes beneath it. This improves security and enhances IE’s sandbox.

Unless you’re running a laptop that moves to corporate networks, you should also disable the Automatically detect settings checkbox to prevent IE from asking your network what proxy to use.

-Eric Lawrence