MVC / REST dovrebbe restituire un 403 o 404 per le risorse appartenenti ad altri utenti?

32

Quando si lavora con un sito basato su risorse (come un'applicazione MVC o un servizio REST), abbiamo due opzioni principali quando un client prova a GET una risorsa a cui non hanno accesso:

  • 403 , che dice che il client è non autorizzato ; o
  • 404 , che dice che la risorsa non esiste (o che non può essere localizzata).

La saggezza comune e la pratica comune sembra essere quella di rispondere con la verità - cioè un 403. Ma mi chiedo se questa sia effettivamente la cosa giusta da fare.

I sistemi di accesso sicuro non ti dicono mai il motivo di un errore di accesso. Vale a dire, per quanto riguarda il cliente, non c'è differenza rilevabile tra un nome utente inesistente e una password errata. Lo scopo è di non rendere identificabili gli ID utente o, peggio, gli indirizzi e-mail.

Da un punto di vista privacy , sembra molto più sicuro restituire un 404. Mi viene in mente l'incidente in cui qualcuno avrebbe scoperto i vincitori di un reality show (Survivor, credo) di osservando quali risorse non esistevano sul sito rispetto a quelle che hanno fatto. Sono preoccupato per un 403 che potenzialmente potrebbe dare informazioni sensibili come un numero seriale o un numero di conto.

Ci sono ragioni convincenti non per restituire un 404? Una politica 404 potrebbe avere effetti collaterali negativi altrove? Se no, allora perché la pratica non è più comune?

    
posta Aaronaught 08.06.2011 - 03:20
fonte

4 risposte

15

Esiste un malinteso generale (e un uso improprio) associato a 403 Forbidden : non si deve dare nulla a ciò che il server pensa della richiesta. È specificamente progettato per dire,

I get what you're requesting, but I'm not going handle the request, no matter what you try. So stop trying.

Qualsiasi UA o client dovrebbe interpretare ciò per indicare che la richiesta mai funzionerà e rispondere in modo appropriato.

Questo ha implicazioni per i client che gestiscono le richieste per conto degli utenti: se un utente non ha effettuato l'accesso, o esegue l'oscuramento, il client che gestisce la richiesta dovrebbe rispondere, "Mi dispiace, ma non posso fare nulla" dopo la prima volta che ottiene 403 e smette di gestire le richieste future. Ovviamente, se si desidera che un utente sia ancora in grado di richiedere l'accesso alle proprie informazioni personali dopo un errore, si tratta di un comportamento ostile all'utente.

403 è in contrasto con 401 Authorization Required , che fa comunica che il server gestirà la richiesta fino a quando si passeranno le credenziali corrette. Questo è solitamente ciò a cui pensa la gente quando sente 403 .

È anche in contrasto con 404 Page Not Found che, come altri hanno sottolineato, è progettato non solo per dire "Non riesco a trovare quella pagina" ma per suggerire al client che il server non fa affermazioni di successo o fallimento per richieste future.

Con 401 e 404 , il server non dice nulla al client o alla UA su come dovrebbero procedere: possono continuare a provare nella speranza di ottenere una risposta diversa.

Quindi 404 è il modo appropriato per gestire una pagina che non vuoi mostrare a tutti, ma non vuoi rivelare nulla sul perché non lo mostrerai in determinate situazioni.

Ovviamente, questo presuppone che il cliente che fa la richiesta si preoccupi della meschina RFC flippancy. Un client abbastanza malizioso non si preoccuperà del codice di stato restituito se non in modo incidentale. Uno saprà che è una pagina utente nascosta (o una potenziale pagina utente nascosta) confrontandola con altre pagine utente conosciute.

Cioè, diciamo che il tuo gestore è users/* . Se so che users/foo , users/bar e users/baaz funzionano, il server che restituisce 401 , 403 o 404 per users/quux non significa che non ho intenzione di provarlo, specialmente se ho ragione di credere che sia un quux utente. Uno scenario di esempio standard è Facebook: il mio profilo è privato, ma i miei commenti sui profili pubblici non lo sono. Un client dannoso sa che esisto anche se restituisci 404 nella pagina del mio profilo.

Quindi i codici di stato non sono per i casi di utilizzo dannoso, sono per i clienti che giocano secondo le regole. E per quei clienti, una 401 o una 404 richiesta è più appropriata.

    
risposta data 08.06.2011 - 05:25
fonte
8

Secondo RFC2616

10.4.4 403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.

noti anche che quando accedi a risorse Proibite, l'autorizzazione non aiuta .

    
risposta data 08.06.2011 - 03:47
fonte
5

Dovresti? .

L'hai detto tu stesso, tradisci il meno possibile. Se stavo attaccando un sistema e ho notato che il server rispondeva con 403 codici, mi concentrerei su quelli, invece di andare avanti. Meglio una porta proclamare che non esiste quindi per proclamarlo come sbarrato.

Lo svantaggio di usare 404 richieste è che esternamente apparirà come se la pagina non esistesse, e questo potrebbe avere dei conflitti rispetto alle pagine che supponiamo esistano, ma che invece mancano. Se non sei preoccupato per i web crawler (i sistemi autenticati dovrebbero essere completamente negati comunque), allora dovresti assolutamente farlo. Ogni API che gestisco accesso non autorizzato allo stesso modo e così StackOverflow . Non riesci a vedere quella pagina? Ti assicuro che esiste , anche se afferma di non farlo.

dovresti riconoscere le richieste quando la risorsa conosciuta esiste e l'accesso è negato. Un accesso non riuscito non dovrebbe comportare un messaggio 404. non dovresti riconoscere le richieste quando l'esistenza della risorsa stessa deve essere protetta. L'accesso al dominio esiste nel pubblico, ma i gruppi o i ruoli di sicurezza al suo interno non lo sono.

Compelling reason not to return 404: If the service is down or there is a bug/error in authentication then you'd get a 404, but the customer/user/tester/developer/support person trying to diagnose the problem may have no idea what's wrong from the error message

Gli sviluppatori dovrebbero avere accesso ai log, che indicano un tentativo di accesso a una risorsa protetta. Clienti / Utenti / Tester genereranno feedback che colpiranno uno sviluppatore.

Security by obscurity... really?

Questa non è sicurezza per oscurità. Stai utilizzando l'oscurità in aggiunta alle corrette misure di sicurezza.

Valid requests getting a "404" on the other hand are just adding complexity and obscurity where it's not necessary

Non sono richieste valide, sono richieste non autorizzate . Stai cambiando una piccola parte (restituisci 404 invece di 403) per ottenere un vantaggio sostanziale in qualsiasi aspirante attaccante.

    
risposta data 08.06.2011 - 04:09
fonte
0

Dipende molto dalle informazioni fornite dal codice di stato 403. Se un endpoint API risponde a GET /myresource/{id} con un 404 quando la risorsa non esiste, allora il codice di stato restituito dall'endpoint quando la risorsa esiste ma non è autorizzato all'utente corrente dovrebbe dipendere dalla prevedibilità di id parametro e la quantità di informazioni che contiene da solo.

  • Se id è un campo privato come un indirizzo email o un numero di conto bancario, probabilmente dovrebbe essere sempre nascosto dietro un 404. Nel caso di un indirizzo email potrebbe impedire ai robot spam di compilare un elenco di email valide indirizzi registrati sul tuo sito web.
  • Se id è un nome utente pubblico, non preoccuparti, ci sono altri modi per accedere a queste informazioni (come, semplicemente sfogliando la pagina del forum del tuo sito web).
  • Se id è un identificatore opaco ma prevedibile (ad esempio un intero autoincrementante), non si fornisce alcuna informazione all'attaccante che non è riuscito ad ottenere con altri mezzi. Quindi secondo me è sicuro restituire un codice di stato 403.
  • Se id è un identificatore opaco e imprevedibile (come un GUID casuale), la domanda è più sottile. Personalmente ritengo che non ci siano problemi nel restituire un codice di stato 403. Questa informazione può essere sfruttata solo se c'è un altro endpoint difettoso nella tua API usando questo ID, ma il vero difetto è il tuo altro endpoint.

Puoi presumere che sia meglio prevenire che curare in ogni caso e nascondere le informazioni indipendentemente dal contesto, ma in realtà non puoi fare affidamento su questo tipo di comportamento per fornire qualsiasi forma di sicurezza . D'altra parte, può fornire riservatezza (o privacy, come altri hanno detto).

Un meccanismo di sicurezza non dovrebbe essere solo un colpo di velocità per l'attaccante, altrimenti è semplicemente inutile. In questo caso, potrebbe persino impedirti di utilizzare correttamente altre funzionalità (crawler, Web Application Firewall alla ricerca di quantità anomale di 403 codici di stato per bloccare gli utenti ...).

    
risposta data 24.07.2018 - 11:22
fonte