Utilizing Chrome’s accessibility APIs to seek out safety bugs

Utilizing Chrome’s accessibility APIs to seek out safety bugs


Chrome’s consumer interface (UI) code is advanced, and typically has bugs.

Are these bugs safety bugs? Particularly, if a consumer’s clicks and actions lead to reminiscence corruption, is that one thing that an attacker can exploit to hurt that consumer?

Our safety severity tips say “sure, typically.” For instance, an attacker may very possible persuade a consumer to click on an autofill immediate, however will probably be a lot more durable to persuade the consumer to step via a complete circulate of various dialogs.

Even when these bugs aren’t the most simply exploitable, it takes an excessive amount of time for our safety shepherds to make these determinations. Consumer interface bugs are sometimes flakey (that’s, not reliably reproducible). Additionally, even when these bugs aren’t essentially deemed to be exploitable, they might nonetheless be annoying crashes which trouble the consumer.

It might be nice if we may discover these bugs routinely.

If solely the entire tree of Chrome UI controls had been uncovered, someway, such that we may enumerate and work together with every UI management routinely.

Aha! Chrome exposes all of the UI controls to assistive know-how. Chrome goes to nice lengths to make sure its total UI is uncovered to display readers, braille gadgets and different such assistive tech. This tree of controls contains all of the toolbars, menus, and the construction of the web page itself. This structural definition of the browser consumer interface is already typically utilized in different contexts, for instance by some password managers, demonstrating that investing in accessibility has advantages for all customers. We’re now taking that funding and leveraging it to seek out safety bugs, too.

Particularly, we’re now “fuzzing” that accessibility tree – that’s, interacting with the completely different UI controls semi-randomly to see if we will make issues crash. This method has a lengthy pedigree.

Display reader know-how is a bit completely different on every platform, however on Linux the tree might be explored utilizing Accerciser.

Screenshot of Accerciser exhibiting the tree of UI controls in Chrome

All we’ve got to do is discover the identical tree of controls with a fuzzer. How onerous can it’s?

“We do that not as a result of it’s simple, however as a result of we thought it might be simple” – Anon.

Really we by no means thought this might be simple, and some completely different bits of tech have needed to fall into place to make this potential. Particularly,

  • There are many combos of how to work together with Chrome. Actually randomly clicking on UI controls in all probability gained’t discover bugs – we want to leverage coverage-guided fuzzing to assist the fuzzer choose combos of controls that appear to succeed in into new code inside Chrome.
  • We want any such bugs to be real. We due to this fact must fuzz the precise Chrome UI, or one thing very comparable, quite than exercising components of the code in an unrealistic unit-test-like context. That’s the place our InProcessFuzzer framework comes into play – it runs fuzz circumstances inside a Chrome browser_test; basically an actual model of Chrome.
  • However such browser_tests have a excessive startup value. We have to amortize that value over hundreds of take a look at circumstances by working a batch of them inside every browser invocation. Centipede is designed to try this.
  • However every take a look at case gained’t be idempotent. Inside a given invocation of the browser, the UI state could also be successively modified by every take a look at case. We intend so as to add concatenation to centipede to resolve this.
  • Chrome is a loud atmosphere with numerous timers, which can effectively confuse coverage-guided fuzzers. Gathering protection for such a big binary is sluggish in itself. So, we don’t know if coverage-guided fuzzing will efficiently discover the UI paths right here.

All of those issues are widespread to the opposite fuzzers which run within the browser_test context, most notably our new IPC fuzzer (weblog posts to observe). However the UI fuzzer introduced some particular challenges.

Discovering UI bugs is just helpful in the event that they’re actionable. Ideally, meaning:

  • Our fuzzing infrastructure offers an intensive set of diagnostics.
  • It may possibly bisect to seek out when the bug was launched and when it was mounted.
  • It may possibly reduce advanced take a look at circumstances into the smallest potential reproducer.
  • The take a look at case is descriptive and says which UI controls had been used, so a human might be able to reproduce it.

These necessities collectively imply that the take a look at circumstances needs to be steady throughout every Chrome model – if a given take a look at case reproduces a bug with Chrome 125, hopefully it would accomplish that in Chrome 124 and Chrome 126 (assuming the bug is current in each). But that is difficult, since Chrome UI controls are deeply nested and sometimes nameless.

Initially, the fuzzer picked controls merely based mostly on their ordinal at every stage of the tree (as an example “management 3 nested in management 5 nested in management 0”) however such take a look at circumstances are unlikely to be steady because the Chrome UI evolves. As a substitute, we settled on an method the place the controls are named, when potential, and in any other case recognized by a mixture of function and ordinal. This yields take a look at circumstances like this:

motion {
path_to_control {
named {
identify: “Check – Chromium”
}
}
path_to_control {
nameless {
function: “panel”
}
}
path_to_control {
nameless {
function: “panel”
}
}
path_to_control {
nameless {
function: “panel”
}
}
path_to_control {
named {
identify: “Bookmarks”
}
}
take_action {
action_id: 12
}
}

Fuzzers are unlikely to stumble throughout these management names by probability, even with the instrumentation utilized to string comparisons. In reality, this by-name method turned out to be solely 20% as efficient as choosing controls by ordinal. To resolve this we added a customized mutator which is sensible sufficient to place in place management names and roles that are identified to exist. We randomly use this mutator or the usual libprotobuf-mutator in an effort to get the most effective of each worlds. This method has confirmed to be about 80% as fast as the unique ordinal-based mutator, whereas offering steady take a look at circumstances.

Chart of code protection achieved by minutes fuzzing with completely different methods

So, does any of this work?

We don’t know but! – and you may observe alongside as we discover out. The fuzzer discovered a few potential bugs (presently entry restricted) within the accessibility code itself however hasn’t but explored far sufficient to find bugs in Chrome’s elementary UI. However, on the time of writing, this has solely been working on our ClusterFuzz infrastructure for a number of hours, and isn’t but engaged on our protection dashboard. In the event you’d prefer to observe alongside, regulate our protection dashboard because it expands to cowl UI code.

Leave a Reply

Your email address will not be published. Required fields are marked *