authentication agenzia - Sicurezza degli schemi di autenticazione REST




entrate api (6)

Una risposta precedente menzionava solo SSL nel contesto del trasferimento dei dati e in realtà non copriva l'autenticazione.

Stai davvero chiedendo di autenticare in modo sicuro i client API REST. A meno che non si stia utilizzando l'autenticazione del client TLS, SSL da solo NON è un meccanismo di autenticazione valido per un'API REST. SSL senza client authc autentica solo il server , che è irrilevante per la maggior parte delle API REST perché si desidera veramente autenticare il client .

Se non si utilizza l'autenticazione client TLS, è necessario utilizzare qualcosa come uno schema di autenticazione basato su digest (come lo schema personalizzato di Amazon Web Service) o OAuth 1.0a o anche l'autenticazione HTTP Basic (ma solo su SSL).

Questi schemi autenticano che la richiesta è stata inviata da qualcuno previsto. TLS (SSL) (senza autenticazione client) garantisce che i dati inviati sul filo non vengano controllati. Sono preoccupazioni separate ma complementari.

Per gli interessati, ho ampliato una domanda SO sugli schemi di autenticazione HTTP e su come funzionano .

Sfondo:

Sto progettando lo schema di autenticazione per un servizio web REST. Questo non ha "veramente" bisogno di essere sicuro (è più di un progetto personale) ma voglio renderlo il più sicuro possibile di un'esperienza di esercizio / apprendimento. Non voglio usare SSL dal momento che non voglio il fastidio e, soprattutto, la spesa per configurarlo.

Queste domande SO erano particolarmente utili per iniziare:

Sto pensando di utilizzare una versione semplificata dell'autenticazione di Amazon S3 (mi piace OAuth ma sembra troppo complicato per le mie esigenze). Sto aggiungendo un nonce generato casualmente, fornito dal server, alla richiesta, per impedire attacchi di riproduzione.

Per arrivare alla domanda:

Sia S3 che OAuth si basano sulla firma dell'URL della richiesta insieme ad alcune intestazioni selezionate. Nessuno di loro firma il corpo della richiesta per le richieste POST o PUT. Non è vulnerabile a un attacco man-in-the-middle, che mantiene l'url e le intestazioni e sostituisce il corpo della richiesta con tutti i dati richiesti dall'attaccante?

Sembra che posso evitare questo includendo un hash del corpo della richiesta nella stringa che viene firmata. È sicuro?


O potresti usare la soluzione nota a questo problema e usare SSL. Le cerimonie autofirmate sono gratuite e si tratta di un progetto personale giusto?



REST significa lavorare con gli standard del web e lo standard per il trasferimento "sicuro" sul web è SSL. Qualsiasi altra cosa sarà un po 'funky e richiederà uno sforzo di implementazione extra per i client, che dovrà disporre di librerie di crittografia disponibili.

Una volta effettuato il commit su SSL, non c'è davvero niente di fantasia richiesto per l'autenticazione in linea di principio. È possibile utilizzare nuovamente gli standard Web e utilizzare l'autenticazione HTTP Basic (nome utente e token segreto inviati insieme a ciascuna richiesta) poiché è molto più semplice di un protocollo di firma elaborato e comunque efficace nel contesto di una connessione sicura. Devi solo essere sicuro che la password non vada mai oltre il testo normale; quindi, se la password viene mai ricevuta tramite una semplice connessione testuale, è possibile anche disabilitare la password e inviare la posta allo sviluppatore. È inoltre necessario assicurarsi che le credenziali non vengano registrate ovunque al momento del ricevimento, proprio come non si registrerebbe una normale password.

HTTP Digest è un approccio più sicuro in quanto impedisce il passaggio del token segreto; invece, è un hash che il server può verificare dall'altra parte. Anche se potrebbe essere eccessivo per le applicazioni meno sensibili se hai preso le precauzioni sopra menzionate. Dopo tutto, la password dell'utente viene già trasmessa in formato testo quando si effettua il login (a meno che non si stia eseguendo una bella crittografia JavaScript nel browser), e allo stesso modo i loro cookie su ogni richiesta.

Nota che con le API, è meglio che il client stia passando dei token - stringhe generate casualmente - invece della password con cui lo sviluppatore accede al sito web. Quindi lo sviluppatore dovrebbe essere in grado di accedere al tuo sito e generare nuovi token che possono essere utilizzati per la verifica dell'API.

Il motivo principale per utilizzare un token è che può essere sostituito se è compromesso, mentre se la password è compromessa, il proprietario può accedere all'account dello sviluppatore e fare tutto ciò che vuole con esso. Un ulteriore vantaggio dei token è che puoi rilasciare token multipli agli stessi sviluppatori. Forse perché hanno più app o perché vogliono token con diversi livelli di accesso.

(Aggiornato per coprire le implicazioni di rendere la connessione solo SSL.)


Ricorda che i tuoi suggerimenti rendono difficile per i client comunicare con il server. Devono capire la tua soluzione innovativa e crittografare i dati di conseguenza, questo modello non è così buono per le API pubbliche (a meno che tu non sia amazon \ yahoo \ google ..).

Ad ogni modo, se devi crittografare il contenuto del corpo ti suggerisco di verificare gli standard e le soluzioni esistenti come:

Crittografia XML (standard W3C)

Sicurezza XML


Ho intenzione di atterrare con il seguente:

PUT fa riferimento a una risorsa, identificata dall'URI. In questo caso, lo stai aggiornando. È la parte dei tre verbi che si riferiscono alle risorse: cancella e ottieni gli altri due.

Il POST è fondamentalmente un messaggio in forma libera, con il suo significato definito "fuori dalla banda". Se il messaggio può essere interpretato come l'aggiunta di una risorsa a una directory, sarebbe OK, ma in pratica è necessario capire il messaggio che si sta inviando (postare) per sapere cosa accadrà con la risorsa.

Poiché PUT, GET e DELETE si riferiscono a una risorsa, sono anche per definizione idempotenti.

POST può eseguire le altre tre funzioni, ma in tal caso la semantica della richiesta andrà persa sugli intermediari come cache e proxy. Questo vale anche per fornire sicurezza sulla risorsa, dal momento che l'URI di un post non indica necessariamente la risorsa a cui si sta applicando (può però).

A PUT non ha bisogno di essere una creazione; il servizio potrebbe errore se la risorsa non è già stata creata, ma in caso contrario aggiornarla. O viceversa - potrebbe creare la risorsa, ma non consentire aggiornamenti. L'unica cosa necessaria per PUT è che punta a una risorsa specifica e il suo carico utile è la rappresentazione di quella risorsa. Un PUT riuscito significa (escludendo l'interferenza) che un GET recuperi la stessa risorsa.

Modifica: Un'altra cosa: un PUT può creare, ma se lo fa, l'ID deve essere un ID naturale - AKA un indirizzo email. In questo modo quando PUT due volte, il secondo put è un aggiornamento del primo. Questo lo rende idempotente .

Se l'ID viene generato (un nuovo ID dipendente, ad esempio), il secondo PUT con lo stesso URL creerà un nuovo record, che viola la regola idempotent. In questo caso il verbo sarebbe POST e il messaggio (non la risorsa) sarebbe quello di creare una risorsa usando i valori definiti in questo messaggio.







rest authentication oauth amazon-s3 rest-security