ladybird/Userland/Libraries/LibWeb/HTML/Scripting
Luke Wilde 7e701f6256 LibWeb: Keep unhandledrejection event promises alive when task is queued
This is fixed by making the "about to be notified rejected promises
list" use JS::Handle instead of JS::NonnullGCPtr. This UAF happens
because notify_about_rejected_promises makes a local copy of this list,
empties the member variable list and then moves the local copy into a
JS::SafeFunction lambda. JS::SafeFunction can only see GC pointers that
are in its storage, not external storage.

Example exploit (requires fixed microtask timing by removing the dummy
execution context):
```html
<script>
Promise.reject(new Error);

// Exit the script block, causing a microtask checkpoint and thus
// queuing of a task to fire the unhandled rejection event for the
// above promise.
// During the time after being queued but before being ran, these
// promises are not kept alive. This is because JS::SafeFunction cannot
// see into a Vector, meaning it can't visit the stored NonnullGCPtrs.
</script>

<script defer>
// Cause a garbage collection, destroying the above promise.
const b = [];
for (var i = 0; i < 200000; i++)
    b.push({});

// Some time after this script block, the queued unhandled rejection
// event task will fire, with the event object containing the dead
// promise.
window.onunhandledrejection = (event) => {
    let value = event.promise;
    console.log(value);
}
</script>
```
2022-12-25 15:32:51 +01:00
..
ClassicScript.cpp LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
ClassicScript.h WebContent+LibWeb+LibJS: Simplify injection of JS console globals 2022-12-09 18:51:03 +00:00
Environments.cpp LibWeb: Keep unhandledrejection event promises alive when task is queued 2022-12-25 15:32:51 +01:00
Environments.h LibWeb: Keep unhandledrejection event promises alive when task is queued 2022-12-25 15:32:51 +01:00
ExceptionReporter.cpp LibJS: Reduce AST memory usage by shrink-wrapping source range info 2022-11-22 21:13:35 +01:00
ExceptionReporter.h WebContent+LibWeb+LibJS: Report exceptions to the JS console 2022-10-15 01:25:12 +02:00
Fetching.cpp AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
Fetching.h AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
ImportMap.h AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
ModuleMap.cpp AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
ModuleMap.h Everywhere: Rename to_{string => deprecated_string}() where applicable 2022-12-06 08:54:33 +01:00
ModuleScript.cpp LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
ModuleScript.h AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
Script.cpp AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
Script.h AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
WindowEnvironmentSettingsObject.cpp LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
WindowEnvironmentSettingsObject.h AK+Everywhere: Rename String to DeprecatedString 2022-12-06 08:54:33 +01:00
WorkerEnvironmentSettingsObject.h LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00