Chromium Blog
News and developments from the open source browser project
A Tale Of Two Pwnies (Part 2)
Monday, June 11, 2012
When we
wrapped up
our recent Pwnium event, we praised the creativity of the submissions and resolved to provide write-ups on how the two exploits worked. We already covered
Pinkie Pie’s submission
in a recent post, and this post will summarize the other winning Pwnium submission: an amazing multi-step exploit from frequent Chromium Security Reward winner Sergey Glazunov.
From the start, one thing that impressed us about this exploit was that it involved no memory corruption at all. It was based on a so-called “Universal Cross-Site Scripting” (or UXSS) bug. The UXSS bug in question (
117226
) was complicated and actually involved two distinct bugs: a state corruption and an inappropriate firing of events. Individually there was a possible use-after-free condition, but the exploit -- perhaps because of various memory corruption mitigations present in Chromium -- took the route of combining the two bugs to form a “High” severity UXSS bug. However, a
Pwnium
prize requires demonstrating something “Critical”: a persistent attack against the local user’s account. A UXSS bug alone cannot achieve that.
So how was this UXSS bug abused more creatively? To understand Sergey’s exploit, it’s important to know that Chromium implements some of its built-in functions using special HTML pages (called WebUI), hosted at origins such as
chrome://about
. These pages have access to privileged JavaScript APIs. Of course, a normal web page or web renderer process cannot just iframe or open a
chrome:// URL
due to strict separation between
http[s]://
and
chrome://
URLs. However, Sergey discovered that iframing an invalid
chrome-extension:// resource
would internally host an error page in the
chrome://chromewebdata
origin (
117230
). Furthermore, this error page was one of the few internal pages that did not have a
Content Security Policy
(CSP) applied. A CSP would have blocked the UXSS bug in this context.
At this point, multiple distinct issues had been abused, to gain JavaScript execution in the
chrome://chromewebdata
origin.
The exploit still had a long way to go, though, as there are plenty of additional barriers:
chrome://chromewebdata
does not have any sensitive APIs associated with it.
chrome://a
is not same-origin with
chrome://b
.
chrome://*
origins only have privileges when the backing process is tagged as privileged by the browser process, and this tagging only happens as a result of a top-level navigation to a
chrome://
URL.
The sensitive
chrome://*
pages generally have CSPs applied that prevent the UXSS bug in question.
The exploit became extremely creative at this point. To get around the defenses, the compromised
chrome://chromewebdata
origin opened a window to
chrome://net-internals
, which had an iframe in its structure. Another WebKit bug -- the ability to replace a cross-origin iframe (
117583
) -- was used to run script that navigated the popped-up window, simply “back” to
chrome://net-internals
(
117417
). This caused the browser to reassess the
chrome://net-internals
URL as a top-level navigation -- granting limited WebUI permissions to the backing process as a side-effect (
117418
).
The exploit was still far from done. It was now running JavaScript inside an iframe inside a process with limited WebUI permissions. It then popped up an about:blank window and abused another bug (
118467
) -- this time in the JavaScript bindings -- to confuse the top-level
chrome://net-internals
page into believing that the new blank window was a direct child. The blank window could then navigate its new “parent” without losing privileges (
113496
). The first navigation was to
chrome://downloads
, which gained access to additional privileged APIs. You probably get a sense of where the exploit was headed now. It finished off by abusing privileged JavaScript APIs to download an attack DLL. The same APIs were used to cleverly “download” and run
wordpad.exe
from the local disk (thus avoiding the system-level prompt for executing downloads from the internet zone). A design quirk of the Windows operating system caused the attack DLL to be loaded into the trusted executable.
As you can imagine, it took us some time to dissect all of this. Distilling the details into a blog post was a further challenge; we’ve glossed over the use of the UXSS bug to bypass pop-up window restrictions. The UXSS bug was actually used three separate times in the exploit. We also omitted details of various other lockdowns we applied in response to the exploit chain.
What’s clear is that Sergey certainly earned his $60k Pwnium reward. He chained together a whopping 14[*] bugs, quirks and missed hardening opportunities. Looking beyond the monetary prize, Sergey has helped make Chromium significantly safer. Besides fixing the array of bugs, we’ve landed hardening measures that will make it much tougher to abuse
chrome://
WebUI pages in the future.
Posted by Ken Buchanan, Chris Evans, Charlie Reis and Tom Sepez, Software Engineers
[*]14, or thereabouts. It’s easy to lose count.
Try Chrome in Metro mode
Thursday, June 7, 2012
Back in March, we
began work
on a
Metro-style enabled desktop browser
, a version of Chrome that will run in both the Metro and desktop environments of Windows 8 on x86. (Chrome won’t run in WinRT, i.e. Windows 8 on ARM processors, as Microsoft is
not allowing browsers
other than Internet Explorer on the platform.) If you’re running the
Release Preview of Windows 8
, you’ll be able to try Chrome in Metro mode in the next
Chrome Dev channel
release by setting it as your default browser.
The initial releases of Chrome in Metro mode will include integration with the basic Windows 8 system functionality, such as
charms
and
snap view
. Over the next few months, we’ll be smoothing out the UI on Metro and improving touch support, so please feel free to
file bugs
. We’re committed to bringing the speed, simplicity, and security of Chrome into Windows 8, and we look forward to working with you on it.
Carlos Pizano, Software Engineer and Metro Gnome
Accelerated CSS Filters Landed in Chromium
Monday, June 4, 2012
CSS filters are a powerful, easy-to-use visual effects tool for web developers. Filters can manipulate the appearance of any HTML element and can be stacked together to create unique effects -- all with a single line of CSS. Chromium GPU accelerates these filters to make them super fast. CSS filters are new in Chromium 19.
The current set of supported filters in Chromium include many that are familiar to web developers with image processing experience, such as sepia, saturation, opacity, and blurs. If you’re a web designer looking to add dynamic visuals to your next page layout, a developer building a photo editing app, or a game developer looking for an easy way to add effects to your next title, CSS filters can help you get there easily.
img { -webkit-filter: sepia(100%) contrast(200%) blur(5px) }
GPU acceleration of these filters brings their performance to the point where they can be used for animating elements in conjunction with CSS animations powered by
-webkit-transition
or even HTML5 video tags.
To get a sense of how much you can do with CSS filters, check out this interactive abstract
painting app
.
For more info on CSS filters, including a full list of those available in Chromium and how to use them, check out the new
CSS Filter tutorial
on HTML5Rocks.
Posted by Stephen “Rose-Colored Glasses” White, Software Engineer
Changes to the Field Trials infrastructure
Friday, May 25, 2012
In theory there’s no difference between theory and practice. In practice, there is
. That’s why we prefer to try
new ideas out in the real world
and see which features actually helped users get where they want to go. In Chrome we call these tests Field Trials, and they’ve been part of every install steadily making Chrome better since day one. For example, Field Trials helped us improve our Omnibox pre-rendering by about 70 percent - making about 1 in 3 Omnibox navigations faster by a second or more.
If you’re
contributing to Chrome
, you should consider using Field Trials to help tune your features. Recently we’ve added infrastructure to help make designing and deploying these tests easier than ever. Field Trials will now have a regular update cycle similar to the one that delivers the newest version of Chrome to users, making it easier to rapidly release and retire new variations. We’ve also centralized the logic of which variations are active so that its easy for developers on M21 or higher to reset their variation state, using the --reset-variation-state command line flag. To learn more about variations of Chrome, check out
Field Trials
at the Chromium project.
Posted by Tyler Odean, Product Manager
A Tale of Two Pwnies (Part 1)
Tuesday, May 22, 2012
Just over two months ago, Chrome sponsored the
Pwnium
browser hacking competition. We had
two fantastic submissions
, and successfully blocked both exploits within 24 hours of their unveiling. Today, we’d like to offer an inside look into the exploit submitted by
Pinkie Pie
.
So, how does one get full remote code execution in Chrome? In the case of Pinkie Pie’s exploit, it took a chain of six different bugs in order to successfully break out of the Chrome sandbox.
Pinkie’s first bug (
117620
) used Chrome’s prerendering feature to load a
Native Client
module on a web page.
Prerendering
is a performance optimization that lets a site provide hints for Chrome to fetch and render a page before the user navigates to it, making page loads seem instantaneous. To avoid sound and other nuisances from preloaded pages, the prerenderer blocks plug-ins from running until the user chooses to navigate to the page. Pinkie discovered that navigating to a pre-rendered page would inadvertently run all plug-ins—even Native Client plug-ins, which are otherwise permitted only for installed extensions and apps.
Of course, getting a Native Client plug-in to execute doesn’t buy much, because the Native Client process’ sandbox is even more restrictive than Chrome’s sandbox for HTML content. What Native Client does provide, however, is a low-level interface to the
GPU command buffers
, which are used to communicate accelerated graphics operations to the GPU process. This allowed Pinkie to craft a special command buffer to exploit the following integer underflow bug (
117656
) in the GPU command decoding:
static uint32 ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer - sizeof(uint32)) / sizeof(T); }
The issue here is that if
size_of_buffer
is smaller than
sizeof
(
uint32
), the result would be a huge value, which was then used as input to the following function:
static size_t ComputeSize(size_t num_results) { return sizeof(T) * num_results + sizeof(uint32); }
This calculation then overflowed and made the result of this function zero, instead of a value at least equal to
sizeof(uint32)
. Using this, Pinkie was able to write eight bytes of his choice past the end of his buffer. The buffer in this case is one of the GPU transfer buffers, which are mapped in both processes’ address spaces and used to transfer data between the Native Client and GPU processes. The Windows allocator places the buffers at relatively predictable locations; and the Native Client process can directly control their size as well as certain object allocation ordering. So, this afforded quite a bit of control over exactly where an overwrite would occur in the GPU process.
The next thing Pinkie needed was a target that met two criteria: it had to be positioned within range of his overwrite, and the first eight bytes needed to be something worth changing. For this, he used the GPU buckets, which are another IPC primitive exposed from the GPU process to the Native Client process. The buckets are implemented as a
tree structure
, with the first eight bytes containing pointers to other nodes in the tree. By overwriting the first eight bytes of a bucket, Pinkie was able to point it to a fake tree structure he created in one of his transfer buffers. Using that fake tree, Pinkie could read and write arbitrary addresses in the GPU process. Combined with some predictable addresses in Windows, this allowed him to build a
ROP chain
and execute arbitrary code inside the GPU process.
The GPU process is still sandboxed well below a normal user, but it’s not as strongly sandboxed as the Native Client process or the HTML renderer. It has some rights, such as the ability to enumerate and connect to the named pipes used by
Chrome’s IPC layer
. Normally this wouldn’t be an issue, but Pinkie found that there’s a brief window after Chrome spawns a new renderer where the GPU process could see the renderer’s IPC channel and connect to it first, allowing the GPU process to impersonate the renderer (
bug 117627
).
Even though Chrome’s renderers execute inside a stricter sandbox than the GPU process, there is a special class of renderers that have IPC interfaces with elevated permissions. These renderers are not supposed to be navigable by web content, and are used for things like extensions and settings pages. However, Pinkie found another bug (
117417
) that allowed an unprivileged renderer to trigger a navigation to one of these privileged renderers, and used it to launch the extension manager. So, all he had to do was jump on the extension manager’s IPC channel before it had a chance to connect.
Once he was impersonating the extensions manager, Pinkie used two more bugs to finally break out of the sandbox. The first bug (
117715
) allowed him to specify a load path for an extension from the extension manager’s renderer, something only the browser should be allowed to do. The second bug (
117736
) was a failure to prompt for confirmation prior to installing an unpacked
NPAPI plug-in extension
. With these two bugs Pinkie was able to install and run his own NPAPI plug-in that executed outside the sandbox at full user privilege.
So, that’s the long and impressive path Pinkie Pie took to crack Chrome. All the referenced bugs were fixed some time ago, but some are still restricted to ensure our users and Chromium embedders have a chance to update. However, we’ve included links so when we do make the bugs public, anyone can investigate in more detail.
In an upcoming post, we’ll explain the details of Sergey Glazunov’s exploit, which relied on roughly 10 distinct bugs. While these issues are already fixed in Chrome, some of them impact a much broader array of products from a range of companies. So, we won’t be posting that part until we’re comfortable that all affected products have had an adequate time to push fixes to their users.
Posted by Jorge Lucangeli Obes and Justin Schuh, Software Engineers
Connect with Web Intents
Tuesday, May 15, 2012
Last year we
proposed the Web Intents API
to help web applications integrate with one another with minimal effort. We've now enabled an experimental version of the API in the most recent
stable version of Chrome
, to gather feedback from the web community and shape the future of the Web Intents API.
This prototype version of Web Intents makes it easier for developers to try out the API and experience its benefits first hand:
Developers who build client apps will be able to easily include functionality from other web services (e.g., photo editing).
Developers creating those services will no longer need to invest time and resources to negotiate and build hardcoded integrations - they can just focus on offering a great quality product with the integration facilitated by the API.
In addition, this implementation of Web Intents can help the design discussions in the
W3C web intents open standards list
. After all, it's impossible to build a complex API—especially one that requires an ecosystem of apps—without feedback from web developers using it in the wild.
We expect that Web Intents will evolve significantly, potentially in backwards-incompatible ways, as
feedback
from real world usage trickles in. Because of its experimental status, the current live version is prefixed and only allows applications to register as services in their Chrome Web Store app manifest.
Once the API is stable, we plan to remove this restriction.
To learn more on how to use the experimental Web Intents API check out the
Web Developers' Guide to Web Intents in Chrome
. If you choose to experiment with Web Intents, be sure to follow our
discussion group
, where we'll announce any impending breaking changes in Chrome's implementation.
Posted by James Hawkins, Software Engineer
Better code optimization decisions for V8
Tuesday, May 1, 2012
As of current dev and beta channel releases, V8 uses a new algorithm based on counters to decide which functions to optimize. This greatly increases performance for small JavaScript programs. For example, on the SunSpider benchmark, which focuses on extremely short-running tests, V8's speed improved by about 25%.
When executing JavaScript, V8 at first compiles it to machine code with a very fast compiler that doesn't optimize the code it produces. V8 has a second,
optimizing compiler
that generates much faster machine code, but takes much more time to do so, so it has to be used selectively. That's why V8 must try to predict which functions will benefit most from optimization, and carefully decide when to optimize them.
In the past, V8 stopped once every millisecond to look at currently running functions, and eventually optimized them. For long-running programs, this worked great, but short-running programs often finished before they could benefit much from the optimizing compiler -- a single millisecond can be a long time to wait before optimizing! In addition, V8 often made different optimization decisions each time a JavaScript program ran, sometimes overlooking small but performance-critical functions.
The new version of V8 makes earlier and more repeatable optimization decisions by analyzing the running program in more detail. It uses counters to keep track of how often JavaScript functions are called and loops are executed in a program, approximating the time spent inside each function. That way V8 is able to quickly gather fine-grained information about performance bottlenecks in a JavaScript program, and to make sure that the optimizing compiler's efforts are spent on those functions that deserve it most.
The new algorithm is contained in the current beta channel releases -- go
give it a spin
now!
Posted by Jakob Kummerow, Software Engineer
Labels
$200K
1
10th birthday
4
abusive ads
1
abusive notifications
2
accessibility
3
ad blockers
1
ad blocking
2
advanced capabilities
1
android
2
anti abuse
1
anti-deception
1
background periodic sync
1
badging
1
benchmarks
1
beta
83
better ads standards
1
billing
1
birthday
4
blink
2
browser
2
browser interoperability
1
bundles
1
capabilities
6
capable web
1
cds
1
cds18
2
cds2018
1
chrome
35
chrome 81
1
chrome 83
2
chrome 84
2
chrome ads
1
chrome apps
5
Chrome dev
1
chrome dev summit
1
chrome dev summit 2018
1
chrome dev summit 2019
1
chrome developer
1
Chrome Developer Center
1
chrome developer summit
1
chrome devtools
1
Chrome extension
1
chrome extensions
3
Chrome Frame
1
Chrome lite
1
Chrome on Android
2
chrome on ios
1
Chrome on Mac
1
Chrome OS
1
chrome privacy
4
chrome releases
1
chrome security
10
chrome web store
32
chromedevtools
1
chromeframe
3
chromeos
4
chromeos.dev
1
chromium
9
cloud print
1
coalition
1
coalition for better ads
1
contact picker
1
content indexing
1
cookies
1
core web vitals
2
csrf
1
css
1
cumulative layout shift
1
custom tabs
1
dart
8
dashboard
1
Data Saver
3
Data saver desktop extension
1
day 2
1
deceptive installation
1
declarative net request api
1
design
2
developer dashboard
1
Developer Program Policy
2
developer website
1
devtools
13
digital event
1
discoverability
1
DNS-over-HTTPS
4
DoH
4
emoji
1
emscriptem
1
enterprise
1
extensions
27
Fast badging
1
faster web
1
features
1
feedback
2
field data
1
first input delay
1
Follow
1
fonts
1
form controls
1
frameworks
1
fugu
2
fund
1
funding
1
gdd
1
google earth
1
google event
1
google io 2019
1
google web developer
1
googlechrome
12
harmful ads
1
html5
11
HTTP/3
1
HTTPS
4
iframes
1
images
1
incognito
1
insecure forms
1
intent to explain
1
ios
1
ios Chrome
1
issue tracker
3
jank
1
javascript
5
lab data
1
labelling
1
largest contentful paint
1
launch
1
lazy-loading
1
lighthouse
2
linux
2
Lite Mode
2
Lite pages
1
loading interventions
1
loading optimizations
1
lock icon
1
long-tail
1
mac
1
manifest v3
2
metrics
2
microsoft edge
1
mixed forms
1
mobile
2
na
1
native client
8
native file system
1
New Features
5
notifications
1
octane
1
open web
4
origin trials
2
pagespeed insights
1
pagespeedinsights
1
passwords
1
payment handler
1
payment request
1
payments
2
performance
20
performance tools
1
permission UI
1
permissions
1
play store
1
portals
3
prefetching
1
privacy
2
privacy sandbox
4
private prefetch proxy
1
profile guided optimization
1
progressive web apps
2
Project Strobe
1
protection
1
pwa
1
QUIC
1
quieter permissions
1
releases
3
removals
1
rlz
1
root program
1
safe browsing
2
Secure DNS
2
security
36
site isolation
1
slow loading
1
sms receiver
1
spam policy
1
spdy
2
spectre
1
speed
4
ssl
2
store listing
1
strobe
2
subscription pages
1
suspicious site reporter extension
1
TCP
1
the fast and the curious
23
TLS
1
tools
1
tracing
1
transparency
1
trusted web activities
1
twa
2
user agent string
1
user data policy
1
v8
6
video
2
wasm
1
web
1
web apps
1
web assembly
2
web developers
1
web intents
1
web packaging
1
web payments
1
web platform
1
web request api
1
web vitals
1
web.dev
1
web.dev live
1
webapi
1
webassembly
1
webaudio
3
webgl
7
webkit
5
WebM
1
webmaster
1
webp
5
webrtc
6
websockets
5
webtiming
1
writable-files
1
yerba beuna center for the arts
1
Archive
2024
Jun
May
Apr
Mar
Feb
2023
Nov
Oct
Sep
Aug
Jun
May
Apr
Feb
2022
Dec
Sep
Aug
Jun
May
Apr
Mar
Feb
Jan
2021
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2020
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2019
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2018
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2017
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2016
Dec
Nov
Oct
Sep
Aug
Jun
May
Apr
Mar
Feb
Jan
2015
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2014
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2013
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2012
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2011
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2010
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2009
Dec
Nov
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2008
Dec
Nov
Oct
Sep
Feed
Follow @ChromiumDev
Give us feedback in our
Product Forums
.