Sicurezza degli schemi di autenticazione REST


228

Sfondo:

Sto progettando lo schema di autenticazione per un servizio web REST. Non è necessario "realmente" essere sicuri (è più un progetto personale) ma voglio renderlo il più sicuro possibile come un'esperienza di esercizio / apprendimento. Non voglio usare SSL poiché non voglio la seccatura e, soprattutto, le spese per la sua configurazione.

Queste domande SO sono state 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 evitare 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 dei due firma il corpo della richiesta per le richieste POST o PUT. Questo 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 desiderati dall'attaccante?

Mi sembra di poterlo evitare includendo un hash del corpo della richiesta nella stringa che viene firmata. È sicuro?


6
Amazon S3 può includere un Content-MD5 come parte della stringa di intestazione per impedire l'attacco MITM che descrivi.
Laz

8
MD5 è una funzione hash molto debole e il suo utilizzo è stato scoraggiato da molti anni ormai: en.wikipedia.org/wiki/MD5 . Usa SHA2 al giorno d'oggi. MD5 è rossetto su un maiale con una crisi di identità.
Henrik,

6
Startcom fornisce certificati SSL gratuiti che non generano avvisi sui certificati nei principali browser
Platone

5
@SeanKAnderson (rant: trovo assurdo come la gente parli del 99,99999% s quando Internet è sotto assedio da parte di agenzie di spionaggio che hanno automatizzato MOLTI attacchi già al 2008 - è un modo così strano di affrontare un vero problema - "Naaah, non sarà un problema; per mia nonna non sarà in grado di hackerarlo"
Henrik,

2
@Plato Consiglierei LetsEncrypt in questi giorni per
certificati

Risposte:


168

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

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

Se non usi l'autenticazione client TLS, dovrai utilizzare qualcosa come uno schema di autenticazione basato su digest (come lo schema personalizzato di Amazon Web Service) o OAuth 1.0a o persino l'autenticazione HTTP di base (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 tramite il filo rimangano non manomessi. Sono preoccupazioni separate ma complementari.

Per chi fosse interessato, ho ampliato una domanda SO sugli schemi di autenticazione HTTP e su come funzionano .


16
Esattamente. L'unica cosa che SSL verifica per quanto riguarda l'API è che la chiamata con cui ha a che fare non è stata disturbata durante il percorso. L'API non ha ancora idea di chi ci stia parlando o se debba avere accesso o meno.
Tim Gautier,

1
Buona risposta. Auspico inoltre avere uno sguardo a questi eccellenti risorse .. owasp.org/index.php/Web_Service_Security_Cheat_Sheet e owasp.org/index.php/REST_Security_Cheat_Sheet (BOZZA)
dodgy_coder

2
Solo un aspetto secondario, ma l'utilizzo di SSL ha anche il vantaggio aggiuntivo di prevenire gli attacchi di intercettazioni e man in the middle.
dodgy_coder

@Les Hazlewood Potresti spiegare in che modo l'autenticazione HTTP di base su Https può aiutare a determinare il server sa con chi sta parlando?
Primavera,

@Les Hazlewood qui l'ho fatto in una domanda; tnx stackoverflow.com/questions/14043397/…
Primavera,

60

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 dovranno disporre di librerie di crittografia.

Una volta che ti impegni a SSL, in linea di principio non è necessario nulla di speciale per l'autenticazione. Puoi di nuovo andare con gli standard web e utilizzare l'autenticazione HTTP di base (nome utente e token segreto inviati insieme ad ogni richiesta) in quanto è molto più semplice di un protocollo di firma elaborato e comunque efficace nel contesto di una connessione sicura. Devi solo assicurarti che la password non superi mai il testo normale; quindi se la password viene mai ricevuta tramite una connessione in testo normale, potresti persino disabilitare la password e spedire allo sviluppatore. Dovresti anche assicurarti che le credenziali non siano registrate da nessuna parte al momento della ricezione, così come non registreresti una password normale.

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. Sebbene possa essere eccessivo per le applicazioni meno sensibili se hai preso le precauzioni di cui sopra. Dopotutto, la password dell'utente viene già trasmessa in testo normale quando accede (a meno che tu non stia eseguendo una crittografia JavaScript sofisticata nel browser) e allo stesso modo i loro cookie su ogni richiesta.

Tieni presente che con le API è meglio che il client passi 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 API.

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

(Aggiornato per comprendere le implicazioni del rendere solo la connessione SSL.)


3
Potresti ottenere un certificato ssl GoDaddy per circa $ 30 all'anno penso. Sono rimasto scioccato nel vedere quanto varranno i certificati SSL Verisign ($ 600 all'anno o qualcosa del genere se ricordo bene?) Ma l'opzione GoDaddy è perfettamente fattibile.
Brian Armstrong,

19
A meno che non si stia utilizzando l'autenticazione reciproca SSL / TLS e la certificazione utilizzata dall'utente / client sia considerata attendibile dal server, non è stato autenticato l'utente nel server / nell'applicazione. Dovresti fare qualcosa in più per autenticare l'utente sul server / sull'applicazione.
Pauld

5
Ryan: la crittografia SSL in questi giorni richiede una quantità piuttosto piccola di potenza di elaborazione rispetto a quella che useresti per generare una risposta con un framework di app web come Django o Rails ecc.
Cameron Walsh,

4
i certificati di startcom sono gratuiti e ampiamente riconosciuti. cacert.org è un'alternativa aperta con meno riconoscimenti
Dima Tisnek,

17
Questo non affronta la domanda, che riguarda l'autenticazione.
Sam Stainsby

8

In alternativa, è possibile utilizzare la soluzione nota a questo problema e utilizzare SSL. I certificati autofirmati sono gratuiti ed è un progetto personale giusto?


2
I certificati autofirmati sono gratuiti, ma AFAIK hai ancora bisogno di un IP statico.
dF.

8
@dF non è necessario disporre di un IP statico ad eccezione di determinati requisiti di licenza commerciali pagati per i certificati.
Chris Marisic,

Se hai il controllo degli archivi di certificati su entrambe le estremità (client e server), questa potrebbe essere un'opzione praticabile ma ... la gestione e la distribuzione dei certificati è probabilmente molto più complessa nella produzione che in un ambiente di sviluppo. Assicurati di comprendere le complessità di questa alternativa prima di impegnarti.
Aled

5

Se richiedi l'hash del corpo come uno dei parametri nell'URL e tale URL è firmato tramite una chiave privata, un attacco man-in-the-middle sarebbe in grado di sostituire il corpo solo con contenuti che genererebbero il stesso hash. Facile da fare con i valori di hash MD5 ora almeno e quando SHA-1 è rotto, beh, ottieni l'immagine.

Per proteggere il corpo da manomissioni, è necessario richiedere una firma del corpo, che un attacco man-in-the-middle avrebbe meno probabilità di riuscire a rompere poiché non conoscono la chiave privata che genera la firma .


9
Trovare una stringa che genererà lo stesso hash md5 del contenuto valido potrebbe essere molto più facile di quanto dovrebbe essere, ma trovare una versione malvagia di contenuto valido che abbia hash sullo stesso valore è ancora proibitivamente difficile. Questo è il motivo per cui md5 non viene più utilizzato per gli hash delle password, ma viene comunque utilizzato per verificare i download.
Tim Gautier,


1

Ricorda che i tuoi suggerimenti rendono difficile per i client comunicare con il server. Devono comprendere 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 suggerirei di verificare gli standard e le soluzioni esistenti come:

Crittografia XML (standard W3C)

Sicurezza XML

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.