Dev.to Security 🔐 Cybersecurity 👁 0 📖 5 min read

Chrome Extension Compromised: A 3-Phase Response Checklist

Originally published on ExtensionBooster. If your Chrome extension is compromised, a malicious update can reach your users within hours, because Chrome checks installed extensions for updates "every few hours." In Decem

Originally published on ExtensionBooster.

If your Chrome extension is compromised, a malicious update can reach your users within hours, because Chrome checks installed extensions for updates "every few hours." In December 2024, one phishing campaign got into at least 35 extensions with more than 2.6 million users. Here is a response plan in three phases (first hour, first day, first month) that you can copy into your repo before you ever need it.

How attackers actually get in

Two-step verification is not enough on its own. These are the three routes that keep coming up:

Route What happens What to lock down
Malicious OAuth app A fake "Chrome Web Store Developer Support" email leads to a consent screen. You grant an attacker's app publishing access, and 2FA never triggers. This is how Cyberhaven was hit in December 2024. Third-party app connections on your Google account
Leaked CI credentials The Chrome Web Store API client secret and refresh token in CI can publish just as well as you can. CI secrets, runners, old contractor machines
Ownership transfer A buyer takes over an extension that already has users and ships a harmful update. Any "we'd like to buy your extension" offer

Catch it early: a version smoke alarm

The clearest warning sign is a version in the Developer Dashboard that you never built. Other signs: Google emails about submissions you didn't make, users reporting new ads, redirects or permission prompts, and a sudden run of one-star reviews that mention malware.

You can automate the first check. This script asks Chrome's update service which version it is serving and fails if that doesn't match your latest release tag. The response format isn't a documented API, so treat it as an early warning, not a guarantee.

// verify-live-version.mjs: node verify-live-version.mjs <id> <version>
const [extId, wanted] = process.argv.slice(2);
const params = new URLSearchParams({
  response: 'updatecheck',
  acceptformat: 'crx3',
  prodversion: '141.0',
  x: `id=${extId}&uc`,
});
const res = await fetch(`https://clients2.google.com/service/update2/crx?${params}`);
const served = (await res.text()).match(/<updatecheck[^>]*\sversion="([^"]+)"/)?.[1];

if (!served) { console.error('No version found in response'); process.exit(2); }
if (served !== wanted) { console.error(`Mismatch: live ${served}, expected ${wanted}`); process.exit(1); }
console.log(`Live version matches: ${served}`);

Run it on a schedule in CI and send failures to a channel someone actually watches at night.

Phase 1: the first hour (stop the spread)

Contain it first and investigate later. Keep a timestamped log of every step you take.

  1. Roll back. The rollback in the Developer Dashboard puts the previous version live "within a minute," and Google says it needs no review. It asks for a new version number and a reason. There are three catches:
    • It only goes back one version. If the attacker published twice, you land on the other bad build, and further rollbacks just cycle between those two.
    • Pending and staged submissions are thrown away.
    • During a percentage rollout, it returns to the last version that reached 100%.
    • If there is no clean version to go back to, unpublish the item instead.
  2. Reclaim the Google account. Change the password, remove 2-step methods you don't recognize, sign out all other sessions and revoke unknown third-party apps. Revoking the app is the step that would have cut off the Cyberhaven attacker.
  3. Prune publisher members that don't need access.
  4. Rotate the Web Store API credentials in CI and pause automated publishing.
  5. Report it through the Chrome Web Store developer support form. Include the item ID, the bad version, when it went live and your evidence.

Phase 2: the first day (scope it and tell users)

Unpack the rogue package and diff it against your last good release. Look for:

  • New permissions or host permissions in manifest.json
  • New network destinations, especially in the service worker
  • Code that reads cookies, tokens, form fields or page content
  • Wider content_scripts matches

Then rotate any secrets that shipped inside the extension and invalidate sessions on your backend.

Your public notice should say what happened, which versions were affected and when, what they could access, what users should do now, and what you are changing. Your clean release can show the notice only to users who updated from an affected version:

const COMPROMISED = new Set(['3.4.1', '3.4.2']);
chrome.runtime.onInstalled.addListener(({ reason, previousVersion }) => {
  if (reason !== 'update' || !COMPROMISED.has(previousVersion)) return;
  chrome.tabs.create({ url: 'https://example.com/security/incident/' });
});

Reply to every angry review with the same short, factual message: confirm the incident, name the fixed version and link to the notice. Don't argue, and never ask anyone to change their rating.

Phase 3: the first month (make it harder next time)

  • Turn on Verified CRX uploads (Package tab). After you opt in, every update must be signed with your own key, so a stolen login alone can't publish. Generate the key offline:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out privatekey.pem
openssl rsa -in privatekey.pem -pubout

Keep the private key out of your Google account and out of every repo. If you lose it, Google says getting a replacement through support can take up to a week.

  • Give each person their own publisher role, with no shared logins.
  • Use security keys or passkeys on every account that can publish.
  • Require a manual approval before the CI publish job runs.
  • Use percentage rollouts so a bad build reaches a small group first.
  • Write a postmortem and publish a short, honest summary.

Your rating can recover. Since Google's August 20, 2026 update, the Chrome Web Store rating focuses on more recent reviews. A burst of one-stars hurts fast, but steady good reviews after the fix count for more than they used to.

Key takeaways

  • Roll back first: it goes live in about a minute with no review.
  • 2FA doesn't stop malicious OAuth apps, so audit your third-party connections.
  • CI publishing credentials are as sensitive as your password.
  • Tell users which versions were affected and what to do, and reply to every review.
  • Verified CRX uploads make a stolen login useless for publishing.

The full guide, including a copy-paste checklist and FAQ, is in the Chrome extension incident response plan on ExtensionBooster. There are more growth and trust guides for extension developers in the ExtensionBooster developer resources.

Have you ever had a publishing account phished or a rogue update go out? What warned you first, users or your own monitoring?

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.