CORS - Misconfigurations & Bypass
Last updated
Last updated
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Стандарт Cross-Origin Resource Sharing (CORS) дозволяє серверам визначати, хто може отримати доступ до їхніх ресурсів та які HTTP методи запитів дозволені з зовнішніх джерел.
Політика одного походження вимагає, щоб сервер, що запитує ресурс, і сервер, що хостить ресурс, використовували один і той же протокол (наприклад, http://
), доменне ім'я (наприклад, internal-web.com
) та порт (наприклад, 80). Згідно з цією політикою, лише веб-сторінки з одного й того ж домену та порту мають доступ до ресурсів.
Застосування політики одного походження в контексті http://normal-website.com/example/example.html
ілюструється наступним чином:
http://normal-website.com/example/
Так: Ідентична схема, домен і порт
http://normal-website.com/example2/
Так: Ідентична схема, домен і порт
https://normal-website.com/example/
Ні: Різна схема і порт
http://en.normal-website.com/example/
Ні: Різне доменне ім'я
http://www.normal-website.com/example/
Ні: Різне доменне ім'я
http://normal-website.com:8080/example/
Ні: Різний порт*
*Internet Explorer ігнорує номер порту при застосуванні політики одного походження, що дозволяє цей доступ.
Access-Control-Allow-Origin
Цей заголовок може дозволяти декілька походжень, значення null
або підстановочний знак *
. Однак, жоден браузер не підтримує декілька походжень, а використання підстановочного знака *
підлягає обмеженням. (Підстановковий знак повинен використовуватися окремо, і його використання разом з Access-Control-Allow-Credentials: true
не дозволено.)
Цей заголовок видається сервером у відповідь на запит ресурсу з іншого домену, ініційований веб-сайтом, при цьому браузер автоматично додає заголовок Origin
.
Access-Control-Allow-Credentials
За замовчуванням, запити з іншого походження здійснюються без облікових даних, таких як куки або заголовок авторизації. Проте, сервер з іншого домену може дозволити читання відповіді, коли облікові дані надсилаються, встановивши заголовок Access-Control-Allow-Credentials
на true
.
Якщо встановлено true
, браузер передаватиме облікові дані (куки, заголовки авторизації або сертифікати клієнта TLS).
Коли ініціюється міждоменний запит за певних умов, таких як використання нестандартного HTTP методу (будь-якого, окрім HEAD, GET, POST), введення нових заголовків або використання спеціального значення заголовка Content-Type, може знадобитися попередній запит. Цей попередній запит, що використовує метод OPTIONS
, служить для інформування сервера про наміри майбутнього міждоменного запиту, включаючи HTTP методи та заголовки, які він має намір використовувати.
Протокол Cross-Origin Resource Sharing (CORS) вимагає цього попереднього перевірки, щоб визначити можливість запитуваної міждоменної операції, перевіряючи дозволені методи, заголовки та надійність походження. Для детального розуміння умов, які обходять необхідність попереднього запиту, зверніться до всебічного посібника, наданого Mozilla Developer Network (MDN).
Важливо зазначити, що відсутність попереднього запиту не скасовує вимогу, щоб відповідь містила заголовки авторизації. Без цих заголовків браузер не здатний обробити відповідь на міждоменний запит.
Розгляньте наступну ілюстрацію попереднього запиту, спрямованого на використання методу PUT
разом із користувацьким заголовком під назвою Special-Request-Header
:
У відповідь сервер може повернути заголовки, що вказують на прийняті методи, дозволений походження та інші деталі політики CORS, як показано нижче:
Access-Control-Allow-Headers
: Цей заголовок вказує, які заголовки можуть бути використані під час фактичного запиту. Він встановлюється сервером, щоб вказати дозволені заголовки в запитах від клієнта.
Access-Control-Expose-Headers
: Через цей заголовок сервер інформує клієнта про те, які заголовки можуть бути відкриті як частина відповіді, крім простих заголовків відповіді.
Access-Control-Max-Age
: Цей заголовок вказує, як довго результати попереднього запиту можуть бути кешовані. Сервер встановлює максимальний час, в секундах, протягом якого інформація, повернена попереднім запитом, може бути повторно використана.
Access-Control-Request-Headers
: Використовується в попередніх запитах, цей заголовок встановлюється клієнтом, щоб проінформувати сервер про те, які HTTP заголовки клієнт хоче використовувати в фактичному запиті.
Access-Control-Request-Method
: Цей заголовок, також використовується в попередніх запитах, встановлюється клієнтом, щоб вказати, який HTTP метод буде використано в фактичному запиті.
Origin
: Цей заголовок автоматично встановлюється браузером і вказує на походження запиту з іншого джерела. Він використовується сервером для оцінки того, чи слід дозволити або відхилити вхідний запит на основі політики CORS.
Зверніть увагу, що зазвичай (в залежності від типу контенту та встановлених заголовків) у GET/POST запиті не надсилається попередній запит (запит надсилається безпосередньо), але якщо ви хочете отримати доступ до заголовків/тіла відповіді, він повинен містити заголовок Access-Control-Allow-Origin, що дозволяє це. Отже, CORS не захищає від CSRF (але може бути корисним).
Access-Control-Request-Local-Network
: Цей заголовок включається в запит клієнта, щоб вказати, що запит спрямований на ресурс локальної мережі. Він слугує маркером, щоб проінформувати сервер, що запит походить з локальної мережі.
Access-Control-Allow-Local-Network
: У відповідь сервери використовують цей заголовок, щоб повідомити, що запитуваний ресурс дозволено ділитися з суб'єктами за межами локальної мережі. Він діє як зелена лампочка для обміну ресурсами через різні мережеві межі, забезпечуючи контрольований доступ при дотриманні протоколів безпеки.
Дійсна відповідь, що дозволяє запит локальної мережі, також повинна містити в відповіді заголовок Access-Controls-Allow-Local_network: true
:
Зверніть увагу, що IP-адреса linux 0.0.0.0 працює для обходу цих вимог для доступу до localhost, оскільки ця IP-адреса не вважається "локальною".
Також можливо обійти вимоги локальної мережі, якщо ви використовуєте публічну IP-адресу локальної точки доступу (наприклад, публічну IP-адресу маршрутизатора). Оскільки в кількох випадках, навіть якщо публічна IP доступна, якщо це з локальної мережі, доступ буде надано.
Зверніть увагу, що навіть якщо наступна конфігурація може виглядати надзвичайно дозволяючою:
Це не дозволено браузерами, і тому облікові дані не будуть надіслані з запитом, дозволеним цим.
Було помічено, що налаштування Access-Control-Allow-Credentials
на true
є передумовою для більшості реальних атак. Це налаштування дозволяє браузеру надсилати облікові дані та читати відповідь, підвищуючи ефективність атаки. Без цього перевага у тому, щоб змусити браузер надіслати запит, зменшується, оскільки використання куків користувача стає неможливим.
Існує виняток, коли мережеве місцезнаходження жертви діє як форма аутентифікації. Це дозволяє використовувати браузер жертви як проксі, обходячи аутентифікацію на основі IP для доступу до внутрішніх додатків. Цей метод має подібності за впливом з DNS rebinding, але його простіше експлуатувати.
Origin
в Access-Control-Allow-Origin
Сценарій у реальному світі, де значення заголовка Origin
відображається в Access-Control-Allow-Origin
, теоретично малоймовірний через обмеження на поєднання цих заголовків. Однак розробники, які прагнуть увімкнути CORS для кількох URL, можуть динамічно генерувати заголовок Access-Control-Allow-Origin
, копіюючи значення заголовка Origin
. Цей підхід може ввести вразливості, особливо коли зловмисник використовує домен з назвою, що виглядає легітимно, обманюючи логіку валідації.
null
походженняnull
походження, вказане для ситуацій, таких як перенаправлення або локальні HTML-файли, займає унікальну позицію. Деякі програми включають це походження в білий список, щоб полегшити локальну розробку, ненавмисно дозволяючи будь-якому веб-сайту імітувати null
походження через пісочницю iframe, таким чином обходячи обмеження CORS.
Коли ви стикаєтеся зі списком дозволених доменів, важливо перевірити можливості обходу, такі як додавання домену зловмисника до дозволеного домену або використання вразливостей захоплення піддоменів. Крім того, регулярні вирази, що використовуються для валідації доменів, можуть не враховувати нюанси в назвах доменів, що створює додаткові можливості для обходу.
Шаблони Regex зазвичай зосереджуються на алфавітно-цифрових, крапкових (.) та дефісних (-) символах, ігноруючи інші можливості. Наприклад, доменне ім'я, створене з використанням символів, які браузери та шаблони regex інтерпретують по-різному, може обійти перевірки безпеки. Обробка символів підкреслення в піддоменах браузерами Safari, Chrome та Firefox ілюструє, як такі розбіжності можуть бути використані для обходу логіки валідації доменів.
Для отримання додаткової інформації та налаштувань цього обходу: https://www.corben.io/advanced-cors-techniques/ та https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
Розробники часто впроваджують захисні механізми для захисту від експлуатації CORS, дозволяючи лише певні домени для запитів інформації. Незважаючи на ці запобіжні заходи, безпека системи не є бездоганною. Наявність навіть одного вразливого піддомену в списку дозволених доменів може відкрити двері для експлуатації CORS через інші вразливості, такі як XSS (міжсайтовий скриптинг).
Щоб проілюструвати, розгляньте сценарій, де домен requester.com
дозволено для доступу до ресурсів з іншого домену, provider.com
. Конфігурація на стороні сервера може виглядати приблизно так:
У цьому налаштуванні всі піддомени requester.com
мають доступ. Однак, якщо піддомен, скажімо, sub.requester.com
, має вразливість XSS, зловмисник може скористатися цією слабкістю. Наприклад, зловмисник з доступом до sub.requester.com
може використати вразливість XSS, щоб обійти політики CORS і зловмисно отримати доступ до ресурсів на provider.com
.
Підсумкова таблиця обходу перевірки URL від PortSwigger виявила, що деякі браузери підтримують дивні символи в доменних іменах.
Chrome і Firefox підтримують підкреслення _
, які можуть обійти регулярні вирази, реалізовані для перевірки заголовка Origin
:
Safari ще більш поблажливий до прийняття спеціальних символів у доменному імені:
Існує можливість, що шляхом експлуатації отруєння кешу на стороні сервера через ін'єкцію HTTP заголовків можна викликати збережену вразливість Cross-Site Scripting (XSS). Цей сценарій розгортається, коли додаток не очищає заголовок Origin
від незаконних символів, створюючи вразливість, особливо для користувачів Internet Explorer та Edge. Ці браузери трактують (0x0d) як законний термінатор HTTP заголовка, що призводить до вразливостей ін'єкції HTTP заголовків.
Розгляньте наступний запит, де маніпулюється заголовок Origin
:
Internet Explorer та Edge інтерпретують відповідь як:
Хоча безпосереднє використання цієї вразливості шляхом відправлення неправильно сформованого заголовка веб-браузером є недоцільним, спеціально підготовлений запит можна вручну згенерувати за допомогою інструментів, таких як Burp Suite. Цей метод може призвести до того, що кеш на стороні сервера зберігатиме відповідь і ненавмисно надаватиме її іншим. Спеціально підготовлений вантаж має на меті змінити набір символів сторінки на UTF-7, кодування символів, яке часто асоціюється з вразливостями XSS через його здатність кодувати символи таким чином, що їх можна виконати як скрипт у певних контекстах.
Для подальшого читання про збережені вразливості XSS дивіться PortSwigger.
Примітка: Використання вразливостей ін'єкції HTTP-заголовків, зокрема через отруєння кешу на стороні сервера, підкреслює критичну важливість перевірки та очищення всіх введених користувачем даних, включаючи HTTP-заголовки. Завжди використовуйте надійну модель безпеки, яка включає перевірку введених даних, щоб запобігти таким вразливостям.
У цьому сценарії спостерігається екземпляр веб-сторінки, що відображає вміст спеціального HTTP-заголовка без належного кодування. Зокрема, веб-сторінка відображає вміст, включений у заголовок X-User-id
, який може містити шкідливий JavaScript, як показано в прикладі, де заголовок містить тег SVG-изображення, призначений для виконання JavaScript-коду при завантаженні.
Політики Cross-Origin Resource Sharing (CORS) дозволяють надсилати спеціальні заголовки. Однак, якщо відповідь не відображається безпосередньо браузером через обмеження CORS, корисність такої ін'єкції може здаватися обмеженою. Критичний момент виникає при розгляді поведінки кешу браузера. Якщо заголовок Vary: Origin
не вказано, стає можливим, щоб шкідлива відповідь була кешована браузером. В подальшому ця кешована відповідь може бути відображена безпосередньо при переході за URL, обходячи необхідність безпосереднього відображення під час початкового запиту. Цей механізм підвищує надійність атаки, використовуючи кешування на стороні клієнта.
Щоб проілюструвати цю атаку, наводиться приклад JavaScript, призначений для виконання в середовищі веб-сторінки, наприклад, через JSFiddle. Цей скрипт виконує просту дію: він надсилає запит на вказаний URL з спеціальним заголовком, що містить шкідливий JavaScript. Після успішного завершення запиту він намагається перейти на цільовий URL, потенційно викликаючи виконання ін'єкованого скрипту, якщо відповідь була кешована без належної обробки заголовка Vary: Origin
.
Ось короткий огляд JavaScript, використаного для виконання цієї атаки:
XSSI, також відомий як Cross-Site Script Inclusion, є типом вразливості, яка використовує той факт, що політика однакового походження (SOP) не застосовується при включенні ресурсів за допомогою тегу script. Це пов'язано з тим, що скрипти повинні мати можливість включатися з різних доменів. Ця вразливість дозволяє зловмиснику отримувати доступ і читати будь-який контент, який був включений за допомогою тегу script.
Ця вразливість стає особливо значущою, коли йдеться про динамічний JavaScript або JSONP (JSON з Padding), особливо коли для аутентифікації використовуються дані про навколишнє середовище, такі як куки. При запиті ресурсу з іншого хоста куки включаються, що робить їх доступними для зловмисника.
Щоб краще зрозуміти та пом'якшити цю вразливість, ви можете використовувати плагін BurpSuite, доступний за адресою https://github.com/kapytein/jsonp. Цей плагін може допомогти виявити та усунути потенційні вразливості XSSI у ваших веб-додатках.
Читати більше про різні типи XSSI та як їх експлуатувати тут.
Спробуйте додати callback
параметр у запит. Можливо, сторінка була підготовлена для відправки даних як JSONP. У цьому випадку сторінка поверне дані з Content-Type: application/javascript
, що обійде політику CORS.
Один зі способів обійти обмеження Access-Control-Allow-Origin
- це запитати веб-додаток, щоб він зробив запит від вашого імені та надіслав відповідь назад. Однак у цьому сценарії облікові дані кінцевої жертви не будуть надіслані, оскільки запит робиться до іншого домену.
CORS-escape: Цей інструмент надає проксі, який пересилає ваш запит разом з його заголовками, одночасно підробляючи заголовок Origin, щоб відповідати запитаному домену. Це ефективно обіймає політику CORS. Ось приклад використання з XMLHttpRequest:
simple-cors-escape: Цей інструмент пропонує альтернативний підхід до проксирування запитів. Замість того, щоб передавати ваш запит як є, сервер робить свій власний запит з вказаними параметрами.
Ви можете обійти перевірки CORS, такі як e.origin === window.origin
, створивши iframe і з нього відкривши нове вікно. Більше інформації на наступній сторінці:
DNS rebinding через TTL - це техніка, яка використовується для обходу певних заходів безпеки шляхом маніпулювання DNS-записами. Ось як це працює:
Зловмисник створює веб-сторінку і змушує жертву отримати до неї доступ.
Потім зловмисник змінює DNS (IP) свого домену, щоб вказувати на веб-сторінку жертви.
Браузер жертви кешує відповідь DNS, яка може мати значення TTL (Time to Live), що вказує, як довго DNS-запис повинен вважатися дійсним.
Коли TTL закінчується, браузер жертви робить новий DNS-запит, що дозволяє зловмиснику виконувати JavaScript-код на сторінці жертви.
Підтримуючи контроль над IP жертви, зловмисник може збирати інформацію з жертви, не надсилаючи жодних куків на сервер жертви.
Важливо зазначити, що браузери мають механізми кешування, які можуть запобігти негайному зловживанню цією технікою, навіть з низькими значеннями TTL.
DNS rebinding може бути корисним для обходу явних перевірок IP, які виконує жертва, або для сценаріїв, коли користувач або бот залишається на одній сторінці протягом тривалого часу, що дозволяє кешу закінчитися.
Якщо вам потрібен швидкий спосіб зловживати DNS rebinding, ви можете використовувати сервіси, такі як https://lock.cmpxchg8b.com/rebinder.html.
Щоб запустити свій власний сервер DNS rebinding, ви можете використовувати інструменти, такі як DNSrebinder (https://github.com/mogwailabs/DNSrebinder). Це передбачає відкриття вашого локального порту 53/udp, створення A-запису, що вказує на нього (наприклад, ns.example.com), і створення NS-запису, що вказує на раніше створений A-субдомен (наприклад, ns.example.com). Будь-який субдомен ns.example.com буде розв'язаний вашим хостом.
Ви також можете дослідити публічно працюючий сервер за адресою http://rebind.it/singularity.html для подальшого розуміння та експериментів.
DNS rebinding через затоплення кешу DNS - це ще одна техніка, яка використовується для обходу механізму кешування браузерів і примушення до другого DNS-запиту. Ось як це працює:
Спочатку, коли жертва робить DNS-запит, на нього відповідає IP-адреса зловмисника.
Щоб обійти захист кешування, зловмисник використовує сервісний робітник. Сервісний робітник затоплює кеш DNS, що ефективно видаляє кешоване ім'я сервера зловмисника.
Коли браузер жертви робить другий DNS-запит, на нього тепер відповідає IP-адреса 127.0.0.1, яка зазвичай посилається на localhost.
Затоплюючи кеш DNS за допомогою сервісного робітника, зловмисник може маніпулювати процесом розв'язання DNS і примусити браузер жертви зробити другий запит, цього разу розв'язуючи на бажану IP-адресу зловмисника.
Ще один спосіб обійти захист кешування - це використання кількох IP-адрес для одного й того ж субдомену у постачальника DNS. Ось як це працює:
Зловмисник налаштовує два A-записи (або один A-запис з двома IP) для одного й того ж субдомену у постачальника DNS.
Коли браузер перевіряє ці записи, він отримує обидві IP-адреси.
Якщо браузер вирішує спочатку використовувати IP-адресу зловмисника, зловмисник може надати корисне навантаження, яке виконує HTTP-запити до того ж домену.
Однак, як тільки зловмисник отримує IP-адресу жертви, він перестає відповідати браузеру жертви.
Браузер жертви, усвідомивши, що домен не відповідає, переходить до використання другої наданої IP-адреси.
Доступаючи до другої IP-адреси, браузер обминає політику одного походження (SOP), що дозволяє зловмиснику зловживати цим і збирати та ексфільтрувати інформацію.
Ця техніка використовує поведінку браузерів, коли для домену надаються кілька IP-адрес. Стратегічно контролюючи відповіді та маніпулюючи вибором IP-адреси браузера, зловмисник може експлуатувати SOP і отримувати інформацію від жертви.
Зверніть увагу, що для доступу до localhost вам слід спробувати переприв'язати 127.0.0.1 у Windows і 0.0.0.0 у Linux. Постачальники, такі як godaddy або cloudflare, не дозволили мені використовувати IP 0.0.0.0, але AWS route53 дозволив мені створити один A-запис з 2 IP, один з яких "0.0.0.0"
Для отримання додаткової інформації ви можете перевірити https://unit42.paloaltonetworks.com/dns-rebinding/
Якщо внутрішні IP не дозволені, вони можуть забути заборонити 0.0.0.0 (працює на Linux і Mac)
Якщо внутрішні IP не дозволені, відповідайте з CNAME на localhost (працює на Linux і Mac)
Якщо внутрішні IP не дозволені як DNS-відповіді, ви можете відповісти CNAME на внутрішні сервіси, такі як www.corporate.internal.
Ви можете знайти більше інформації про попередні техніки обходу та як використовувати наступний інструмент у доповіді Gerald Doussot - Стан атак DNS Rebinding & Унікальність походження - конференція DEF CON 27.
Унікальність походження
- це інструмент для виконання атак DNS rebinding. Він включає необхідні компоненти для переприв'язки IP-адреси DNS-імені сервера атаки до IP-адреси цільової машини та для надання корисних навантажень для експлуатації вразливого програмного забезпечення на цільовій машині.
Використовуйте TLS у внутрішніх сервісах
Запитуйте аутентифікацію для доступу до даних
Перевіряйте заголовок Host
https://wicg.github.io/private-network-access/: Пропозиція завжди надсилати попередній запит, коли публічні сервери хочуть отримати доступ до внутрішніх серверів
Fuzz можливі неправильні налаштування в політиках CORS
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)