Safeguard
Industry Analysis

WebExtension vulnerabilities in React DevTools and Vue.js DevTools

CVE-2023-5654 and CVE-2023-5718 exposed 5M+ React and Vue devtools users to postMessage flaws. Here's how devtools extensions became supply chain risk.

Safeguard Research Team
Research
7 min read

On October 19, 2023, security researchers disclosed CVE-2023-5654: React Developer Tools, a browser extension installed by more than 4 million Chrome users, registered a window.addEventListener('message', ...) listener that accepted a fetch-file-with-cache event from any web page and used the message contents to trigger an unvalidated fetch() call from the extension's privileged context. Four days later, CVE-2023-5718 exposed a parallel flaw in Vue.js devtools, installed by more than 1 million users, that let a malicious iframe capture base64-encoded screenshot data from sensitive local or internal resources and exfiltrate it through the same postMessage channel. Both bugs trace back to the same architectural gap: WebExtension content scripts that bridge an untrusted web page to privileged browser APIs without checking who sent the message. For teams shipping React or Vue applications, the tools engineers open dozens of times a day were, for years, a quiet path into the browser's privileged layer.

What vulnerability did researchers find in React Developer Tools?

React Developer Tools shipped a content script that listened for a fetch-file-with-cache message on window and used the URL inside that message to make a fetch() request from the extension's elevated context, without verifying the message's origin or sanitizing the URL. Because window.addEventListener('message', ...) in a content script receives events from every frame on the page, not just the extension's own UI, any website the victim visited could post a crafted message and force the extension to issue arbitrary outbound requests. Researchers cataloged this as CVE-2023-5654, an Improper Authorization issue (CWE-862) with a CVSS 3.1 base score in the 6.5-7.0 range depending on scoring model, and noted realistic abuse cases including click-fraud generation and using the victim's browser as an unwitting participant in a request flood. The fix landed in react-devtools 4.28.4, which removed the vulnerable branch of the onMessage handler entirely rather than attempting to sanitize it. Any project pinned to an older react-devtools or react-devtools-core npm package, or any developer running an unpatched Chrome/Firefox extension build, remained exposed until they upgraded.

What went wrong in Vue.js devtools?

Vue.js devtools leaked screenshot data to the page that requested it, because the extension's postMessage handler sent capture results back to whichever listener registered for them, without confirming the requester was the extension's own trusted UI. A malicious page could embed an iframe pointed at a sensitive target — a local file, an internal admin panel, or a staging URL the developer had open in another tab — register a message listener, and receive the base64-encoded screenshot the extension captured of that target. This was cataloged as CVE-2023-5718, published October 23, 2023, with a CVSS score of 4.3. It wasn't Vue devtools' first postMessage problem: a 2021 issue (tracked in the vuejs/devtools-v6 repository as issue #1353) showed a cross-site scripting bug in the toast function of devtools-background.js, triggerable by a crafted postMessage the moment a victim opened Chrome DevTools (F12) on a malicious page. Both flaws share the same root cause as the React bug: a privileged background or content script trusting message content over message origin.

Why do postMessage listeners turn a devtools extension into an attack surface?

They turn a devtools extension into an attack surface because the WebExtension model deliberately injects content scripts into the page's own JavaScript context, and window.postMessage has no built-in sender authentication — it's the extension code's job to check event.origin and reject anything it doesn't expect. When that check is skipped, every open tab on every website the developer visits becomes a potential message sender to a script that holds extension-level permissions: fetching arbitrary URLs, reading tab content, or forwarding data to a privileged background page. The OWASP Browser Extension Vulnerabilities Cheat Sheet flags this exact pattern — unvalidated external messages and forwarding of unverified messages to privileged APIs — as one of the most common root causes of extension CVEs, precisely because content scripts sit at the seam between "web page, fully untrusted" and "extension, fully trusted." A devtools extension is an especially attractive target for this class of bug because it's installed almost exclusively by developers, who routinely have internal tools, staging environments, and source maps open in adjacent tabs.

How many developers were exposed, and for how long?

At minimum, 4 million-plus React Developer Tools users and 1 million-plus Vue.js devtools users ran a vulnerable build at some point between the extensions' respective release history and their October 2023 patches. React Developer Tools versions prior to 4.28.4 carried the fetch-file-with-cache flaw; because the extension auto-updates for most Chrome and Firefox users, the practical exposure window for actively-used browsers closed within days of the patch, but any pinned react-devtools-core dependency used for programmatic debugging (common in React Native and Electron tooling) could persist far longer since npm packages don't auto-update. Vue.js devtools' screenshot leak (CVE-2023-5718) and the earlier 2021 toast XSS both required a developer to have the extension installed and, in the 2021 case, to actively open DevTools on a malicious page — a routine action for any working front-end engineer, which is what made the bug practically exploitable rather than theoretical.

What does this mean for software supply chain risk beyond the browser?

It means the developer's own browser is part of the software supply chain, not just a viewing window for it. React and Vue devtools run with elevated extension permissions inside the same browser profile developers use to reach internal staging environments, admin consoles, CI dashboards, and cloud provider portals — so a flaw that lets any web page trigger arbitrary fetches or exfiltrate screenshots from that browser is functionally a bridge from "attacker-controlled web page" to "developer's internal tooling." This is the same category of risk security teams already track for CI/CD plugins and IDE extensions: a widely-installed, developer-facing tool with elevated access that most inventories never enumerate because it isn't a backend service or a production dependency. Snyk's original research into these two extensions made this point explicitly — the vulnerability class isn't unique to React or Vue tooling, it's endemic to how WebExtensions are built, which means the same postMessage-trust pattern is worth auditing in any other devtools, password manager, or productivity extension a development team standardizes on.

How should security teams detect and respond to devtools extension risk?

Security teams should treat browser extensions used by engineering as first-class supply chain inventory, tracked and versioned the same way a backend dependency is. Concretely, that means maintaining a current list of extensions permitted in developer browser profiles, mapping each to its current version and known CVEs (CVE-2023-5654 and CVE-2023-5718 should both be closed items by now, but verify rather than assume), and flagging any pinned react-devtools-core or similar npm packages used in test/debug harnesses that don't benefit from browser auto-update. Because the underlying flaw is a code pattern — trusting event.data without checking event.origin — teams building or maintaining their own internal extensions should grep their own content scripts for addEventListener('message' and confirm an origin allowlist exists before message data reaches a privileged API.

How Safeguard Helps

Safeguard's Griffin AI ingests advisories like CVE-2023-5654 and CVE-2023-5718 and runs reachability analysis against your actual dependency graph, so if react-devtools-core is pinned in a test harness or Electron tooling package, you get a prioritized finding instead of a generic "you have this package" alert. SBOM generation and ingest give security teams the inventory that most orgs are missing for developer-facing tooling — extensions, devtools packages, and CI plugins — so exposure windows like the multi-year gap some pinned react-devtools-core installs carried get closed on a known timeline rather than discovered after the fact. Where a fix is available, Safeguard opens an auto-fix PR that bumps the affected package to the patched version and runs your existing test suite, so remediation doesn't wait for a manual dependency-bump sprint. That combination — reachability-scored findings, real inventory, and pull-request-ready fixes — is what turns a disclosure like this one from a scramble into a routine patch cycle.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.