{"id":54194,"date":"2023-10-18T16:06:26","date_gmt":"2023-10-18T16:06:26","guid":{"rendered":"https:\/\/packetstormsecurity.com\/news\/view\/35134\/Getting-RCE-In-Chrome-With-Incomplete-Object-Initialization-In-The-Maglev-Compiler.html"},"modified":"2023-10-18T16:06:26","modified_gmt":"2023-10-18T16:06:26","slug":"getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler","status":"publish","type":"post","link":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/","title":{"rendered":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler"},"content":{"rendered":"<p><head> <meta charset=\"UTF-8\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <link rel=\"profile\" href=\"https:\/\/gmpg.org\/xfn\/11\"> <link rel=\"icon\" type=\"image\/x-icon\" href=\"https:\/\/github.githubassets.com\/favicon.ico\"> <meta name=\"robots\" content=\"index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1\"> <!-- This site is optimized with the Yoast SEO Premium plugin v21.2 (Yoast SEO v21.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ --> <title>Getting RCE in Chrome with incomplete object initialization in the Maglev compiler &#8211; The GitHub Blog<\/title> <meta name=\"description\" content=\"In this post, I'll exploit CVE-2023-4069, a type confusion in Chrome that allows remote code execution (RCE) in the renderer sandbox of Chrome by a single visit to a malicious site.\"> <link rel=\"canonical\" href=\"https:\/\/github.blog\/2023-10-17-getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/\"> <meta property=\"og:locale\" content=\"en_US\"> <meta property=\"og:type\" content=\"article\"> <meta property=\"og:title\" content=\"Getting RCE in Chrome with incomplete object initialization in the Maglev compiler\"> <meta property=\"og:description\" content=\"In this post, I'll exploit CVE-2023-4069, a type confusion in Chrome that allows remote code execution (RCE) in the renderer sandbox of Chrome by a single visit to a malicious site.\"> <meta property=\"og:url\" content=\"https:\/\/github.blog\/2023-10-17-getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/\"> <meta property=\"og:site_name\" content=\"The GitHub Blog\"> <meta property=\"article:published_time\" content=\"2023-10-17T15:00:55+00:00\"> <meta property=\"article:modified_time\" content=\"2023-10-17T14:24:05+00:00\"> <meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?fit=1200%2C630\"> <meta property=\"og:image:width\" content=\"1200\"> <meta property=\"og:image:height\" content=\"630\"> <meta property=\"og:image:type\" content=\"image\/png\"> <meta name=\"author\" content=\"Man Yue Mo\"> <meta name=\"twitter:card\" content=\"summary_large_image\"> <meta name=\"twitter:label1\" content=\"Written by\"> <meta name=\"twitter:data1\" content=\"Man Yue Mo\"> <meta name=\"twitter:label2\" content=\"Est. reading time\"> <meta name=\"twitter:data2\" content=\"13 minutes\"> <!-- \/ Yoast SEO Premium plugin. --> <link rel=\"dns-prefetch\" href=\"\/\/cdnjs.cloudflare.com\">\n<link rel=\"dns-prefetch\" href=\"\/\/analytics.githubassets.com\">\n<link rel=\"dns-prefetch\" href=\"\/\/stats.wp.com\">\n<link rel=\"dns-prefetch\" href=\"\/\/v0.wordpress.com\">\n<link rel=\"alternate\" type=\"application\/rss+xml\" title=\"The GitHub Blog \u00bb Feed\" href=\"https:\/\/github.blog\/feed\/\">\n<link rel=\"alternate\" type=\"application\/rss+xml\" title=\"The GitHub Blog \u00bb Comments Feed\" href=\"https:\/\/github.blog\/comments\/feed\/\"> <link rel=\"stylesheet\" id=\"all-css-0\" href=\"https:\/\/github.blog\/wp-includes\/css\/dist\/block-library\/style.min.css?m=1697500969g\" type=\"text\/css\" media=\"all\"> <link rel=\"stylesheet\" id=\"all-css-6\" href=\"https:\/\/github.blog\/wp-content\/themes\/github-2021\/assets\/css\/site.min.css?m=1696345416g\" type=\"text\/css\" media=\"all\">\n<link rel=\"stylesheet\" id=\"highlightjs-css-css\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/highlight.js\/11.4.0\/styles\/default.min.css?ver=11.4.0\" media=\"all\">\n<link rel=\"stylesheet\" id=\"all-css-8\" href=\"https:\/\/github.blog\/wp-content\/mu-plugins\/jetpack-12.6\/css\/jetpack.css?m=1697569669g\" type=\"text\/css\" media=\"all\">\n<link rel=\"https:\/\/api.w.org\/\" href=\"https:\/\/github.blog\/wp-json\/\"><link rel=\"alternate\" type=\"application\/json\" href=\"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/74790\"><link rel=\"EditURI\" type=\"application\/rsd+xml\" title=\"RSD\" href=\"https:\/\/github.blog\/xmlrpc.php?rsd\">\n<meta name=\"generator\" content=\"WordPress 6.3.2\">\n<link rel=\"shortlink\" href=\"https:\/\/wp.me\/pamS32-jsi\">\n<link rel=\"alternate\" type=\"application\/json+oembed\" href=\"https:\/\/github.blog\/wp-json\/oembed\/1.0\/embed?url=https%3A%2F%2Fgithub.blog%2F2023-10-17-getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler%2F\">\n<link rel=\"alternate\" type=\"text\/xml+oembed\" href=\"https:\/\/github.blog\/wp-json\/oembed\/1.0\/embed?url=https%3A%2F%2Fgithub.blog%2F2023-10-17-getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler%2F&amp;format=xml\"> <meta name=\"ha-url\" content=\"https:\/\/collector.githubapp.com\/github-blog\/collect\"><link rel=\"preload\" href=\"https:\/\/github.blog\/wp-content\/themes\/github-2021\/assets\/fonts\/alliance\/Alliance-No-1-ExtraBold.woff2\" as=\"font\" type=\"font\/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"https:\/\/github.blog\/wp-content\/themes\/github-2021\/assets\/fonts\/alliance\/Alliance-No-1-Bold.woff2\" as=\"font\" type=\"font\/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"https:\/\/github.blog\/wp-content\/themes\/github-2021\/assets\/fonts\/alliance\/Alliance-No-1-Regular.woff2\" as=\"font\" type=\"font\/woff2\" crossorigin=\"anonymous\"><link rel=\"icon\" href=\"https:\/\/github.blog\/wp-content\/uploads\/2019\/01\/cropped-github-favicon-512.png?fit=32%2C32\" sizes=\"32x32\">\n<link rel=\"icon\" href=\"https:\/\/github.blog\/wp-content\/uploads\/2019\/01\/cropped-github-favicon-512.png?fit=192%2C192\" sizes=\"192x192\">\n<link rel=\"apple-touch-icon\" href=\"https:\/\/github.blog\/wp-content\/uploads\/2019\/01\/cropped-github-favicon-512.png?fit=180%2C180\">\n<meta name=\"msapplication-TileImage\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2019\/01\/cropped-github-favicon-512.png?fit=270%2C270\"><br \/>\n<\/head><body class=\"post-template-default single single-post postid-74790 single-format-standard font-mktg no-sidebar\" id=\"readabilityBody\"> <\/p>\n<section class=\"position-relative\" data-color-mode=\"dark\" data-light-theme=\"light\" data-dark-theme=\"dark_dimmed\">\n<div class=\"container-xl p-responsive-blog\">\n<div class=\"gutter-spacious pt-1 \" readability=\"7.0953237410072\">\n<div class=\"col-12 offset-lg-1 col-lg-10 col-xl-7 mt-5 mt-lg-10 mb-6 mb-lg-8\" readability=\"9.4604316546763\">\n<ul class=\"d-inline-block list-style-none mb-12px post-hero__categories\">\n<li class=\"d-inline-block mr-3\"><a href=\"https:\/\/github.blog\/category\/company\/\" class=\"f4-mktg text-gradient-purple-coral text-bold\">Company<\/a><\/li>\n<li class=\"d-inline-block mr-3\"><a href=\"https:\/\/github.blog\/category\/security\/\" class=\"f4-mktg text-gradient-purple-coral text-bold\">Security<\/a><\/li>\n<\/ul>\n<p class=\"f4-mktg\">In this post, I&#8217;ll exploit CVE-2023-4069, a type confusion in Chrome that allows remote code execution (RCE) in the renderer sandbox of Chrome by a single visit to a malicious site.<\/p>\n<\/p><\/div>\n<div class=\"offset-lg-1 col-lg-10\">\n<div class=\"position-relative z-1\"> <svg aria-hidden=\"true\" width=\"1032\" height=\"548\" class=\"width-full height-auto d-block\" \/><\/svg> <img loading=\"lazy\" decoding=\"async\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?resize=800%2C425 800w, https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?resize=1200%2C630 1600w\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?resize=1200%2C630\" width=\"1600\" height=\"850\" alt=\"Getting RCE in Chrome with incomplete object initialization in the Maglev compiler\" class=\"cover-image rounded-2\"> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/section>\n<section class=\"container-xl mx-auto p-responsive-blog\">\n<div class=\"gutter-spacious\">\n<div class=\"col-12 offset-lg-1 col-lg-10\">\n<p>Author<\/p>\n<div class=\"d-flex flex-nowrap pb-1 flex-items-start\"> <time datetime=\"2023-10-17\" class=\"d-block border-left flex-shrink-0 text-mono f5-mktg color-fg-muted mb-3\"> October 17, 2023 <\/time> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/section>\n<div class=\"container-xl mx-auto p-responsive-blog mt-4 mt-md-7 mb-7 mb-md-9\">\n<div class=\"d-flex flex-wrap gutter-spacious\"> <main role=\"main\" id=\"post-74790\" class=\"col-12 col-lg-7 post__content col-md-8 post-74790 post type-post status-publish format-standard has-post-thumbnail hentry category-company category-security tag-chrome tag-exploit-development tag-github-security-lab\"> <html readability=\"233.66399158006\"><body readability=\"468.22474281192\"><\/p>\n<p>In this post I\u2019ll exploit CVE-2023-4069, a type confusion vulnerability that I reported in July 2023. The vulnerability\u2014which allows remote code execution (RCE) in the renderer sandbox of Chrome by a single visit to a malicious site\u2014is found in <a href=\"https:\/\/v8.dev\/\">v8<\/a>, the Javascript engine of Chrome. It was filed as <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=1465326\">bug 1465326<\/a> and subsequently fixed in version <a href=\"https:\/\/chromereleases.googleblog.com\/2023\/08\/stable-channel-update-for-desktop.html\">115.0.5790.170\/.171<\/a>.<\/p>\n<p>Vulnerabilities like this are often the starting point for a \u201cone-click\u201d exploit, which compromises the victim\u2019s device when they visit a malicious website. What\u2019s more, renderer RCE in Chrome allows an attacker to compromise and execute arbitrary code in the Chrome renderer process. That being said, the renderer process has limited privilege and such a vulnerability needs to be chained with a second \u201csandbox escape\u201d vulnerability (either another vulnerability in the Chrome browser process or one in the operating system) to compromise Chrome itself or the device.<\/p>\n<p>While many of the most powerful and sophisticated \u201cone-click\u201d attacks are highly targeted, and average users may be more at risk from less sophisticated attacks such as phishing, users should still keep Chrome up-to-date and enable automatic updates, as vulnerabilities in v8 can often be exploited relatively quickly.<\/p>\n<p>The current vulnerability, CVE-2023-4069, exists in the Maglev compiler, a new mid-tier JIT compiler in Chrome that optimizes Javascript functions based on previous knowledge of the input types. This kind of optimization is called speculative optimization and care must be taken to make sure that these assumptions on the inputs are still valid when the optimized code is used. The complexity of the JIT engine has led to many security issues in the past and has been a popular target for attackers.<\/p>\n<h2 id=\"maglev-compiler\">Maglev compiler<\/h2>\n<p>The <a href=\"https:\/\/docs.google.com\/document\/d\/13CwgSL4yawxuYg3iNlM-4ZPCB8RgJya6b8H_E2F-Aek\/edit#heading=h.djws22xta9wz\">Maglev compiler<\/a> is a mid-tier JIT compiler used by v8. Compared to the top-tier JIT compiler, <a href=\"https:\/\/v8.dev\/docs\/turbofan\">TurboFan<\/a>, Maglev generates less optimized code but with a faster compilation speed. Having multiple JIT compilers is common in Javascript engines, the idea being that with multiple tier compilers, you\u2019ll find a more optimal tradeoff between compilation time and runtime optimization.<\/p>\n<p>Generally speaking, when a function is first run, slow bytecode is generated, as the function is run more often, it may get compiled into more optimized code, first from a lowest-tier JIT compiler. If the function gets used more often, then its optimization tier gets moved up, resulting in better runtime performance\u2014but at the expense of a longer compilation time. The idea here is that for code that runs often, the runtime cost will likely outweigh the compile time cost. You can consult <a href=\"https:\/\/ponyfoo.com\/articles\/an-introduction-to-speculative-optimization-in-v8\">An Introduction to Speculative Optimization in v8<\/a> by Benedikt Meurer for more details of how the compilation process works.<\/p>\n<p>The Maglev compiler is enabled by default starting from version 114 of Chrome. Similar to TurboFan, it goes through the bytecode of a Javascript function, taking into account the feedback that was collected from previous runs, and transforms the bytecode into more optimized code. However, unlike TurboFan, which first transforms bytecodes into a <a href=\"https:\/\/darksi.de\/d.sea-of-nodes\/\">\u201cSea of Nodes\u201d<\/a>, Maglev uses an intermediate representation and first transforms bytecodes into SSA (Static Single-Assignment) nodes, which are declared in the file <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/376123191e0361a8639c1783abcf2490a506c748:v8\/src\/maglev\/maglev-ir.h\">maglev-ir.h<\/a>. At the time of writing, the compilation process of Maglev consists mainly of two phases of optimizations: the first phase involves <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/376123191e0361a8639c1783abcf2490a506c748:v8\/src\/maglev\/maglev-compiler.cc;l=403\">building a graph<\/a> from the SSA nodes, while the second phase consists of <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/376123191e0361a8639c1783abcf2490a506c748:v8\/src\/maglev\/maglev-compiler.cc;l=421\">optimizing the representations of Phi values<\/a>.<\/p>\n<h2 id=\"object-construction-in-v8\">Object construction in v8<\/h2>\n<p>The bug in this post really has more to do with object constructions than with Maglev, so now I\u2019ll go through more details and some concepts of how v8 handles Javascript constructions. A Javascript function can be used as a constructor and called with the <code>new<\/code> keyword. When it is called with <code>new<\/code>, the <code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/new.target\">new.target<\/a><\/code> variable exists in the function scope that specifies the function being called with <code>new<\/code>. In the following case, <code>new.target<\/code> is the same as the function itself.<\/p>\n<pre><code class=\"language-javascript\">function foo() { %DebugPrint(new.target);\n}\nnew foo(); \/\/ foo\nfoo(); \/\/ undefined\n<\/code><\/pre>\n<p>This, however, is not always the case and <code>new.target<\/code> may be different from the function itself. For example, in case of a construction via a derived constructor:<\/p>\n<pre><code class=\"language-javascript\">\nclass A { constructor() { %DebugPrint(new.target); }\n} class B extends A {\n} new A(); \/\/ A\nnew B(); \/\/ B\n<\/code><\/pre>\n<p>Another way to have a different <code>new.target<\/code> is to use the <code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Reflect\/construct\">Reflect.construct<\/a><\/code> built-in function:<\/p>\n<pre><code class=\"language-javascript\">\nReflect.construct(A, [], B); \/\/ B\n<\/code><\/pre>\n<p>The signature of <code>Reflect.construct<\/code> is as follows, which specifies <code>newTarget<\/code> as the <code>new.target<\/code>:<\/p>\n<pre><code class=\"language-javascript\">\nReflect.construct(target, argumentsList, newTarget)\n<\/code><\/pre>\n<p>The <code>Reflect.construct<\/code> method sheds some light on the role of <code>new.target<\/code> in object construction. According to the documentation, <code>target<\/code> is the constructor that is actually executed to create and initialize an object, while <code>newTarget<\/code> provides the <code>prototype<\/code> for the created object. For example, the following creates a <code>Function<\/code> type object and only <code>Function<\/code> is called.<\/p>\n<pre><code class=\"language-javascript\">\nvar x = Reflect.construct(Function, [], Array);\n<\/code><\/pre>\n<p>This is consistent with construction via class inheritance:<\/p>\n<pre><code class=\"language-javascript\">\nclass A {} class B extends A {} var x = new B();\nconsole.log(x.__proto__ == B.prototype); \/\/&lt;--- true\n<\/code><\/pre>\n<p>Although in this case, the derived constructor <code>B<\/code> does get called. So what is the object that\u2019s actually created? For functions that actually return a value, or for class constructors, the answer is more clear:<\/p>\n<pre><code class=\"language-javascript\">\nfunction foo() {return [1,2];}\nfunction bar() {}\nvar x = Reflect.construct(foo, [], bar); \/\/&lt;--- returns [1,2]\n<\/code><\/pre>\n<p>but less so otherwise:<\/p>\n<pre><code class=\"language-javascript\">\nfunction foo() {}\nfunction bar() {}\nvar x = Reflect.construct(foo, [], bar); \/\/&lt;--- returns object {}, instead of undefined\n<\/code><\/pre>\n<p>So even if a function does not return an object, using it as <code>target<\/code> in <code>Reflect.construct<\/code> still creates a Javascript object. Roughly speaking, object constructions follow these steps: (see, for example, <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/0e4c9a3d8b9194c4885a1576fce9e0dc9004a22c:v8\/src\/builtins\/x64\/builtins-x64.cc;l=146\">Generate_JSConstructStubGeneric<\/a><\/code>.)<\/p>\n<p>First a default <code>receiver<\/code> (the <code>this<\/code> object) is created using <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/79c9dc7ddf20ae484798ec359d62aafb09a8c291:v8\/src\/builtins\/builtins-constructor-gen.cc;l=260;bpv=0;bpt=0\">FastNewObject<\/a><\/code>, and then the <code>target<\/code> function is invoked. If the <code>target<\/code> function returns an object, then the default <code>receiver<\/code> is discarded and the return value of <code>target<\/code> is used as the returned object instead; otherwise, the default <code>receiver<\/code> is returned.<\/p>\n<h3 id=\"default-receiver-object\">Default <code>receiver<\/code> object<\/h3>\n<p>The default <code>receiver<\/code> object created by <code>FastNewObject<\/code> is relevant to this bug, so I\u2019ll explain it in a bit more detail. Most Javascript functions contain an internal field, <code>initial_map<\/code>. This is a <code>Map<\/code> object that determines the type and the memory layout of the default <code>receiver<\/code> object created by this function. In v8, <code>Map<\/code> determines the hidden type of an object, in particular, its memory layout and the storage of its fields. Readers can consult \u201c<a href=\"https:\/\/mathiasbynens.be\/notes\/shapes-ics\">JavaScript engine fundamentals: Shapes and Inline Caches<\/a>\u201d by Mathias Bynens to get a high-level understanding of object types and maps.<\/p>\n<p>When creating the default <code>receiver<\/code> object, <code>FastNewObject<\/code> will try to use the <code>initial_map<\/code> of <code>new.target<\/code> (<code>new_target<\/code>) as the <code>Map<\/code> for the default <code>receiver<\/code>:<\/p>\n<pre><code class=\"language-javascript\">\nTNode ConstructorBuiltinsAssembler::FastNewObject( TNode context, TNode target, TNode new_target, Label* call_runtime) { \/\/ Verify that the new target is a JSFunction. Label end(this); TNode new_target_func = HeapObjectToJSFunctionWithPrototypeSlot(new_target, call_runtime); ... GotoIf(DoesntHaveInstanceType(CAST(initial_map_or_proto), MAP_TYPE), call_runtime); TNode<map> initial_map = CAST(initial_map_or_proto); TNode<\/map><\/code><\/pre>\n<p>This is curious, as the default <code>receiver<\/code> should have been created using <code>target<\/code> and <code>new_target<\/code> should only be used to set its <code>prototype<\/code>. The reason for this is because of an optimization that caches both the <code>initial_map<\/code> of <code>target<\/code> and the <code>prototype<\/code> of <code>new_target<\/code> in the <code>initial_map<\/code> of <code>new_target<\/code>, which I\u2019ll explain now.<\/p>\n<p>In the above, <code>FastNewObject<\/code> has a check (marked as \u201ccheck\u201d in the above snippet) that makes sure that <code>target<\/code> is the same as the <code>constructor<\/code> field of the <code>initial_map<\/code>. For most functions, <code>initial_map<\/code> is created lazily, or its <code>constructor<\/code> field is pointing to itself (<code>new_target<\/code> in this case). So when <code>new_target<\/code> is first used to construct an object with a different <code>target<\/code>, the <code>call_runtime<\/code> slow path is likely taken, which uses <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/ba1b4d2b303094d63f500878f3670f2235f988c7:v8\/src\/objects\/js-objects.cc;l=2374\">JSObject::New<\/a><\/code>:<\/p>\n<pre><code class=\"language-javascript\">\nMaybeHandle JSObject::New(Handle constructor, Handle new_target, Handle site) { ... Handle<map> initial_map; ASSIGN_RETURN_ON_EXCEPTION( isolate, initial_map, JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject); ... Handle result = isolate-&gt;factory()-&gt;NewFastOrSlowJSObjectFromMap( initial_map, initial_capacity, AllocationType::kYoung, site); return result;\n}\n<\/map><\/code><\/pre>\n<p>This function calls <code>GetDerivedMap<\/code>, which may call <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/79c9dc7ddf20ae484798ec359d62aafb09a8c291:v8\/src\/objects\/js-function.cc;l=1037\">FastInitializeDerivedMap<\/a><\/code> to create an <code>initial_map<\/code> in the <code>new_target<\/code>:<\/p>\n<pre><code class=\"language-javascript\">\nbool FastInitializeDerivedMap(Isolate* isolate, Handle new_target, Handle constructor, Handle<map> constructor_initial_map) { ... Handle<map> map = Map::CopyInitialMap(isolate, constructor_initial_map, instance_size, in_object_properties, unused_property_fields); map-&gt;set_new_target_is_base(false); Handle prototype(new_target-&gt;instance_prototype(), isolate); \/\/Also sets map.prototype to prototype and map.constructor to constructor JSFunction::SetInitialMap(isolate, new_target, map, prototype, constructor); ...\n<\/map><\/map><\/code><\/pre>\n<p>The <code>initial_map<\/code> created here is a copy of the <code>initial_map<\/code> of <code>target<\/code> (<code>constructor<\/code>), but with its <code>prototype<\/code> set to the <code>prototype<\/code> of <code>new_target<\/code> and its <code>constructor<\/code> set to <code>target<\/code>. This is the only case when the <code>constructor<\/code> of an <code>initial_map<\/code> points to a function other than itself and provides the context for the <code>initial_map<\/code> of <code>new_target<\/code> to be used in <code>FastNewObject<\/code>: if the <code>constructor<\/code> of an <code>initial_map<\/code> points to a different function, then the <code>initial_map<\/code> is a copy of the <code>initial_map<\/code> of the <code>constructor<\/code>. Checking that <code>new_target.initial_map.constructor<\/code> equals <code>target<\/code>, <code>FastNewObject<\/code> ensures that the <code>initial_map<\/code> of <code>new_target<\/code> is a copy of <code>target.initial_map<\/code>, but with <code>new_target.prototype<\/code> as its <code>prototype<\/code>, which is the correct <code>Map<\/code> to use.<\/p>\n<h3 id=\"the-vulnerability\">The vulnerability<\/h3>\n<p>Derived classes often have no-op default constructors, which do not modify <code>receiver<\/code> objects, for example:<\/p>\n<pre><code class=\"language-javascript\">\nclass A {}\nclass B extends A {}\nclass C extends B {}\nconst o = new C();\n<\/code><\/pre>\n<p>In this case, when calling <code>new C()<\/code>, the default constructor calls to <code>B<\/code> and <code>A<\/code> are no-op and can be omitted. The <code><a href=\"https:\/\/source.chromium.org\/chromium\/_\/chromium\/v8\/v8.git\/+\/b1553b9188afd9bdc6bb3daf0956770ff82b6fd0\">FindNonDefaultConstructorOrConstruct<\/a><\/code> bytecode is an optimization to omit redundant calls to no-op default constructors in these cases. In essence, it walks up the chain of super constructors and skips the default constructors that can be omitted. If it can skip all the intermediate default constructors and reach the base constructor, then <code>FastNewObject<\/code> is called to create the default <code>receiver<\/code> object. The bytecode is introduced in a derived class constructor:<\/p>\n<pre><code class=\"language-javascript\">\nclass A {}\nclass B extends A {}\nnew B();\n<\/code><\/pre>\n<p>Running the above with the <code>print-bytecode<\/code> flag in <code>d8<\/code> (the standalone version of v8), I can see that <code>FindNonDefaultConstructorOrConstruct<\/code> is inserted in the bytecode of the derived constructor <code>B<\/code>:<\/p>\n<pre><code class=\"language-javascript\">\n[generated bytecode for function: B (0x1a820019ba41 )]\nBytecode length: 45\nParameter count 1\nRegister count 7\nFrame size 56 0x1a820019be6c @ 0 : 19 fe f9 Mov , r1 1700 S&gt; 0x1a820019be6f @ 3 : 5a f9 fa f5 FindNonDefaultConstructorOrConstruct r1, r0, r5-r6 ... 0x1a820019be7e @ 18 : 99 0c JumpIfTrue [12] (0x1a820019be8a @ 30) ... 0x1a820019be8a @ 30 : 0b 02 Ldar 0x1a820019be8c @ 32 : ad ThrowSuperAlreadyCalledIfNotHole 0x1a820019be8d @ 33 : 19 f7 02 Mov r3, 1713 S&gt; 0x1a820019be90 @ 36 : 0d 01 LdaSmi [1] 1720 E&gt; 0x1a820019be92 @ 38 : 32 02 00 02 SetNamedProperty , [0], [2] 0x1a820019be96 @ 42 : 0b 02 Ldar 1727 S&gt; 0x1a820019be98 @ 44 : aa Return\n<\/code><\/pre>\n<p>In particular, if <code>FindNonDefaultConstructorOrConstruct<\/code> succeeds (returns <code>true<\/code>), then the default <code>receiver<\/code> object will be returned immediately.<\/p>\n<p>The vulnerability happens in the handling of <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8\/src\/maglev\/maglev-graph-builder.cc;l=5350;bpv=0\">FindNonDefaultConstructorOrConstruct<\/a><\/code> in Maglev.<\/p>\n<pre><code class=\"language-javascript\">\nvoid MaglevGraphBuilder::VisitFindNonDefaultConstructorOrConstruct() { ... compiler::OptionalHeapObjectRef new_target_function = TryGetConstant(new_target); if (kind == FunctionKind::kDefaultBaseConstructor) { ValueNode* object; if (new_target_function &amp;&amp; new_target_function-&gt;IsJSFunction()) { object = BuildAllocateFastObject( FastObject(new_target_function-&gt;AsJSFunction(), zone(), broker()), AllocationType::kYoung); ...\n<\/code><\/pre>\n<p>If it manages to skip all the default constructors and reach the base constructor, then it\u2019ll check whether <code>new_target<\/code> is a constant. If that is the case, then <code>BuildAllocateFastObject<\/code>, instead of <code>FastNewObject<\/code>, is used to create the <code>receiver<\/code> object. The problem is that, unlike <code>FastNewObject<\/code>, <code>BuildAllocateFastObject<\/code> uses the <code>initial_map<\/code> of <code>new_target<\/code> without checking its <code>constructor<\/code> field:<\/p>\n<pre><code class=\"language-javascript\">\nValueNode* MaglevGraphBuilder::BuildAllocateFastObject( FastObject object, AllocationType allocation_type) { ... ValueNode* allocation = ExtendOrReallocateCurrentRawAllocation( object.instance_size, allocation_type); BuildStoreReceiverMap(allocation, object.map); \/\/ new_target.initial_map ... return allocation;\n}\n<\/code><\/pre>\n<p>Why is this bad? As explained before, when constructing an object, <code>target<\/code>, rather than <code>new_target<\/code>, is called to initialize the object fields. If <code>new_target<\/code> is not of the same type as <code>target<\/code>, then creating an object with the <code>initial_map<\/code> of <code>new_target<\/code> can leave fields uninitialized:<\/p>\n<pre><code class=\"language-javascript\">\nclass A {}\nclass B extends A {}\nvar x = Reflect.construct(B, [], Array);\n<\/code><\/pre>\n<p>In this case, <code>new_target<\/code> is <code>Array<\/code>, so if the <code>initial_map<\/code> of <code>new_target<\/code> is used to create <code>x<\/code> (<code>receiver<\/code>), then <code>x<\/code> is going to be an <code>Array<\/code> type object, which has a field <code>length<\/code> that specifies the size of the array and is used for bounds checking. If <code>B<\/code>, which is the <code>target<\/code>, is used to initialize the <code>Array<\/code> object, then <code>length<\/code> would become uninitialized. This problematic scenario is prevented by checking the <code>constructor<\/code> of <code>new_target.initial_map<\/code> to make sure that it is <code>B<\/code>, and the absence of the check in Maglev results in the vulnerability.<\/p>\n<p>There is one problem here: I need <code>new_target<\/code> to be a constant to reach this code, but when used with <code>Reflect.construct<\/code>, <code>new_target<\/code> is an argument to the function and is never going to be a constant. To overcome this, let\u2019s take a look at what <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8\/src\/maglev\/maglev-graph-builder.cc;l=2234;bpv=0\">TryGetConstant<\/a><\/code>, which is used in <code>FindNonDefaultConstructorOrConstruct<\/code> to check that <code>new_target<\/code> is a constant, does:<\/p>\n<pre><code class=\"language-javascript\">\ncompiler::OptionalHeapObjectRef MaglevGraphBuilder::TryGetConstant( ValueNode* node, ValueNode** constant_node) { if (auto result = TryGetConstant(broker(), local_isolate(), node)) { \/\/&lt;--- 1. if (constant_node) *constant_node = node; return result; } const NodeInfo* info = known_node_aspects().TryGetInfoFor(node); \/\/is_constant()) { if (constant_node) *constant_node = info-&gt;constant_alternative; return TryGetConstant(info-&gt;constant_alternative); } return {};\n}\n<\/code><\/pre>\n<p>When checking whether a node is constant, <code>TryGetConstant<\/code> first checks if the node is a known global constant (marked as 1. in the above), which will be false in our case. However, it also checks <code>NodeInfo<\/code> for the node to see if it has been marked as a constant by other nodes (marked as 2. in the above). If the value of the node has been checked against a global constant previously, then its <code>NodeInfo<\/code> will be set to a <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8\/src\/maglev\/maglev-graph-builder.cc;l=6738;bpv=0\">constant<\/a>. If that\u2019s the case, then I can store <code>new.target<\/code> to a global variable that has not been changed, which will cause Maglev to <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8\/src\/maglev\/maglev-graph-builder.cc;l=2802;bpv=0\">insert a CheckValue<\/a> node to ensure that <code>new.target<\/code> is the same as the global constant:<\/p>\n<pre><code class=\"language-javascript\">\nclass A {} var x = Array; class B extends A { constructor() { x = new.target; \/\/&lt;--- insert CheckValue node to cache new.target as constant (Array) super(); }\n} Reflect.construct(B, [], Array); \/\/&lt;--- Calls `B` as `target` and `Array` as `new_target`\n<\/code><\/pre>\n<p>When <code>B<\/code> is optimized by Maglev and the optimized code is run, <code>Reflect.construct<\/code> is likely to return an <code>Array<\/code> with <code>length<\/code> <code>0<\/code>. This is because initially, the free spaces in the heap mostly contain zeroes, so when the created <code>Array<\/code> uses an uninitialized value as its <code>length<\/code>, this value is most likely going to be zero. However, once a garbage collection is run, the free spaces in the heap will likely contain some non-trivial values (objects that are freed by garbage collection). By creating some objects in the heap, deleting them, and then triggering a garbage collection, I could carefully arrange the heap to make the uninitialized <code>Array<\/code> created through the bug take any value as its <code>length<\/code>. In practice, a rather crude trial-and-error approach (which mostly involves triggering a garbage collection and creating uninitialized <code>Array<\/code> with the bug until you get it right) is sufficient to give me consistent and reliable results:<\/p>\n<pre><code class=\"language-javascript\">\n\/\/----- Create incorrect Maglev code ------\nvar x = Array; class B extends A { constructor() { x = new.target; super(); }\n}\nfunction construct() { var r = Reflect.construct(B, [], x); return r;\n}\n\/\/Compile optimize code\nfor (let i = 0; i &lt; 2000; i++) construct();\n\/\/-----------------------------------------\n\/\/Trigger garbage collection to fill the free space of the heap\nnew ArrayBuffer(gcSize);\nnew ArrayBuffer(gcSize); corruptedArr = construct(); \/\/ length of corruptedArr is 0, try again...\ncorruptedArr = construct(); \/\/ length of corruptedArr takes the pointer of an object, which gives a large value\n<\/code><\/pre>\n<p>While this already allows out-of-bounds (OOB) access to a Javascript array, which is often sufficient to gain code execution, the situation is slightly more complicated in this case.<\/p>\n<h2 id=\"gaining-code-execution\">Gaining code execution<\/h2>\n<p>The <code>Array<\/code> created via the bug has no elements, so its element store is set to the <code><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/3b1595b086b25cb118bf613bbc8e245f46bf7512:v8\/src\/heap\/factory-base.cc;l=131;bpv=0;bpt=0\">empty_fixed_array<\/a><\/code>. The main problem is that <code>empty_fixed_array<\/code> is located in a read-only region of the v8 heap, which means that an OOB write needs to be large enough to pass the entire read-only heap or it\u2019ll just crash on access:<\/p>\n<pre><code class=\"language-javascript\">\nDebugPrint: 0x10560004d5e5: [JSArray] - map: 0x10560018ed39 <map> [FastProperties] - prototype: 0x10560018e799 - elements: 0x105600000219 [HOLEY_SMI_ELEMENTS] \/\/&lt;------- address of empty_fixed_array ...\n<\/map><\/code><\/pre>\n<p>As you can see above, the lower 32 bits of the address of <code>empty_fixed_array<\/code> is <code>0x219<\/code>, which is fairly small. The lower 32 bits of the address is called the compressed address. In v8, most references are only stored as the lower 32 bits of the full 64-bit pointers in the heap, while the higher 32 bits remain constant and are cached in a register. In particular, v8 objects are referenced using the compressed address and this is an optimization called pointer compression.<\/p>\n<p>As explained in Section \u201cBypassing the need to get an infoleak\u201d of my <a href=\"https:\/\/securitylab.github.com\/research\/in_the_wild_chrome_cve_2021_37975\/\">other post<\/a>, the addresses of many objects are very much constant in v8 and depend only on the software version. In particular, the address of <code>empty_fixed_array<\/code> is the same across different runs and software versions, and more importantly, it remains a small address. This means most v8 objects are going to be placed at an address larger than that of the <code>empty_fixed_array<\/code>. In particular, with a large enough <code>length<\/code>, it is possible to access any v8 object.<\/p>\n<p>While at least in theory, this bug can be used to exploit, it is still unclear how I can use this to access and modify a specific object of my choice. Although I can use the uninitialized <code>Array<\/code> created by the bug to search through all objects that are allocated behind <code>empty_fixed_array<\/code>, doing so is inefficient and I may end up accessing some invalid objects that could result in a crash. It would be good if I can at least have an idea of the addresses for objects that I created in Javascript.<\/p>\n<p>In a <a href=\"https:\/\/powerofcommunity.net\/poc2022\/ManYueMo.pdf\">talk<\/a> that I gave at the <a href=\"https:\/\/powerofcommunity.net\/2022.htm\">POC2022<\/a> conference last year, I shared how object addresses in v8 can indeed be predicted accurately by simply knowing the version of Chrome. What I didn\u2019t know then was that, even after a garbage collection, object addresses can still be predicted reliably.<\/p>\n<pre><code class=\"language-javascript\">\n\/\/Triggers garbage collection\nnew ArrayBuffer(gcSize);\nnew ArrayBuffer(gcSize); corruptedArr = construct();\ncorruptedArr = construct(); var oobDblArr = [0x41, 0x42, 0x51, 0x52, 1.5]; \/\/&lt;---- address remains consisten across runs\n<\/code><\/pre>\n<p>For example, in the above situation, the object <code>oobDblArr<\/code> created after garbage collection remains in the same address fairly consistently across different runs. While the address can sometimes change slightly, it is sufficient to give me a rough starting point to search for <code>oobDblArr<\/code> in <code>corruptedArr<\/code> (the <code>Array<\/code> created from the bug). With this, I can corrupt the length of <code>oobDblArr<\/code> to gain an OOB access with <code>oobDblArr<\/code>. The exploit flow is now very similar to the one described in my <a href=\"https:\/\/github.blog\/2023-09-26-getting-rce-in-chrome-with-incorrect-side-effect-in-the-jit-compiler\/\">previous post<\/a>, and consists of the following steps:<\/p>\n<ol>\n<li>Place an <code>Object<\/code> <code>Array<\/code>, <code>oobObjArr<\/code> after <code>oobDblArr<\/code>, and use the OOB read primitive to read the addresses of the objects stored in this array. This allows me to obtain the address of any v8 object.<\/li>\n<li>Place another double array, <code>oobDblArr2<\/code> after <code>oobDblArr<\/code>, and use the OOB write primitive in <code>oobDblArr<\/code> to overwrite the <code>element<\/code> field of <code>oobDblArr2<\/code> to an object address. Accessing the elements of <code>oobDblArr2<\/code> then allows me to read\/write to arbitrary addresses.<\/li>\n<li>While this gives me arbitrary read and write primitives within the v8 heap and also obtains the address of any object, due to the recently introduced <a href=\"https:\/\/docs.google.com\/document\/d\/1FM4fQmIhEqPG8uGp5o9A-mnPB5BOeScZYpkHjo0KKA8\/edit\">heap sandbox<\/a> in v8, the v8 heap is fairly isolated and it still can\u2019t access arbitrary memory within the renderer process. In particular, I can no longer use the standard method of overwriting the <code>RWX<\/code> pages that are used for storing Web Assembly code to achieve code execution. Instead, <a href=\"https:\/\/mem2019.github.io\/jekyll\/update\/2022\/02\/06\/DiceCTF-Memory-Hole.html\">JIT spraying<\/a> can be used to bypass the heap sandbox.<\/li>\n<li>The idea of JIT spraying is that a pointer to the JIT optimized code of a function is stored in a Javascript <code>Function<\/code> object, by modifying this pointer using arbitrary read and write primitive within the v8 heap, I can make this pointer jump to the middle of the JIT code. If I use data structures, such as a double array, to store shell code as floating point numbers in the JIT code, then jumping to these data structures will allow me to execute arbitrary code. I refer readers to <a href=\"https:\/\/mem2019.github.io\/jekyll\/update\/2022\/02\/06\/DiceCTF-Memory-Hole.html\">this post<\/a> for more details.<\/li>\n<\/ol>\n<p>The exploit can be found <a href=\"https:\/\/github.com\/github\/securitylab\/tree\/main\/SecurityExploits\/Chrome\/v8\/CVE_2023_4069\">here<\/a> with some set up notes.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>With different tiers of optimizations in Chrome, the same functionality often needs to be implemented multiple times, each with different and specific optimization considerations. For complex routines that rely on subtle assumptions, this can result in security problems when porting code between different optimizations, as we have seen in this case, where the implementation of <code>FindNonDefaultConstructorOrConstruct<\/code>has missed out an important check.<\/p>\n<p><\/body> <\/html><\/main> <\/div>\n<\/div>\n<section class=\"related-posts container-xl mx-auto p-responsive-blog\">\n<h2 class=\"h5-mktg border-bottom pb-3 mb-lg-3\"> Related posts <\/h2>\n<\/section>\n<section class=\"recirculation-modules container-xl mx-auto p-responsive-blog\">\n<h2 class=\"h5-mktg border-bottom pb-3 mb-lg-1\"> Explore more from GitHub <\/h2>\n<div class=\"d-flex flex-wrap gutter-condensed\">\n<div class=\"col-12 col-md-6 col-lg-3 d-flex mt-4 mt-lg-6\" readability=\"5.2735849056604\">\n<div class=\"rounded-2 color-bg-subtle d-flex flex-column flex-items-start width-full f4-mktg color-fg-muted\" readability=\"6.4905660377358\"> <img decoding=\"async\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2022\/05\/company.svg\" width=\"44\" height=\"44\" class=\"width-auto d-block mb-3\" loading=\"lazy\" alt=\"Company\"> <\/p>\n<h3 class=\"color-fg-default mb-3\">Company<\/h3>\n<p> The latest on GitHub, from GitHub. <\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"col-12 col-md-6 col-lg-3 d-flex mt-4 mt-lg-6\" readability=\"6.0743801652893\">\n<div class=\"rounded-2 color-bg-subtle d-flex flex-column flex-items-start width-full f4-mktg color-fg-muted\" readability=\"7.8099173553719\"> <img decoding=\"async\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/Icon-Circle.svg\" width=\"44\" height=\"44\" class=\"width-auto d-block mb-3\" loading=\"lazy\" alt=\"GitHub Universe 2023\"> <\/p>\n<h3 class=\"color-fg-default mb-3\">GitHub Universe 2023<\/h3>\n<p> Get free virtual tickets to the global developer event for AI, security, and DevEx. <\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"col-12 col-md-6 col-lg-3 d-flex mt-4 mt-lg-6\" readability=\"5.047619047619\">\n<div class=\"rounded-2 color-bg-subtle d-flex flex-column flex-items-start width-full f4-mktg color-fg-muted\" readability=\"5.8888888888889\"> <img decoding=\"async\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2022\/05\/Copilot_Blog_Icon-1.svg\" width=\"44\" height=\"44\" class=\"width-auto d-block mb-3\" loading=\"lazy\" alt=\"GitHub Copilot\"> <\/p>\n<h3 class=\"color-fg-default mb-3\">GitHub Copilot<\/h3>\n<p> Don&#8217;t fly solo. Try 30 days for free. <\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"col-12 col-md-6 col-lg-3 d-flex mt-4 mt-lg-6\" readability=\"5.0322580645161\">\n<div class=\"rounded-2 color-bg-subtle d-flex flex-column flex-items-start width-full f4-mktg color-fg-muted\" readability=\"5.8709677419355\"> <img decoding=\"async\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2022\/05\/careers.svg\" width=\"44\" height=\"44\" class=\"width-auto d-block mb-3\" loading=\"lazy\" alt=\"Work at GitHub!\"> <\/p>\n<h3 class=\"color-fg-default mb-3\">Work at GitHub!<\/h3>\n<p> <span>Check out our current job openings.<\/span> <\/p>\n<\/p><\/div>\n<\/div><\/div>\n<\/section>\n<div data-color-mode=\"dark\" data-light-theme=\"light\" data-dark-theme=\"dark\">\n<section id=\"newsletter\" class=\"color-bg-subtle py-6 py-lg-8\">\n<div class=\"container-xl p-responsive-blog\">\n<div class=\"newsletter rounded-2\">\n<div class=\"d-flex flex-row flex-wrap color-bg-subtle rounded-2\" readability=\"6.5130434782609\">\n<div class=\"pl-6 pr-6 pl-lg-7 pr-lg-7 py-6 py-lg-7 col-12 col-lg-6 col-xl-7\" readability=\"9\">\n<h2 class=\"h4-mktg color-fg-default\"> Subscribe to The GitHub Insider<\/h2>\n<p class=\"f3-mktg color-fg-muted mt-2 mb-0\">Discover tips, technical guides, and best practices in our monthly newsletter for developers.<\/p>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/section><\/div>\n<p> <\/body> READ MORE <a href=\"https:\/\/packetstormsecurity.com\/news\/view\/35134\/Getting-RCE-In-Chrome-With-Incomplete-Object-Initialization-In-The-Maglev-Compiler.html\">HERE<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>READ MORE HERE&#8230;<\/p>\n","protected":false},"author":2,"featured_media":54195,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_layout":"default_layout","footnotes":""},"categories":[60],"tags":[8623],"class_list":["post-54194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-packet-storm","tag-headlinehackerflawgooglechrome"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News<\/title>\n<meta name=\"description\" content=\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security &amp; Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News\" \/>\n<meta property=\"og:description\" content=\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security &amp; Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/\" \/>\n<meta property=\"og:site_name\" content=\"ThreatsHub Cybersecurity News\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-18T16:06:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?resize=1200%2C630\" \/>\n<meta name=\"author\" content=\"TH Author\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@threatshub\" \/>\n<meta name=\"twitter:site\" content=\"@threatshub\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"TH Author\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/\"},\"author\":{\"name\":\"TH Author\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/person\\\/12e0a8671ff89a863584f193e7062476\"},\"headline\":\"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler\",\"datePublished\":\"2023-10-18T16:06:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/\"},\"wordCount\":2711,\"publisher\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png\",\"keywords\":[\"headline,hacker,flaw,google,chrome\"],\"articleSection\":[\"Packet Storm\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/\",\"name\":\"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png\",\"datePublished\":\"2023-10-18T16:06:26+00:00\",\"description\":\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png\",\"contentUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png\",\"width\":1200,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"headline,hacker,flaw,google,chrome\",\"item\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tag\\\/headlinehackerflawgooglechrome\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\",\"name\":\"ThreatsHub Cybersecurity News\",\"description\":\"%%focuskw%% Threat Intel \u2013 Threat Intel Services \u2013 CyberIntelligence \u2013 Cyber Threat Intelligence - Threat Intelligence Feeds - Threat Intelligence Reports - CyberSecurity Report \u2013 Cyber Security PDF \u2013 Cybersecurity Trends - Cloud Sandbox \u2013- Threat IntelligencePortal \u2013 Incident Response \u2013 Threat Hunting \u2013 IOC - Yara - Security Operations Center \u2013 SecurityOperation Center \u2013 Security SOC \u2013 SOC Services - Advanced Threat - Threat Detection - TargetedAttack \u2013 APT \u2013 Anti-APT \u2013 Advanced Protection \u2013 Cyber Security Services \u2013 Cybersecurity Services -Threat Intelligence Platform\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\"},\"alternateName\":\"Threatshub.org\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\",\"name\":\"ThreatsHub.org\",\"alternateName\":\"Threatshub.org\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/Threatshub_Favicon1.jpg\",\"contentUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/Threatshub_Favicon1.jpg\",\"width\":432,\"height\":435,\"caption\":\"ThreatsHub.org\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/threatshub\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/person\\\/12e0a8671ff89a863584f193e7062476\",\"name\":\"TH Author\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"caption\":\"TH Author\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News","description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/","og_locale":"en_US","og_type":"article","og_title":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News","og_description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","og_url":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/","og_site_name":"ThreatsHub Cybersecurity News","article_published_time":"2023-10-18T16:06:26+00:00","og_image":[{"url":"https:\/\/github.blog\/wp-content\/uploads\/2023\/04\/1200.630-Global@2x-1.png?resize=1200%2C630","type":"","width":"","height":""}],"author":"TH Author","twitter_card":"summary_large_image","twitter_creator":"@threatshub","twitter_site":"@threatshub","twitter_misc":{"Written by":"TH Author","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#article","isPartOf":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/"},"author":{"name":"TH Author","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/person\/12e0a8671ff89a863584f193e7062476"},"headline":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler","datePublished":"2023-10-18T16:06:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/"},"wordCount":2711,"publisher":{"@id":"https:\/\/www.threatshub.org\/blog\/#organization"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#primaryimage"},"thumbnailUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2023\/10\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png","keywords":["headline,hacker,flaw,google,chrome"],"articleSection":["Packet Storm"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/","url":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/","name":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler 2026 | ThreatsHub Cybersecurity News","isPartOf":{"@id":"https:\/\/www.threatshub.org\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#primaryimage"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#primaryimage"},"thumbnailUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2023\/10\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png","datePublished":"2023-10-18T16:06:26+00:00","description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","breadcrumb":{"@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#primaryimage","url":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2023\/10\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png","contentUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2023\/10\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler.png","width":1200,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.threatshub.org\/blog\/getting-rce-in-chrome-with-incomplete-object-initialization-in-the-maglev-compiler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.threatshub.org\/blog\/"},{"@type":"ListItem","position":2,"name":"headline,hacker,flaw,google,chrome","item":"https:\/\/www.threatshub.org\/blog\/tag\/headlinehackerflawgooglechrome\/"},{"@type":"ListItem","position":3,"name":"Getting RCE In Chrome With Incomplete Object Initialization In The Maglev Compiler"}]},{"@type":"WebSite","@id":"https:\/\/www.threatshub.org\/blog\/#website","url":"https:\/\/www.threatshub.org\/blog\/","name":"ThreatsHub Cybersecurity News","description":"%%focuskw%% Threat Intel \u2013 Threat Intel Services \u2013 CyberIntelligence \u2013 Cyber Threat Intelligence - Threat Intelligence Feeds - Threat Intelligence Reports - CyberSecurity Report \u2013 Cyber Security PDF \u2013 Cybersecurity Trends - Cloud Sandbox \u2013- Threat IntelligencePortal \u2013 Incident Response \u2013 Threat Hunting \u2013 IOC - Yara - Security Operations Center \u2013 SecurityOperation Center \u2013 Security SOC \u2013 SOC Services - Advanced Threat - Threat Detection - TargetedAttack \u2013 APT \u2013 Anti-APT \u2013 Advanced Protection \u2013 Cyber Security Services \u2013 Cybersecurity Services -Threat Intelligence Platform","publisher":{"@id":"https:\/\/www.threatshub.org\/blog\/#organization"},"alternateName":"Threatshub.org","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.threatshub.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.threatshub.org\/blog\/#organization","name":"ThreatsHub.org","alternateName":"Threatshub.org","url":"https:\/\/www.threatshub.org\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2025\/05\/Threatshub_Favicon1.jpg","contentUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2025\/05\/Threatshub_Favicon1.jpg","width":432,"height":435,"caption":"ThreatsHub.org"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/threatshub"]},{"@type":"Person","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/person\/12e0a8671ff89a863584f193e7062476","name":"TH Author","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","caption":"TH Author"}}]}},"_links":{"self":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts\/54194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/comments?post=54194"}],"version-history":[{"count":0,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts\/54194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/media\/54195"}],"wp:attachment":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/media?parent=54194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/categories?post=54194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/tags?post=54194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}