Wednesday, April 7, 2010

The Beauty of Google Chrome

Google Chrome is really an amazing application. A lot has been said about its performance and how Opera 10.5 is slightly faster in terms of rendering and JavaScript performance. However, Opera doesn't implement any of the sandboxing techniques that Chrome does, if it did, it would suffer a significant performance penalty. This is a look at Google Chrome on Windows.

What exactly does make Chrome so special? It's the fact that it uses recommended practices for Windows security. It's funny reading some of the archived documentation on MSDN. The documentation uses examples on how a future release of Internet Explorer or Outlook , carefully disclaiming that current releases do not leverage these security features, could use such feature to provide additional protection to users.

Needless to say, Internet Explorer (IE) and Outlook still do not implement these recommendations but Chrome does. It implements and leverages the following technologies from Windows:

1. Multi-process architecture

Yes, IE 8 has this also but their implementation is very different from the one found in Chrome. In both browsers, each tab represents a distinct process. On Windows Vista and higher, both mark the process as a low integrity level, more on this later. This is pretty much where the similarities' end.

In IE, the browser leverages the fact that each thread in Windows can have a message pump and have user object likes windows, buttons, etc. That means that each child process is managing the user interface of the tab directly. It also means that this child process, its threads and its resources live in the same security context that you do. The only difference however is that most risks are mitigated by marking the process as a low integrity one. This means however that squatter and shatter attacks can still be performed on other windows, just as long as those processes are also low integrity ones. All this to say that child processes render content to your screen.

In Chrome, child processes are also renderers but they do not actually manage anything on screen. They're renderers and these processes do not have a message pump that is coming from Windows' user interface layer. Instead, their message pump is a custom one that is listening on a named pipe in Windows (a socketpair() on OSX and Linux). They listen for requests, render data and send back the information to the broker process which is actually the chrome of Chrome.

In other words, they render everything to an off screen surface that never interacts with your screen. Even if it did, we'll see later that it wouldn't matter anyway.

That means when you click on something, a message from the broker process, Chrome's chrome, is sent to one of the renderers, once it's done processing the message, the renderer communicates back the result to the broker for on screen rendering. We can see how such communication would be expensive and how it would slow down Chrome. Making Chrome's performance, and Windows' implementation of named pipes, even more impressive to witness.

It's also important to note that the lifetime of a renderer process in Chrome can also be very short. If you navigate to something like "" to "" using the same tab, Chrome has killed the renderer that was handling "" and spawned a new one to handle "" even if you did not switch tabs. Not only does this make it impossible to leak any information from the first renderer to the new one, it's also a very effective way of doing garbage collection. All resources, including leaks, that were used by the now defunct renderer are reclaimed automatically by the kernel.

2. Restricted Tokens

Windows NT has token based security. Most objects, i.e., files, sockets, pipes, etc., in Windows are securable, if not in the beginning, the capabilities have been iteratively added in subsequent versions.

Chrome sets up a token for its child processes that translate to "deny access to everything token". This means child processes cannot acquire any resources that were not implicitly inherited from the broker. Even the named pipe that is used for communication with the broker cannot be opened directly by the child, it must be inherited.

3. Use of Windows job objects

Windows 2000 introduced support for jobs. Jobs in Windows have 2 distinct responsibilities:

  • They include the ability to act on a group of processes atomically
  • They allow additional security restrictions to be placed on this group of processes

The second one is of interest here. I'm not saying Chrome doesn't use the first, I'm saying it's of no importance to our stroll on its implementation of security.

Windows doesn't allow security to be set on various API it inherited from OS/2 and 16-bit Windows. This includes manipulating any User or GDI objects , this is what allows for things like shatter attacks, capturing keystrokes and all kinds of bad things. It's also what makes the desktop experience possible, so windows, copy & paste, etc.

It does so because introducing new interfaces that would allow for fine grained security and deprecating the old ones would pretty much deprecate every Windows application out there, including Microsoft's. It also wouldn't make for the same end user experience. A lot of the mechanics that users' take for granted today on Windows, OSX, etc., just wouldn't be possible or very easy to implement.

Microsoft, in the earlier days of Windows, also decided not to do this for another reason: performance. We can imagine that requiring to check the security permission of every single window object when broadcasting a message would be very expensive for computer's in service 10-15 years ago when a simple logon session routinely has hundreds of windows. Don't forget, there are a lot of hidden windows on your desktop.

However, instead of adding new functions with additional parameters for security, you can set the security and continue to use the same function. This is what Microsoft did with the job object. Specifying the job object allows to set other limits on these child processes that normally would have free reign, allowing you to forbid the following:

  • Access to the clipboard
  • Creation of new processes
  • Access to other windows
  • Access to the window station object's global atom's table
  • Access to virtual desktop objects, ability to switch between them
  • Logoff, login
  • Creating new User objects
  • Change system parameters
  • Prevent hook functions, like trapping every key message, from being set

So once the job restrictions are set, normal function calls that would otherwise go unchallenged by the operating system are now restricted.

4. Use of Windows virtual desktop objects

The initial release of Windows NT, 3.1, had support for virtual desktops. However, this is circa 1989 for release in 1991, virtual desktops on Windows NT were not implemented to allow usage that is more in line with our thinking of virtual desktops today. For example, there is no way to switch a window from one desktop to another.

Instead, virtual desktops in NT were designed to be a security mechanism. They are the boundary of communication for User objects. This means if you install a global keyboard hook, you can also do so on your own desktop. If you broadcast a message to all windows, you're sending a message to every window on your desktop.

They were introduced so that login would be secure, that is, when you log on to Windows NT, there are 3 desktops created. The default one, the logon one and the screen saver one.

The logon one is only active when you lock your workstation and you need to unlock it. This allows for secure login since processes in the default desktop cannot create a keyboard hook into the logon desktop.

The screen saver is used to run the screen saver in its own sandbox. This means that a screensaver that is potentially malware would not be able to access your default desktop.

Of course, you still have the ability to create new windows on any desktop unless the proper steps are taken to secure them and this is indeed what Chrome does. Since its child processes don't have a user interface you can actually see, the child processes are nonetheless in a new desktop.

All these child processes also run in a job object that forbids them from accessing any of the virtual desktop functions. This means these processes can still interact with other low integrity processes but the only other processes these renderers can see are the one's found on Chrome's dedicated desktop for renderers. This is a step further than just marking the children as low integrity. The only possible squatter or shatter attacks that would be possible would be on other processes found in this desktop, problem is however for the would be attacker, is that these renderers don't actually have a user interface either.

5. Integrity level

The integrity level mechanism introduced in Vista allows for processes to be imbued with a level of trust. If a process wants to interact with a process of higher integrity, a UAC prompt is required to escalate the process. Also, low integrity processes do not have the ability to read any system objects or modify them

Chrome and Other Browser's Today

None of these mechanism are being leveraged by Firefox, Opera or Safari. Internet Explorer uses jobs and multi-processes but the sandbox is limited in scope compared to the one found in Chrome. Just food for thought on what browser you should be running to navigate the hostile web.

A final note, Microsoft has announced that it does not plan to support Internet Explorer 9 on anything less than Windows Vista SP2 stating only that "a modern browser requires a modern operating system". We're quick to point out that Chrome does indeed run on Windows XP. However, it is interesting to understand Windows XP's impact on Chrome.

It impacts Chrome in a few fundamental ways, the first one, is that, integrity levels were introduced in Vista, so it's not possible to mark child processes as low in Windows XP. This means these child processes have more privileges. However, due to other efforts realized to execute the renderer's under a proper sandbox, the scope is somewhat limited. The problem lies more in the ability to change system objects like registry keys. Registry key access is also governed by tokens but most users run as administrators under Windows XP.

More importantly however are the following:

  1. Windows XP does not require NTFS. It obviously supports it but installation on FAT32 is also supported. This means that the restricted token assigned to the child processes under such a file system will not forbid a compromised renderer from opening new files. Funnily enough, an attacker would need to deduce the path to any file he wishes to open however since listing of files would be prevented by the restricted token. Unfortunately, it's more than easy enough to deduce the path to important Windows' system files.
  2. Sockets are not securable objects. That's right, before the introduction of Vista, sockets are not governed by any token or any kind of security at all. That means a compromised renderer could create any number of new network connections. This could be used to download malicious code and then inject them in the files that were opened in the step above.

Ultimately, even on Windows XP, the sandbox setup by Chrome is nonetheless very impressive. Users should still be wary of that particular version of Windows compared to what is offered by Vista and above.

No comments: