81 chrome extension review
Skill FluxonLab/Skillry/plugins/optional-specialist/skills/81-chrome-extension-review
Use when you need to review Chrome extension manifests, content scripts, background workers, permissions, and store-readiness.From its SKILL.md
npx -y skills add FluxonLab/Skillry --skill 81-chrome-extension-reviewAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.5 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
Chrome Extension Review
Purpose
Review Chrome extensions for Manifest V3 compliance, security (CSP, XSS, privilege escalation), permission minimization, message-passing correctness, content script isolation, and Chrome Web Store policy readiness.
When to use
- Reviewing a new or updated Chrome extension before submitting to the Chrome Web Store.
- Auditing an existing extension's
manifest.json, service worker, content scripts, or popup pages. - Evaluating permission requests for least-privilege compliance.
- Reviewing extension code after a MV2 → MV3 migration.
- Security audit of an extension that handles user credentials, payment data, or PII.
When not to use
- Firefox/Safari WebExtension review where browser-specific APIs differ significantly — flag divergences but note this skill targets Chrome.
- Pure web app review with no
chrome.*API usage. - Native messaging host code review (separate OS-level process).
Procedure
1. Manifest V3 compliance
- Confirm
"manifest_version": 3— MV2 extensions are being phased out and will stop working in Chrome. background.service_workerreplacesbackground.scripts/background.pagefrom MV2.declarativeNetRequestreplaceswebRequestblocking mode — verify rules are defined in_rules.jsonor fetched viaupdateDynamicRules.actionreplacesbrowser_action/page_action.- Remote code execution is prohibited: no
eval(), nonew Function(string), nochrome.tabs.executeScriptwith a string body loaded from a remote URL. content_scriptsmust not usedocument.write().
2. Permissions — least privilege
- List every permission in
permissions,optional_permissions, andhost_permissions. - For each permission, verify it is actually used in the code. Remove any unused permission.
- Prefer
activeTabover broadhost_permissionslike<all_urls>or*://*/*when the extension only needs the current tab. - Sensitive permissions (
tabs,history,bookmarks,cookies,webNavigation,downloads,nativeMessaging) require clear justification in the store listing. scriptingpermission: verifychrome.scripting.executeScriptis not used to inject remotely-fetched code strings.storagevsunlimitedStorage: only requestunlimitedStorageif the data volume genuinely requires it.
3. Host permissions
- Scope to the minimum set of origins required.
https://api.example.com/*is better thanhttps://*/*. - Wildcard subdomains (
https://*.example.com/*) must be justified — ensure the extension does not accidentally run on all subdomains of a large service. - Optional host permissions should be requested at runtime via
chrome.permissions.request()rather than declared statically for permissions not needed at install time.
4. Content Security Policy
- Extension pages (popup, options, sidepanel) must have a strict CSP in
manifest.jsonunder"content_security_policy". - Minimum acceptable:
"script-src 'self'; object-src 'none';"— nounsafe-inline, nounsafe-eval. - External script sources in CSP are not allowed in MV3 for extension pages.
- Content scripts run in an isolated world by default; verify they do not access
unsafeWindoworwindow.wrappedJSObjectwithout necessity.
5. Message passing security
chrome.runtime.onMessage.addListener: verify thesenderis checked before acting on messages — do not trust messages from arbitrary web pages.chrome.runtime.sendMessagefrom content scripts: the service worker handler must validate the message shape before executing privileged actions.chrome.runtime.onMessageExternal(cross-extension messaging): explicitly whitelist allowed extension IDs if used.postMessagebetween content script and page: validateevent.originstrictly; never useorigin === '*'.
6. Content script isolation and XSS
- Content scripts must not inject innerHTML with page-supplied data:
element.innerHTML = response.datais XSS ifresponse.datais attacker-controlled. - Use
textContentfor text,createElement+setAttributefor DOM construction. - DOM-based XSS: watch for
document.location,document.URL,document.referrerfed intoeval,innerHTML, ordocument.write. - Content scripts should not expose functions on the page's
windowobject unless strictly necessary.
7. Service worker (background)
- Service workers are event-driven and terminate when idle — do not rely on in-memory state persisting between events; use
chrome.storage.sessionorchrome.storage.local. - Avoid long-running
setInterval— usechrome.alarmsfor periodic tasks. chrome.alarms.createrequires thealarmspermission.- Unhandled promise rejections in service workers silently fail — add
.catch()to all async chains. chrome.storage.localis not encrypted — do not store sensitive credentials there; usechrome.storage.session(cleared on browser restart) or the OS credential store via native messaging.
8. web_accessible_resources
- List only the resources that must be accessible from web pages.
- Specify
matchesto restrict which origins can access the resource — avoid"matches": ["<all_urls>"]. - An overly permissive
web_accessible_resourcesallows malicious pages to fingerprint extension presence and load extension assets.
9. Data handling and privacy
- Personal data collected (browsing history, form data, PII) must be disclosed in the store privacy policy and in the manifest
"privacy_policy"URL. - No sending of tab URLs or content to third-party servers without user consent.
- Verify no API keys, client secrets, or tokens are hardcoded in extension source — they are visible to users who inspect the extension.
10. Chrome Web Store policy readiness
- Extension must have a single, clear purpose described in the listing.
- No obfuscated code — the store may reject or remove extensions with intentionally obfuscated JavaScript.
- Update URL must be omitted (managed by the store) for public listings.
- Icons: 16, 48, 128 px PNG required; verify they are included in the package.
Checklist
MV3 compliance:
-
manifest_version: 3 -
background.service_workerdefined (nobackground.page) - No
eval(),new Function(string), or remote script injection -
declarativeNetRequestused instead of blockingwebRequestwhere applicable
Permissions:
- Every declared permission is used in code
-
activeTabpreferred over<all_urls>where possible - Sensitive permissions (
tabs,history,cookies) justified - Host permissions scoped to minimum required origins
Security:
- CSP on extension pages:
script-src 'self', nounsafe-inline/unsafe-eval -
runtime.onMessagevalidatessenderbefore privileged actions - Content scripts avoid
innerHTMLwith external data -
web_accessible_resourceshas restrictedmatches
Service worker:
- No in-memory state relied upon across events
-
chrome.alarmsused for periodic tasks, notsetInterval - All async promise chains have
.catch()
Privacy:
- No hardcoded API keys in source
- No PII sent to third parties without user consent
- Privacy policy URL in manifest
Common issues & anti-patterns
- MV2 background page left in manifest: causes load failure in Chrome 127+ (MV2 phase-out). Replace with
service_worker. "host_permissions": ["<all_urls>"]: flags for manual review in the store and is almost always broader than needed.innerHTMLwith data fromfetch(): if the fetched resource can be influenced by a web page (CORS, redirect), this is a stored XSS vector inside the extension context.- No
sendercheck inonMessage: a malicious web page can send crafted messages to the extension's background and trigger privileged actions. - Storing OAuth tokens in
chrome.storage.local: readable by any code with access to the extension context. Preferchrome.storage.sessionor prompt re-auth. eval()in content scripts for template rendering: violates MV3 CSP and the store policy.web_accessible_resources: ["*"]withmatches: ["<all_urls>"]: allows any web page to detect the extension and load any bundled asset.chrome.tabs.queryfor all tabs: collecting all open tab URLs is a privacy risk and requires justification; preferactiveTab.
Required output
Return a structured report with:
- Summary: pass / needs fixes / blocked (store-rejection risk or security issue).
- Manifest snapshot: key fields reviewed (version, permissions, host_permissions, CSP, service worker).
- Findings table: severity (critical / high / medium / low / info), category, file + line, description, remediation.
- Permission audit: each permission listed with justification status (justified / unused / overly broad).
- Store readiness: checklist of store policy items that pass or require attention.
- Next handoff: specific items to fix before store submission; note any that require store team waiver.
Safety
- Do not install or execute the extension in a browser during review.
- Never extract or print API keys found in the source — flag as critical finding requiring rotation.
- Do not access the extension's storage contents or user data.
- If the extension appears to perform undisclosed data collection (keylogging, form scraping), flag as critical and recommend immediate removal from distribution.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.