2012-10-11 15 views
10

Sto lavorando a una pagina Web che utilizza molto AJAX per comunicare con il server. Il server, a sua volta, ha una vasta API REST/JSON che espone le diverse operazioni chiamate dal client web.Protezione API Web da applicazioni non autorizzate

Questo sito Web viene utilizzato da utenti sia anonimi che autenticati. Come ci si potrebbe aspettare, le chiamate al servizio Web emesse da utenti autenticati richiedono l'autenticazione e sono quindi protette da utenti o applicazioni non autorizzati.

Tuttavia, il sito Web presenta molte funzionalità che non richiedono autenticazione e alcune di queste utilizzano servizi Web anonimi. L'unico modo che sto usando per impedire agli estranei di chiamare questo servizio web è usando uno CSRF token. Lo so, il token CSRF non è molto utile in questo senso ... con un po 'di tempo in mano, puoi capire come consumare i servizi web anche se usano un token CSRF.

Ovviamente, è possibile utilizzare un CAPTCHA per impedire l'utilizzo autonomo del servizio Web da parte di applicazioni o bot. Tuttavia, qualsiasi essere umano sarà in grado di usarlo.

La condivisione di una chiave segreta tra client e server, dall'altra parte, sarebbe inutile. Questo, a causa della capacità di qualsiasi estraneo di leggerlo dal codice sorgente della pagina web.

Mi piacerebbe rendere questi servizi Web difficili da invocare come possibile per qualsiasi applicazione di terze parti. Cosa faresti oltre all'utilizzo del token CSRF? Sembra un po 'stupido, ma hey, forse è stupido e sto solo perdendo tempo.

Nota: data questa applicazione utilizza un browser e non un "eseguibile" come client, this question è irrilevante per la discussione. Non posso usare un segreto tra server e client (non che io sappia, almeno)

+1

Quindi quello che stai dicendo è che non vuoi che gli umani oi computer siano in grado di usare la tua API? –

risposta

1

si potrebbe avere un problema di facile di quella descritta nella questione legata dal momento che non c'è bisogno di distribuire un binario gli utenti. Anche se la tua app è open source, la chiave HMAC/firma (nella parte "Firme richieste" di quella risposta) può essere controllata da un ambiente/configurazione.

In sintesi:

  1. La chiave segreta non è in realtà inviato tra client e server. Piuttosto, è usato per firmare le richieste
  2. Assicurati che le richieste includano alcuni elementi univoci/casuali (probabilmente la tua chiave CSRF è sufficiente) in modo che due richieste per gli stessi dati API non siano identiche.
  3. Firmare la richiesta con la chiave segreta e aggiungere la firma alla richiesta. Sei collegato a una domanda PHP ma non chiari se la lingua che stai utilizzando. In .Net vorrei usare una classe HMAC come HMACSHA256.
  4. Sul lato server API utilizzare lo stesso oggetto HMAC per verificare che la richiesta sia stata firmata con la stessa chiave segreta.
+0

Penso che avrei potuto spiegarmi male. Questa è un'applicazione Web e sto parlando delle * componenti accessibili in modo anonimo * che espone. Capisco che le firme delle richieste non debbano aggiungere la chiave segreta. Tuttavia, come si distribuirebbe in modo sicuro quella chiave, data l'applicazione Web è accessibile in modo anonimo? –

+0

Ho pensato che la domanda riguardasse il controllo dell'accesso ai servizi web/API, non il sito web stesso. Cioè vuoi solo ** il tuo ** codice sito web per chiamare l'API, non qualche altro sito web o bot. E dal momento che controlli la logica lato server per entrambi i pezzi, essi hanno una chiave condivisa tra loro utilizzata per autenticare le richieste. – explunit

1

Forse potresti utilizzare i contatori per tenere traccia delle conversazioni. Solo il server e i client saranno in grado di prevedere la successiva iterazione in una conversazione. In questo modo, penso, puoi impedire ad applicazioni di terze parti di impersonare qualcuno (solo un'idea).

All'inizio, iniziano a parlare ad alcune iterazioni (i=0, ad esempio).

  • Ogni volta che il client richiede qualcosa, il contatore viene incrementato di un certo numero sia il lato server e il client (i=i+some_number).

  • E, dopo alcuni minuti di non comunicazione, entrambi sanno che devono resettare il contatore (i=0).

+0

Come identificheresti i client per incrementare il contatore? –

+1

Questa è l'idea alla base del nonce http://en.wikipedia.org/wiki/Nonce – badunk

1

Questa è solo un'idea basata sul concetto di RSA e che posiziona anche il rilevamento di frodi sul sistema. Il rischio degli utenti autorizzati è minimo, tuttavia possono tentare di effettuare chiamate anonime anche al tuo servizio web.

Per utenti UN-Authorized: per ogni chiamata al servizio Web, generare un token dire usando RSA che cambia dopo un po 'di tempo (può essere configurato diciamo 30 min). In questo modo la previsione del codice è ridotta al minimo. Fino ad ora non ho sentito parlare di collisione RSA. Invia questo token all'utente per la sua sessione del browser. Per maggiore sicurezza, potremmo voler allegare un ID di sessione con token RSA. Dal momento che gli ID di sessione sono uniche, le nuove chiamate anonime richiedono un nuovo ID di sessione.

Le chiamate possono essere tracciate utilizzando il meccanismo di controllo. Inoltre, per servizio web può esserci una diversa configurazione RSA. Come funziona l'Algorithm for Fraud Detection è una sfida da sola.

Per utenti autorizzati: Ogni utente deve essere rintracciato dal proprio indirizzo IP utilizzando il blocco intestazione. Il principio token RSA può essere applicato.

La soluzione è molto vaga, ma vale la pena considerare.

+0

Potrebbe non essere possibile tracciare l'indirizzo MAC tramite HTTP – user1428716

+0

downvoter care per commentare? – user1428716

+0

Grazie Andrew Barber – user1428716

1

Vorrei fare qualche passo.

  • Forza https sul sito. Reindirizza automaticamente qualsiasi richiesta HTTP in arrivo a https (l'attributo RequireHttps è utile per questo)
  • Ogni pagina deve (in modo sicuro, quindi https) inviare un token di utilizzo monouso al client, da utilizzare per la pagina. Lo script in esecuzione sul client può contenere questo nella memoria della pagina. Qualsiasi richiesta di ritorno invia una risposta salata con hash &, insieme con il sale nonce. Il server può ripetere i passaggi con il token salvato + salt e l'hash per confermare la richiesta. (molto simile alla risposta di explunit sopra) (Vale la pena notare che la richiesta sicura da un client non viene autenticata da un account utente, semplicemente un token inviato con l'intera pagina.)
  • La definizione per la volta potrebbe o può essere la sessione o il caricamento della pagina, a seconda della preferenza di sicurezza o comodità. I token dovrebbero essere lunghi e scaduti abbastanza rapidamente per frustrare gli attaccanti.

SSL + Hash (token + nonce) dovrebbe essere sufficiente per le vostre esigenze.

1

Questo è interessante. Di seguito è un suggerimento pazzo. Ricorda, anche la tua domanda è ugualmente pazza.

Il sito Web, una volta aperto tramite un browser, dovrebbe generare una lunga connessione di polling (Cometa di programmazione). Questo creerà una sessione unica tra il browser e il server. Quando JS sta effettuando la chiamata ajax, invia qualche token (token univoco ogni volta) al server attraverso il thread di polling lungo. Lascia che anche AJAX invii lo stesso token. Sul server, ottieni il token AJAX e verifica se hai un token simile nella tua lunga sessione di polling. Se sì, soddisfare la richiesta. Qualsiasi programmatore può rompere questo. Ma non sarà facile.È probabile che i freeboarder non vedano nemmeno questi secondi codici di cometa. È possibile implementare il codice della cometa in modo tale che non sia facile da rilevare o capire. Quando chiamano il tuo servizio, invia un messaggio "Servizio non disponibile". Saranno confusi. Rendi anche il codice della cometa https.

È anche possibile controllare per quanto tempo è aperto quel thread di polling lungo. Se la sessione è stata appena aperta e ricevi subito una chiamata Ajax, puoi supporre che si tratti di una chiamata di terze parti. Dipende dal tuo flusso del sito web. Se la chiamata Ajax avviene dopo un secondo di caricamento della pagina, è possibile verificare tale modello sul lato server.

Chiunque codifica per la tua API pubblica, avrà da 1 a 2 controlli segreti che non saprebbero nemmeno e anche se lo sapessero, potrebbero essere scoraggiati da tutta la codifica aggiuntiva che devono fare.

+0

Nessuno ha intenzione di "indovinare" a quali sono le chiamate, quindi quei tentativi di ingannare gli umani non funzioneranno davvero. Semplicemente passano come normali utenti e registrano le trasmissioni da/verso il server. Rivelerebbe rapidamente qualsiasi stranezza come parte dell'effettiva stretta di mano della sicurezza ... – badunk

Problemi correlati