This is the first of a series of posts that will dive deep inside Google Chrome’s codebase and understand how it works as much as possible.
I believe that it’s a great idea to know what on earth is going on in the software you run, the first and foremost of them being your browser, especially as a flurry of universal security vulnerabilities were discovered inside Chrome recently.
Google Chrome is a slightly modified and reskinned copy of Chromium, an open-source browser. This means that source code is available, which makes this investigation possible.
The objective is not to understand every single function and line of code - it’s to get an overview of the high-level components that make up the software.
What is the WebUI?
It is a special web page that has access to the Google Chrome internal machinery itself. For example, the New Tab page, the Settings page, the Extensions page, etc.
The URLs that use the chrome:// prefix (which is a protocol in its own right) are all WebUIs. They are scripted using the same web technologies used in normal web pages such as HTML, CSS, and Javascript, but they have permission to access browser internals.
When I say “internals”, I am referring to the renderer, which I will talk about later. For now, it suffices to say that it is the component that generates a bitmap from the HTML and CSS and draws it on the screen.
The renderer is usually written in some form of Javascript. You might have heard of the V8 engine (not to be confused with the car engine of the same name). This is the renderer that powers not only Chrome, but also NodeJS. It has some methods which allow you to run arbitrary Javascript on it [WebUIMessageHandler::CallJavascriptFunction()] and send messages to the window object using chrome.send(). This is used to implement things like service workers.
Google Chrome pages are sandboxed
The vast majority of pages have no access to the filesystem or any part of the world outside the browser whatsoever. Since implementing access controls on each and every tab would be prohibitively slow, this sandbox is enforced on the renderer.
As a result, the renderer (and all the pages under it) can only draw stuff to the screen but not interact with the OS. They cannot access the camera or microphone. They cannot show you popups or use your on-device location services. Chrome even supports USB and serial port interfacing - which is not surprising when you consider it’s the basis of ChromeOS - and obviously, a page has no access to those either.
I can make a long list of resources that are off-limit to pages, but you can find many of them by going to the Site Permissions area for that particular page.
The WebUI as an attack vector
Most security vulnerabilities like the one you saw above rely on breaking through the sandbox using maliciously crafted Javascript served in a webpage that bypasses the renderer.
WebUI pages are special because they are not sandboxed like this. This makes them an attractive attack vector, especially when you consider Chrome supports extensions. See that New Tab Page extension in the results for example? It can technically replace the chrome://newtab WebUI with its own page.
Also, since WebUIs receive all the service worker messages, it’s possible that a malicious service worker sends something that’s designed to gain access to some internal Chrome functionality.
These issues can be mitigated by disallowing WebUIs from loading random HTTP(S) fetches and data URLs. If they need to embed content from an external page for some reason, such as the Google Doodles, they can use iframes for that, which are sandboxed like a standard web page.
Parts of the WebUI
Chrome makes a WebUI by creating a C++ class of the same name, along with a WebUIDataSource, a WebUIMessageHandler, and a WebUIController which is responsible for pulling the strings that make the puppet move (figuratively). All of these are neatly documented consecutively on this page.
The WebUI represents the actual super-privileged Chrome page. The WebUIDataSource adds resources to a WebUI that it can access later, for example, images or translation strings. The WebUIMessageHandler receives Javascript events on behalf of the WebUI.
To summarize what we have learned, I have made this simple diagram of linked concepts. Who ever knew that learning parts of your programs could be so simple?