Domanda

Sto iniziando a costruire un'API REST per un progetto a cui sto lavorando e mi ha portato a fare una piccola ricerca sul modo migliore per costruire un'API usando RoR. Scopro abbastanza rapidamente che, per impostazione predefinita, i modelli sono aperti al mondo e possono essere chiamati tramite URL semplicemente inserendo un "quot .xml" alla fine dell'URL e passando i parametri appropriati.

Quindi è arrivata la domanda successiva. Come posso proteggere la mia app per impedire modifiche non autorizzate? Nel fare delle ricerche ho trovato un paio di articoli che parlavano di attr_accessible e attr_protected e di come possono essere usati. L'URL particolare che ho trovato parlando di questi è stato pubblicato nel maggio del '07 ( qui ).

Come per tutte le cose rubino, sono sicuro che le cose si siano evolute da allora. Quindi la mia domanda è: è ancora il modo migliore per proteggere un'API REST in RoR?

In caso contrario, cosa suggerisci in uno dei "nuovi progetti"? o uno "progetto esistente" scenario?

È stato utile?

Soluzione

Esistono diversi schemi per l'autenticazione delle richieste API e sono diversi dalla normale autenticazione fornita da plugin come restful_authentication o act_as_authenticated. Soprattutto, i client non manterranno le sessioni, quindi non esiste un concetto di accesso.

Autenticazione HTTP

È possibile utilizzare l'autenticazione HTTP di base. Per questo, i client API useranno un nome utente e una password regolari e lo inseriranno nell'URL in questo modo:

http://myusername:mypass@www.someapp.com/

Credo che restful_authentication supporti questo immediatamente, quindi puoi ignorare se qualcuno sta usando la tua app tramite l'API o tramite un browser.

Uno svantaggio qui è che stai chiedendo agli utenti di mettere il loro nome utente e password in chiaro in ogni richiesta. Eseguendolo su SSL, puoi renderlo sicuro.

Non credo di aver mai visto un'API che lo utilizza, comunque. Mi sembra una buona idea decente, soprattutto perché è supportato dagli attuali schemi di autenticazione, quindi non so quale sia il problema.

Chiave API

Un altro modo semplice per abilitare l'autenticazione API è usare le chiavi API. È essenzialmente un nome utente per un servizio remoto. Quando qualcuno si iscrive per utilizzare la tua API, dai loro una chiave API. Questo deve essere passato con ogni richiesta.

Uno svantaggio qui è che se qualcuno ottiene la chiave API di qualcun altro, può fare richieste come quell'utente. Penso che facendo sì che tutte le tue richieste API utilizzino HTTPS (SSL), puoi compensare un po 'questo rischio.

Un altro aspetto negativo è che gli utenti utilizzano le stesse credenziali di autenticazione (la chiave API) ovunque vadano. Se vogliono revocare l'accesso a un client API la loro unica opzione è quella di cambiare la loro chiave API, disabilitando anche tutti gli altri client. Ciò può essere mitigato consentendo agli utenti di generare più chiavi API.

Chiave API + firma chiave segreta

Obsoleto (sorta di) - vedi OAuth sotto

Significativamente più complesso sta firmando la richiesta con una chiave segreta. Questo è ciò che fanno Amazon Web Services (S3, EC2 e simili). In sostanza, si danno all'utente 2 chiavi: la loro chiave API (es. Nome utente) e la loro chiave segreta (es. Password). La chiave API viene trasmessa con ogni richiesta, ma la chiave segreta no. Al contrario, viene utilizzato per firmare ogni richiesta, in genere aggiungendo un altro parametro.

IIRC, Amazon realizza questo prendendo tutti i parametri alla richiesta e ordinandoli per nome del parametro. Quindi, questa stringa viene hash, usando la chiave segreta dell'utente come chiave hash. Questo nuovo valore viene aggiunto come nuovo parametro alla richiesta prima di essere inviato. Da parte di Amazon, fanno la stessa cosa. Prendono tutti i parametri (tranne la firma), li ordinano e l'hash usando la chiave segreta. Se questo corrisponde alla firma, sanno che la richiesta è legittima.

L'aspetto negativo qui è la complessità. Far funzionare correttamente questo schema è un problema, sia per lo sviluppatore API che per i client. Aspettatevi molte chiamate di supporto ed e-mail arrabbiate dagli sviluppatori client che non riescono a far funzionare le cose.

OAuth

Per combattere alcuni dei problemi di complessità con la chiave + firma segreta, è emerso uno standard chiamato OAuth . Al centro OAuth è un insieme di chiavi + firma segreta, ma gran parte di essa è standardizzata ed è stata inclusa nelle librerie per molte lingue .

In generale, è molto più facile sia per il produttore che per il consumatore dell'API utilizzare OAuth piuttosto che creare il proprio sistema chiave / firma.

OAuth segmenta intrinsecamente anche l'accesso, fornendo credenziali di accesso diverse per ciascun consumatore API. Ciò consente agli utenti di revocare selettivamente l'accesso senza influire sulle altre applicazioni che consumano.

In particolare per Ruby, esiste un gemma OAuth che fornisce supporto immediato sia per i produttori che per i consumatori di OAuth. Ho usato questo gioiello per costruire un'API e anche per consumare API OAuth e sono rimasto molto colpito. Se ritieni che l'applicazione abbia bisogno di OAuth (al contrario del più semplice schema di chiavi API), allora posso facilmente consigliare di utilizzare la gemma OAuth.

Altri suggerimenti

  

Come posso proteggere la mia app per impedire   modifiche non autorizzate?

attr_accessible e attr_protected sono entrambi utili per controllare la capacità di eseguire assegnazioni di massa su un modello ActiveRecord. Sicuramente vuoi usare attr_protected per prevenire attacchi di iniezione di forma; vedi Usa attr_protected o ti hackereremo .

Inoltre, per impedire a chiunque di accedere ai controller nell'app Rails, avrai quasi sicuramente bisogno di un sistema di autenticazione utente e inserisci un before_filter nei tuoi controller per assicurarti di avere un utente autorizzato che effettua la richiesta prima di consentire l'esecuzione dell'azione del controller richiesta.

Consulta la Guida alla sicurezza di Ruby on Rails (parte del progetto di documentazione Rails) per tonnellate informazioni più utili.

Al momento sto affrontando domande simili a te perché sto anche creando un API REST per un'applicazione rotaie.

Suggerisco di assicurarsi che solo gli attributi che possono essere modificati dall'utente siano contrassegnati con attr_accessible. Questo imposterà una lista bianca di attributi che possono essere assegnati usando update_attributes.

Quello che faccio è qualcosa del genere:

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

Tutti i miei modelli ereditano da quello, in modo che siano costretti a definire attr_accessible per tutti i campi che vogliono rendere assegnabili in massa. Personalmente, vorrei che ci fosse un modo per abilitare questo comportamento di default (potrebbe esserci, e non lo so).

Solo per sapere che qualcuno può assegnare in massa una proprietà non solo usando l'API REST, ma anche usando un normale post di modulo.

Un altro approccio che consente di risparmiare molte cose da soli consiste nell'utilizzare qualcosa come http://www.3scale.net / che gestisce chiavi, token, quote ecc. per i singoli sviluppatori. Fa anche analisi e crea un portale per sviluppatori.

Esiste un plug-in ruby ??/ rails plug-in ruby ??API che si applica alle politiche per il traffico non appena arriva - puoi usarlo insieme alla oAuth gem . Puoi anche usarlo lasciando cadere la vernice davanti all'app e usando la mod lib di vernice: Modulo API Varnish .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top