Aggiungendo all'aspetto di alto livello la buona progettazione dell'API fornita da @Daisetsu, il modo migliore per proteggere un'API REST basata sul web riduce a due scelte:
1 Invia tutto su HTTPS. Consenti all'utente di eseguire l'autenticazione con l'API per ottenere una chiave di sessione e includerla in ogni query futura.
BUON : tutto è sicuro.
BAD : il costo della negoziazione della connessione HTTPS richiede più risorse del server (non un problema a meno che non si disponga di un'API pesante) e il tempo di risposta a una chiamata sarà più lungo.
2 Utilizza un HMAC (firma) e invialo insieme ad ogni richiesta.
2 è ciò che molte API Amazon Web Services utilizzano e il metodo più popolare per implementare l'approccio è generalmente definito come "OAuth a 2 vie".
2 può sembrare confuso / casuale / follemente complesso dato il tuo livello di comfort con la sicurezza, quindi descriverò il succo di come funziona:
- SERVER e CLIENT condividono 2 valori: una chiave pubblica e privata.
- La chiave pubblica può essere conosciuta da più persone, va bene.
- La chiave privata NON PU CAN. Deve essere conosciuto solo dal server e dal client.
- Quando il client effettua una richiesta al server, invia due cose importanti: la chiave pubblica e un HMAC (noto anche come "firma")
La firma rappresenta un hash dei parametri inclusi nella richiesta: /search.json?public_key=123456&term=shritam&range=180days&sig=dKdjalkjDKd97daskdDKl2
- L'hash viene calcolato combinando tutti i parametri che compongono la query in una stringa, quindi eseguendo la stringa e la chiave segreta tramite un algoritmo di hashing come MD5, SHA-1, SHA-256, ecc.
- Il server riceve la richiesta e prima di fare qualsiasi altra cosa, usando la chiave pubblica fornita nella richiesta, cerca la chiave segreta dell'utente.
- Quindi il server riunisce nuovamente tutti i parametri della richiesta in ESATTAMENTE LO STESSO MODO del client e li ha cancellati con la chiave segreta appena estratta dal database per quell'utente.
- Se l'hash corrisponde, la richiesta viene eseguita. Se gli hash non corrispondono, la richiesta viene rifiutata.
Considerata la natura pedante e schizzinosa della generazione di un hash (se l'input è di 1 carattere diverso, come uno spazio extra, l'hash risultante è diverso) ci devono essere VERAMENTE regole specifiche su come i parametri sono combinati, come sono codificati, come vengono sottoposti a hash con la chiave segreta e così via.
Fortunatamente le specifiche OAuth 1.0 (sezioni da 3.4.1 a 3.4.2) fanno esattamente questo; essi definiscono esattamente il processo che server e client devono seguire quando generano quell'hash, quindi qualsiasi client o server compatibile OAuth può comunicare tra loro in modo più efficace.
Nota a margine: OAuth 2.0 è fuori, prendilo!
Indipendentemente dal fatto che tu usi OAuth o meno, devi solo accertarti che i tuoi client e server siano tutti d'accordo su COME viene creata e firmata la stringa. Amazon Web Services utilizza un metodo leggermente diverso per generare la stringa da firmare inserendo newlines dove OAuth concatena tutto insieme.
Ho visto alcune API online che generano l'HMAC facendo sì che la persona abbia cancellato la propria chiave pubblica con la propria chiave segreta e l'abbia inviata insieme; in questo caso si sta essenzialmente trasformando l'HMAC in un ID di sessione e si rischiano gli stessi problemi di side-side a cui soffrono le API session-over-unsecured.
Tieni presente che qualsiasi parametro che includi nella generazione HMAC non può essere modificato da un intercettazione man-in-the-middle e reinvia la tua query.
Qualsiasi parametro che NON fa parte del calcolo HMAC, può essere modificato da un man-in-the-middle e inviato di nuovo perché non fa parte della firma, quindi quando il server va a ricalcolare l'HMAC non lo farà vedere gli hash non corrispondenti causati dal cambiamento.
Questi sono i punti salienti della protezione di un'API REST basata su HTTP (non HTTPS).