The Basics

Disclosure or Patch Date: 25 March 2022

Product: Google Chromium

Advisory: https://chromereleases.googleblog.com/2022/03/stable-channel-update-for-desktop_25.html

Affected Versions: pre 99.0.4844.84

First Patched Version: 99.0.4844.84

Issue/Bug Report: https://bugs.chromium.org/p/chromium/issues/detail?id=1309225

Patch CL: https://chromium.googlesource.com/v8/v8/+/0981e91a4f8692af337e2588562ad1504f4bffdc

Bug-Introducing CL: N/A

Reporter(s): Anonymous

The Code

Proof-of-concept:

style = document.createElement('p').style;
style.prop = { toString: () => {
  style.prop = 1;
}};

Exploit sample: N/A

Access to the exploit sample? No

The Vulnerability

Bug class: Logic/design issue

Vulnerability details:

This vulnerability can be triggered through property access interceptor for CSSStyleDeclaration objects. The property access interceptor is a method that runs anytime that a property of the object is accessed. The interceptor can lead to user JavaScript execution during the property assignment process. For CVE-2022-1096 specifically, if the object doesn't have a property with the specified name, it can be added during the user JavaScript execution in the interceptor. The vulnerability itself is in the property access interceptor support in V8. The issue is that the interceptor doesn't re-check the status of the property after the user's JavaScript runs; the execution continues as if the property still doesn't exist. The property is then added to the object a second time leading to a corrupted object, which was then used to gain remote code execution.

The vulnerability is the same as 2021 in-the-wild 0-day, CVE-2021-30551, just accessed differently. The code path patched for CVE-2021-30551 was only if the property was in the object's prototype chain. This time the vulnerability was exploited using a property that is directly owned by the object rather than in its prototype chain.

Patch analysis:

To fix CVE-2021-30551 in 2021, the SetSuperProperty call was added after the interceptor (and user JavaScript) would run in SetPropertyInternal. SetSuperProperty can correctly handle if the object and property state has changed due to user JavaScript running. To patch, CVE-2022-1096, the SetSuperProperty call was moved in order to be called in both cases in SetPropertyInternal: when the property is directly owned by the object and when the property is in the object's prototype chain, rather than just when the object is in the object's prototype chain.

This fix was insufficient though. SetPropertyInternal is only used when something is being directly assigned to a property like in the syntax: obj.prop = x. A different function, DefineOwnPropertyIgnoreAttributes is called when a property is assigned to a value using Object.defineProperty instead. This was fixed as CVE-2022-1232.

Thoughts on how this vuln might have been found (fuzzing, code auditing, variant analysis, etc.):

Since the same root cause bug was discovered as exploited in-the-wild in 2021, it seems likely that this vulnerability was found via variant analysis. When looking at the patch for CVE-2021-30551 it's clear that the fix only covered one of the "if/else" branches in SetPropertyInternal. So it seems reasonable to search to see if the same vulnerability could be exploited via the other "if/else" branch, which is what happened here.

(Historical/present/future) context of bug:

  • CVE-2016-5128 - Security researcher reported bug in the property access interceptor for HTMLEmbedElement
  • CVE-2021-30551 - 2021 in-the-wild 0-day in property access interceptor for HTMLEmbedElement
  • CVE-2022-1096 (this bug) - 2022 in-the-wild 0-day in property access interceptor for CSSStyleDeclaration. Exploiting same root cause bug as CVE-2021-30551
  • CVE-2022-1232 - CVE-2022-1096 was incompletely fixed. This patched a variant.

The Exploit

(The terms exploit primitive, exploit strategy, exploit technique, and exploit flow are defined here.)

Exploit strategy (or strategies): Unknown because I didn't have access to the exploit, but likely the same as CVE-2021-30551.

Exploit flow:

Known cases of the same exploit flow:

Part of an exploit chain?

The Next Steps

Variant analysis

Areas/approach for variant analysis (and why):

  • Checking other object types to see if they follow different property access interceptor paths
  • Check other browsers for similar issues

Found variants: N/A

Structural improvements

What are structural improvements such as ways to kill the bug class, prevent the introduction of this vulnerability, mitigate the exploit flow, make this type of vulnerability harder to exploit, etc.?

Ideas to kill the bug class:

The ability to run user scripts that may synchronously modify the process state at an unexpected time is a fundamental problem in any software with scripting capabilities, especially web browsers. Chrome mitigates this bug class by putting DisallowJavascriptExecution scope objects in critical parts of the browser to block user JavaScript execution. The main challenge with this approach is to proactively identify all those critical parts.

Ideas to mitigate the exploit flow: N/A

Other potential improvements:

0-day detection methods

What are potential detection methods for similar 0-days? Meaning are there any ideas of how this exploit or similar exploits could be detected as a 0-day?

Other References