Come impedire ad altri siti web di inviare richieste AJAX su più domini?

4

Da due diverse applicazioni, sono stato in grado di inviare richieste di origine incrociata. Sebbene il browser restituisca un errore di "origine incrociata", il mio server continua a ricevere ed eseguire la richiesta. Ad esempio, da un sito remoto posso richiamare la richiesta di dominio incrociato usando

$.ajax({
        xhrFields: {
            withCredentials: true
        },
        data:{ my: 'a' },
        url: 'http://MyApp/Page',
        type: 'POST'
})

So che il browser non restituisce la risposta allo script, ma la mia pagina server viene ancora eseguita.

Supponiamo che un utente innocente abbia effettuato il login in un sito http://example.com . Questa applicazione accetterà le richieste POST per inserire un record. Quando l'utente innocente visita http://HackerSite.com , http://HackerSite.com sarà in grado di inviare una richiesta POST a http://example.com tramite AJAX. Come può essere prevenuto?

    
posta user960567 24.10.2013 - 20:19
fonte

4 risposte

16

Oltre che tramite una richiesta AJAX interdominio con credenziali, il POST nell'esempio potrebbe anche essere inviato utilizzando un modulo standard senza AJAX:

<form method="post" action="http://MyApp/Page" name="hiddenFormInIframe">

<input type="hidden" name="my" value="a" />

</form>
<script type="text/javascript">
  document.hiddenFormInIframe.submit();
</script>

Ciò includerebbe anche i cookie nella richiesta.

La vulnerabilità di cui parli si chiama Falsificazione richiesta cross-site .

Puoi evitare che il POST venga inviato da un altro dominio inviando un'intestazione nella tua richiesta AJAX e controllando il lato del server dell'intestazione. Un'intestazione comune da utilizzare è X-Requested-With . Questa intestazione non può essere inviata tra domini tramite AJAX poiché questa intestazione non è nella lista sicura (senza CORS essere abilitato sul tuo server). Un modulo HTML non può inviare neanche questa intestazione.

Solo le seguenti intestazioni sono autorizzate per il dominio incrociato tramite AJAX:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type

L'intestazione X-Requested-With viene impostata automaticamente quando si utilizza JQuery e puoi verificarlo nel tuo codice ASP.NET .

Tuttavia in passato ci sono stati alcuni exploit tramite plugin come Flash dove potrebbero essere impostate le intestazioni che non erano possibili tramite un browser (ad es. Referer ) quindi per evitare questo si consiglia di utilizzare modello di token del sincronizzatore che implica l'impostazione di un token in un campo nascosto o in un'intestazione. Questo token sarà validato così come il cookie di autenticazione per tutte le richieste con effetti collaterali. Cioè richieste che cambiano, invia o cancellano (normalmente POST).

Per maggiori informazioni su CORS vedi qui: link

    
risposta data 10.11.2013 - 21:52
fonte
2

I criteri interdominio impediscono ai domini di leggere le informazioni in alcune circostanze da altri domini che non lo consentono esplicitamente con intestazioni CORS . Ma questo non impedisce alle richieste di origine incrociata di uscire. La richiesta nel tuo esempio dovrebbe essere un " pre-volo "% richiesta diOPTIONS : una richiesta di verifica per verificare se la richiesta" effettiva "avrà esito positivo.

Parte della soluzione potrebbe essere quella di terminare le richieste di OPTIONS all'inizio del processo: non appena è possibile determinare se l'accesso al dominio probing è consentito.

Una soluzione più completa può comportare token di accesso API. A ogni caricamento della pagina, genera e incorpora un token di accesso. Includere quel token in tutte le richieste API / AJAX. Qualsiasi richiesta che non include il token dovrebbe terminare anticipatamente.

    
risposta data 02.09.2014 - 16:50
fonte
2

L'idea migliore qui è come altri dichiarati, usa i token CSRF. La forma più semplice è quella di aggiungere l'indirizzo IP dell'utente come identificatore in un database e quindi aggiungere un valore casuale per questo IP. Il valore casuale è il token corretto.

Ad esempio, quando qualcuno visita la tua pagina per ottenere il modulo, porta l'IP dell'utente, diciamo: 12.12.12.12.

Aggiungi in un database di valori-chiave con valore casuale: 12.12.12.12 = ljghsdlghdlghdlshsdflgd (nota, NON usare l'esempio "ljghsdlghdlghdlshsdflgd", invece genera un valore pseudo-casuale di una lunghezza sufficiente)

Aggiungi questo valore pseudo-casuale come campo nascosto.

Al momento dell'invio, utilizza l'indirizzo IP dell'utente per cercare la risposta suggerita. Se la risposta effettiva corrisponde alla risposta suggerita, la richiesta viene accettata. In QUALUNQUE tentativo di invio (indipendentemente dal successo o meno), eliminare il record nel database, se esiste. Ciò significa che qualsiasi tentativo CSRF invaliderà i token reali per l'utente target e ogni token sarà di tipo monouso. A seconda del tipo di database, è semplice come impostare la chiave su "" o semplicemente cancellarlo.

Come: 12.12.12.12="".

Una buona idea è anche quella di scadere di questi valori in base al tempo, sia per motivi di sicurezza, sia per eliminare dati non necessari nel database. A seconda che si tratti di un forum, può essere saggio avere un paio d'ore come tempo di validità, mentre se è un semplice modulo per dire, cambia una password, quindi è sufficiente per circa 5 minuti come tempo di validità.

Un'altra idea è captcha, che impedisce anche attacchi automatici lato client, come infezioni da virus e trojan di controllo remoto automatizzati. A seconda della sensibilità dell'applicazione Web, può essere una buona idea utilizzare i token Captcha AND CSRF all'unisono. Non seguire il consiglio di utilizzare lo stesso token per un'intera sessione, è una cattiva idea per quanto riguarda la sicurezza poiché esiste una piccola possibilità che l'utente possa essere indotto a inviare un token a un utente malintenzionato e al sito. Un token monouso sarà privo di difetti per l'attaccante, ma un token multiuso può essere pericoloso quanto una sessione, che CSRF è progettato per proteggere.

Quindi usa i token monouso, è la migliore sicurezza rispetto ai token multiuso, e anche i token monouso non devono essere protetti in transito come suggerito dall'articolo CSRF in una delle altre risposte.

    
risposta data 03.09.2014 - 06:39
fonte
1

La pagina del server non dovrebbe essere eseguita se tutto è configurato correttamente. La richiesta dovrebbe essere rifiutata prima che abbia la possibilità di arrivare così lontano.

Sospetto che tu abbia configurato la tua applicazione / server per avere Access-Control-Allow-Origin impostato su * . Ci sono un certo numero di posti che possono essere fatti, ma uno comune per l'applicazione asp.net è in web.config (s). Esempio:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
  </customHeaders>
</httpProtocol>

Vorrei verificare se hai questo set ovunque nella tua app. Tieni presente che asp.net può avere più file web.config e utilizzerà le impostazioni dal più vicino. Ad esempio, supponiamo di avere la seguente struttura di directory:

/MyProject/ajax/stuff

Se hai un web.config nella tua directory MyProject e un web.config nella tua directory stuff , i file in stuff useranno il web.config da stuff ovunque sia possibile.

Fammi sapere se questo è fonte di confusione.

Inoltre, credo che questo possa essere configurato anche in IIS, quindi dai un'occhiata anche alle intestazioni.

    
risposta data 24.10.2013 - 20:35
fonte

Leggi altre domande sui tag