Problemi di sicurezza dell'URL relativo fornito dall'utente in Location: header

1

Questo è simile a questa domanda , ma un po 'più specifico.

TL; DR; Ci sono problemi di sicurezza nel consentire agli URL relativi forniti dall'utente nell'intestazione Location: sul reindirizzamento?

Sfondo:

Sto scrivendo un piccolo proxy da utilizzare di fronte a CouchDB . Per autenticare l'API CouchDB, è necessario inviare un POST all'endpoint /_session come descritto qui .

Questo endpoint accetta un parametro di query facoltativo, next , che, quando presente, farà sì che una richiesta di autenticazione di successo risponda con 302 e un Location: di reindirizzamento, piuttosto che un semplice 200 .

Ora CouchDB ha quello che mi sembra un'implementazione insicura di questo. Il valore next viene semplicemente aggiunto al nome host del server (senza barra !!). Quindi una richiesta come questa:

POST /_session?next=foobar

Riceverai una risposta che include:

Location: http://someserver.comfoobar

Penso che questo sia abbastanza chiaramente negativo, ma almeno il danno è limitato solo alle richieste autenticate, quindi un phisher casuale probabilmente non può fare molto con esso. Ma mi rende ancora un po 'a disagio.

Quindi mi sembra che debba essere fatta qualche validazione. Come minimo, un / deve essere preteso dall'URL fornito dall'utente. Ma sto pensando che un approccio più semplice potrebbe essere semplicemente convalidare che l'URL fornito dall'utente sia relativo, e quindi rispondere solo con quello.

Quindi per il mio esempio:

POST /_session?next=foobar

Risponderebbe con:

Location: /foobar

È un approccio sicuro?

    
posta Flimzy 12.03.2017 - 12:35
fonte

3 risposte

1

La possibilità di reindirizzare il tuo sito a un altro URL determinato dall'input dell'utente è considerata solo una vulnerabilità se può essere utilizzato per reindirizzare l'utente fuori sede.

I reindirizzamenti non sicuri possono essere utilizzati nei tentativi di phishing: in un'email di phishing un link a https://realbank.com/?next=http://evil.attacker avrà una maggiore possibilità di essere seguito rispetto a un link a http://evil.attacker .

Inoltre, per evitare CSP è possibile utilizzare reindirizzamenti non sicuri. Se un sito ha una regola CSP che dice che può caricare solo Javascript da quell'host, il caricamento di una pagina che reindirizza allo script su un altro host continuerà a funzionare.

Ancora una volta, queste vulnerabilità presuppongono che tu possa reindirizzare il sito. Se limiti i reindirizzamenti al tuo sito, generalmente è sicuro.

    
risposta data 12.03.2017 - 12:56
fonte
1

Ci sono altri pericoli di questo approccio. Sembra davvero che il codice CouchDB sia terribilmente insicuro (il che non mi sorprende affatto, non ho mai visto un DB NoSQL con sicurezza tollerabile ad eccezione di cose come DynamoDB).

Oltre al pericolo che hai già riconosciuto (reindirizzamento ad un altro dominio abusando della mancanza di un percorso root / carattere), c'è anche il rischio di un'iniezione di intestazione. Se il server accetta solo il parametro di query e lo aggiunge senza alcun tipo di convalida, un utente malintenzionato potrebbe potenzialmente iniettare una nuova riga seguita da intestazioni HTTP aggiuntive o anche una riga vuota seguita da una risposta HTTP (come un documento HTML). L'impatto di queste cose dipenderebbe dal client: ad esempio, una risposta con due% di intestazioni diLocation: non è conforme, ma la maggior parte dei clienti ne seguirà uno e se è la seconda, allora il tuo aggressore ha un reindirizzamento completamente arbitrario - ma posso pensare ad alcuni modi in cui potrebbe quasi certamente essere sfruttabile.

La soluzione standard per i reindirizzamenti aperti è, se possibile, creare una tabella di ricerca delle destinazioni e richiedere alla richiesta di specificare l'indice di tale tabella. Questo funziona solo se hai un numero finito (e almeno in qualche modo prevedibile) di possibili destinazioni, ma è facile da implementare e non vulnerabile al tipo di imbrogli di cui stiamo parlando qui. Inoltre, non deve essere una tabella di ricerca effettiva; cose come ?next=userprofile,privacysettings o simili (per specificare che l'utente deve essere reindirizzato alla pagina delle impostazioni sulla privacy del proprio profilo) funzionano altrettanto bene come ricerche indicizzate, purché si convalidino le stringhe fornite e non si faccia nulla di stupido quando si incontrano quelle non riconosciute.

    
risposta data 12.03.2017 - 13:07
fonte
1

Apri reindirizzamento

Da dove viene originariamente il valore next ? Le richieste POST non sono generalmente vulnerabili al reindirizzamento aperto.

Ma assumendo che sia controllabile da una precedente richiesta GET:

Il tuo approccio risolve un problema. Prima, un utente malintenzionato potrebbe iniettare .evil.com e quindi essere reindirizzato a someserver.com.evil.com che è sotto il controllo dell'utente malintenzionato. Anche se . non è consentito, se l'url è ad esempio someserver.co un utente malintenzionato potrebbe iniettare m e essere reindirizzato a someserver.com .

La tua soluzione presenta tuttavia un nuovo problema. Se un utente malintenzionato inietta /evil.com , verrà reindirizzato a //evil.com , che è un URL relativo al protocollo.

Altri problemi

Appart da problemi di reindirizzamento aperti, essere in grado di reindirizzare internamente non è di troppo beneficio per un utente malintenzionato. Se l'autenticazione è aperta a CSRF, può fornire alcuni vantaggi negli attacchi login-CSRF (ad esempio per reindirizzare la vittima a una pagina contenente un carico utile XSS). Potrebbe anche essere possibile ignorare la protezione CSRF basata sul controllo di riferimento per le richieste GET.

    
risposta data 12.03.2017 - 13:41
fonte

Leggi altre domande sui tag