Soll MVC / REST eine 403 oder 404 für Ressourcen anderer Benutzer zurückgeben?

33

Bei der Arbeit mit einer ressourcenbasierten Site (z. B. einer MVC-Anwendung oder einem REST-Service) haben wir zwei Hauptoptionen, wenn ein Client versucht, auf GETeine Ressource zuzugreifen, auf die er keinen Zugriff hat:

  • 403 , die besagt, dass der Client nicht autorisiert ist ; oder
  • 404 , die besagt, dass die Ressource nicht vorhanden ist (oder nicht gefunden werden konnte).

Allgemeine Weisheit und übliche Praxis scheinen zu sein, mit der Wahrheit zu antworten - das ist ein 403. Aber ich frage mich, ob dies tatsächlich das Richtige ist.

Sichere Anmeldesysteme geben niemals den Grund für einen Anmeldefehler an. Für den Kunden ist also kein Unterschied zwischen einem nicht vorhandenen Benutzernamen und einem falschen Passwort feststellbar. Damit sollen Benutzer-IDs - oder schlimmer noch E-Mail-Adressen - nicht auffindbar gemacht werden.

Aus Sicht des Datenschutzes erscheint es viel sicherer, einen 404 zurückzugeben. Ich erinnere mich an den Vorfall, bei dem Berichten zufolge jemand die Gewinner einer Reality-Show (Survivor, glaube ich) herausgefunden hat, indem er sich ansah, welche Ressourcen auf der nicht vorhanden waren Seite gegen welche. Ich mache mir Sorgen, dass ein 403 möglicherweise vertrauliche Informationen wie eine Seriennummer oder eine Kontonummer preisgibt.

Gibt es zwingende Gründe , einen 404 nicht zurückzugeben? Könnte eine 404-Richtlinie an anderer Stelle negative Nebenwirkungen haben? Wenn nicht, warum ist die Praxis dann nicht üblicher?

Aaronaught
quelle
1
Zwingender Grund, 404 nicht zurückzugeben: Wenn der Service nicht verfügbar ist oder ein Fehler bei der Authentifizierung vorliegt, erhalten Sie eine 404, aber der Kunde / Benutzer / Tester / Entwickler / Support-Mitarbeiter, der versucht, das Problem zu diagnostizieren, hat möglicherweise keine Ahnung Was ist los mit der Fehlermeldung?
Steven Evers
@Snorfus: Das ist ein guter Punkt - ich hätte es in eine Antwort gesetzt. Obwohl Josh bereits einen guten Kontrapunkt
hinzugefügt hat
Ein weiterer Aspekt, den Sie berücksichtigen sollten, ist folgende: Wie werden 404-Zellen nachgeschaltet? Gibt es eine CDN oder eine Art Caching? Wenn Sie jemals in der Lage sein möchten, diese zwischenzuspeichern, möchten Sie wahrscheinlich nicht, dass Ihr "Benutzer hat keine Berechtigung" 404s zwischengespeichert werden.
pc1oad1etter

Antworten:

15

Es gibt ein allgemeines Missverständnis (und einen Missbrauch) 403 Forbidden: Es soll nichts darüber verraten, was der Server über die Anfrage denkt. Es wurde speziell entwickelt, um zu sagen,

Ich bekomme, was Sie verlangen, aber ich werde die Anfrage nicht bearbeiten, egal was Sie versuchen. Also hör auf es zu versuchen.

Jeder UA oder Client sollte dies dahingehend interpretieren, dass die Anforderung niemals funktioniert, und angemessen reagieren.

Dies hat Auswirkungen auf Clients, die Anfragen im Namen von Benutzern bearbeiten: Wenn ein Benutzer nicht angemeldet ist, oder wenn er sich vertippt, sollte der Client, der die Anfrage bearbeitet, nach dem ersten Mal antworten: "Es tut mir leid, aber ich kann nichts tun" es bekommt das 403und hört auf, zukünftige Anfragen zu bearbeiten. Wenn ein Benutzer nach einem Fehler weiterhin Zugriff auf seine persönlichen Informationen anfordern kann, ist dies offensichtlich ein benutzerfeindliches Verhalten.

403ist im Gegensatz zu 401 Authorization Required, was sich , dass der Server die Anforderung, solange Sie die richtigen Anmeldeinformationen passieren behandeln weggeben. Dies ist normalerweise das, woran die Leute denken, wenn sie hören 403.

Es ist auch im Gegensatz dazu, 404 Page Not Foundwas, wie andere betonten, nicht nur darauf ausgelegt ist, "Ich kann diese Seite nicht finden" zu sagen, sondern dem Client vorzuschlagen, dass der Server keine Ansprüche auf Erfolg oder Misserfolg für zukünftige Anforderungen erhebt.

Mit 401und 404sagt der Server dem Client oder der UA nichts darüber, wie er vorgehen soll: Er kann weiterhin versuchen, eine andere Antwort zu erhalten.

Dies 404ist der geeignete Weg, um eine Seite zu behandeln, die Sie nicht allen zeigen möchten, aber nichts darüber preisgeben möchten, warum Sie sie in bestimmten Situationen nicht zeigen.

Dies setzt natürlich voraus, dass der Client, der die Anfrage stellt, sich um geringfügige RFC-Abweichungen kümmert. Ein Client, der böswillig genug ist, kümmert sich nicht um den zurückgegebenen Statuscode, außer auf zufällige Weise. Man erkennt, dass es sich um eine versteckte Benutzerseite (oder eine potenzielle versteckte Benutzerseite) handelt, indem man sie mit anderen bekannten Benutzerseiten vergleicht.

Nehmen wir an, Ihr Handler ist users/*. Wenn ich weiß users/foo, users/barund users/baazArbeit, der Server einer Rückkehr 401, 403oder 404für users/quuxbedeutet nicht , ich werde es nicht versuchen, vor allem , wenn ich Grund zu glauben , dass es ist ein quuxBenutzer. Ein Standard-Beispielszenario ist Facebook: Mein Profil ist privat, meine Kommentare zu öffentlichen Profilen jedoch nicht. Ein böswilliger Client weiß, dass ich existiere, auch wenn Sie 404auf meine Profilseite zurückkehren.

Statuscodes sind also nicht für böswillige Anwendungsfälle gedacht, sondern für die Clients, die sich an die Regeln halten. Und für diese Kunden ist ein 401oder eine 404Anfrage am besten geeignet.


quelle
4
Gute Punkte zu 401 vs. 403. Ich stimme der Endgültigkeit Ihrer Aussagen zu 404 jedoch nicht zu. Sicher, im Beispiel von Facebook wissen Sie bereits, dass quuxes das gibt. Es wird jedoch nicht immer externe Beweise geben, insbesondere auf nicht-sozialen Websites, auf denen Kundendaten wirklich privat sind . Ein neugieriger oder feindlichen Benutzer könnte schließlich in der Lage sein zu folgern , dass du lügst, aber nicht unbedingt , welche Ressourcen Sie liegen über . Ich denke, der springende Punkt hier ist, dass Sie sich nicht um 404-Ressourcen kümmern müssen, es sei denn, es gibt keine anderen Methoden zur Ermittlung.
Aaronaught
@Aaronaught Die Sache ist, dass Sie wirklich, wirklich sicher sein müssen , dass jemand nicht herausfinden kann, worüber der Server täuscht, oder dass es keine Methode zur Entdeckung gibt, gegen die Sie sich nicht verhärtet haben. Eine kluge Person wird es herausfinden, und zu diesem Zeitpunkt ist der Statuscode bedeutungslos.
1
Ich bin mir immer noch nicht sicher, wie eine Person, die klug genug ist, es herausfinden könnte , wenn keine Daten zwischen Benutzerprofilen ausgetauscht werden. Ich verstehe, dass irgendwann bestimmt jemand feststellen wird, dass "oh, ein 404 bedeutet, dass es möglicherweise existiert, aber ich kann einfach nicht darauf zugreifen" - aber unter der Annahme, dass der Server denselben Fehler für Ressourcen zurückgibt, die wirklich nicht existieren, wie würde man den Unterschied zwischen einer nicht existierenden und einer privilegierten Ressource erkennen?
Aaronaught
@Aaronaught Das Einzige, was eine Person wissen müsste, ist, dass die URL zu einem Profil vorhanden sein sollte. Sie können einfach Profil-IDs verwenden und diese pseudo erhöhen (eine Person mit einer Profil-ID von 3333 bedeutet also nicht, dass es eine Person mit einer Profil-ID von 3332 gibt) Stichprobengröße der gültigen IDs. Gelingt dies nicht und gibt es sogar ein vollständig gehärtetes System, bei dem keine Informationen darüber verloren gehen, wie URLs für Profilseiten generiert werden, gibt es immer Social Engineering.
8

Gemäß RFC2616

10.4.4 403 Verboten

Der Server hat die Anfrage verstanden, lehnt sie jedoch ab. Die Autorisierung hilft nicht und die Anfrage SOLLTE NICHT wiederholt werden. Wenn die Anforderungsmethode nicht HEAD war und der Server veröffentlichen möchte, warum die Anforderung nicht erfüllt wurde, MUSS er den Grund für die Ablehnung in der Entität beschreiben. Wenn der Server diese Informationen dem Client nicht zur Verfügung stellen möchte, kann stattdessen der Statuscode 404 (Not Found) verwendet werden.

Beachten Sie auch, dass beim Zugriff auf verbotene Ressourcen die Autorisierung nicht hilft .

Lüge Ryan
quelle
Ich kenne den RFC, obwohl er der Realität wenig ähnelt. Kaum ein Server erklärt jemals den Grund für einen 403 über diesen ersten Satz hinaus ("Der Server hat die Anforderung verstanden, weigert sich jedoch, sie zu erfüllen."), Und die meisten MVC-Frameworks haben sogar etwas Ähnliches, HttpUnauthorizedResultdas für privilegierte Ressourcen verwendet werden soll . Mir ist klar , auch (natürlich) , dass 404 kann stattdessen verwendet werden; Meine Frage ist, ob es verwendet werden soll oder nicht und was bei dieser Entscheidung zu beachten ist.
Aaronaught
@Aaronaught: Im RFC können Sie nicht nur 404 verwenden, sondern es wird empfohlen , 404 zu werfen, wenn Sie nichts bestätigen möchten.
Lie Ryan
3
Das ist in Ordnung, aber wann sollte ich nichts anerkennen? Oder besser gesagt, wann soll ich? Das ist wirklich der Kern der Frage.
Aaronaught
5

Solltest du? Ja .

Du hast es selbst gesagt, verrate so wenig wie möglich. Wenn ich ein System angriff und bemerkte, dass der Server mit 403 Codes antwortete, würde ich mich auf diese konzentrieren, anstatt weiterzumachen. Besser, eine Tür verkündet, dass sie nicht existiert, als zu verkünden, dass sie gesperrt ist.

Der Nachteil bei der Verwendung von 404-Anforderungen besteht darin, dass es von außen so aussieht, als ob die Seite nicht vorhanden ist. Dies kann zu Konflikten im Vergleich zu Seiten führen, die vorhanden sein sollen , aber stattdessen fehlen. Wenn Sie sich keine Sorgen um Webcrawler machen (authentifizierte Systeme sollten sowieso komplett abgelehnt werden), sollten Sie sich unbedingt dafür entscheiden. Alle APIs, die ich nicht autorisiert habe, werden genauso behandelt wie StackOverflow . Kann diese Seite nicht sehen? Ich versichere Ihnen , es tut exist, obwohl er behauptet , nicht zu tun .

Sie sollten Anfragen bestätigen , wenn die Ressource bekannt zu existieren und der Zugriff verweigert wird. Eine fehlgeschlagene Anmeldung sollte nicht zu einer 404-Nachricht führen. Sie sollten Anforderungen nicht bestätigen, wenn die Existenz der Ressource selbst geschützt werden soll. Der Zugriff auf den Realm ist in der Öffentlichkeit vorhanden, die darin enthaltenen Sicherheitsgruppen oder -rollen jedoch nicht.


Zwingender Grund, 404 nicht zurückzugeben: Wenn der Service nicht verfügbar ist oder ein Fehler bei der Authentifizierung vorliegt, erhalten Sie eine 404, aber der Kunde / Benutzer / Tester / Entwickler / Support-Mitarbeiter, der versucht, das Problem zu diagnostizieren, hat möglicherweise keine Ahnung Was ist los mit der Fehlermeldung?

Entwickler sollten Zugriff auf Protokolle haben, die einen Versuch anzeigen, auf eine geschützte Ressource zuzugreifen. Kunden / Benutzer / Tester generieren Feedback, das schließlich einen Entwickler trifft.

Sicherheit durch Dunkelheit ... wirklich?

Dies ist keine Sicherheit durch Unbekanntheit. Sie verwenden Unbekanntheit zusätzlich zu den richtigen Sicherheitsmaßnahmen.

Gültige Anfragen, die hingegen ein "404" erhalten, erhöhen nur die Komplexität und Unübersichtlichkeit, wenn dies nicht erforderlich ist

Sie sind keine gültigen Anfragen, sie sind nicht autorisierte Anfragen. Sie ändern einen kleinen Teil (Rückgabe 404 statt 403), um einen wesentlichen Vorteil für potenzielle Angreifer zu erzielen.

Josh K
quelle
Sicherheit durch Dunkelheit ... wirklich? Wenn jemand versucht, Ihre Dienste mit böswilliger Absicht zu stupsen, weiß er bereits, dass sie dort sind. Gültige Anfragen, die hingegen ein "404" erhalten, erhöhen nur die Komplexität und Unübersichtlichkeit, wenn dies nicht erforderlich ist.
Steven Evers
4
@Snorfus: Hier muss ein subtiler Unterschied zwischen Sicherheit und Datenschutz gemacht werden . Privatsphäre ist, fast per definitionem, "durch Unbekanntheit". Dies ist besonders wichtig im Zusammenhang mit einem ressourcenbasierten System, da das Vorhandensein oder Nichtvorhandensein einer Ressource möglicherweise eine wichtige Information ist. Möglicherweise gibt es auch Sicherheitsargumente, mit denen ich mich jedoch weniger beschäftige. Ich würde gerne mehr über diese zusätzliche Komplexität erfahren. Können Sie über Ihren ersten Kommentar hinaus ins Detail gehen? (Vielleicht in einer umfassenderen Antwort? Wurden Sie von 404'ed 403s gebissen?)
Aaronaught
2
@Snorfus: Ich möchte im Nachhinein noch hinzufügen, dass Tiefenverteidigung nicht dasselbe ist wie Sicherheit durch Dunkelheit . Letzteres impliziert, dass es keine anderen Schutzmaßnahmen gibt. Ein bereits sicheres System zu verschleiern, kann jedoch oftmals eine gute Sache sein - solange es später keine weiteren Probleme verursacht. In diesem Fall ist es selbstverständlich, dass das System bereits gesichert ist, da die 404s durch einen Autorisierungscode ausgegeben werden.
Aaronaught
@Aaronaught: Ich werde eine ausführlichere Antwort veröffentlichen, aber zum Thema: Wenn eine Ressource privat ist, welche Gründe stecken dahinter, sie öffentlich zugänglich zu machen?
Steven Evers
@Snorfus: Eine Ressource ist für einen Kunden - oder vielleicht für eine Gruppe - privat , nicht für die ganze Welt.
Aaronaught
0

Es hängt wirklich von den Informationen ab, die der Statuscode 403 liefert. Wenn ein API-Endpunkt GET /myresource/{id}mit einem 404 antwortet, wenn die Ressource nicht vorhanden ist, sollte der Statuscode, der vom Endpunkt zurückgegeben wird, wenn die Ressource vorhanden, aber nicht für den aktuellen Benutzer autorisiert ist, von der Vorhersagbarkeit des idParameters und der Menge abhängen von Informationen, die es selbst enthält.

  • Wenn ides sich um ein privates Feld wie eine E-Mail-Adresse oder eine Bankkontonummer handelt, sollte es wahrscheinlich immer hinter einem 404 versteckt sein. Im Falle einer E-Mail-Adresse könnte dies verhindern, dass Spam-Bots eine Liste gültiger E-Mail-Adressen erstellen, die auf Ihrer Website registriert sind.
  • Wenn ides sich um einen öffentlichen Benutzernamen handelt, gibt es andere Möglichkeiten, auf diese Informationen zuzugreifen (z. B. indem Sie einfach auf der Forenseite Ihrer Website surfen).
  • Wenn ides sich um eine undurchsichtige, aber vorhersehbare Kennung handelt (z. B. eine automatisch inkrementierende Ganzzahl), geben Sie dem Angreifer keine Informationen weiter, die er auf andere Weise nicht erhalten konnte. Meiner Meinung nach ist es also sicher, einen 403-Statuscode zurückzugeben.
  • Wenn ides sich um eine undurchsichtige, unvorhersehbare Kennung handelt (wie eine zufällige GUID), ist die Frage subtiler. Ich persönlich denke, es ist kein Problem, einen 403-Statuscode zurückzugeben. Diese Informationen könnten nur ausgenutzt werden, wenn ein anderer fehlerhafter Endpunkt in Ihrer API diese ID verwendet, der eigentliche Fehler jedoch Ihr anderer Endpunkt ist.

Sie können davon ausgehen, dass es in jedem Fall besser ist, auf Nummer sicher zu gehen und die Informationen unabhängig vom Kontext zu verbergen. Sie können sich jedoch nicht auf diese Art von Verhalten verlassen, um irgendeine Form von Sicherheit zu gewährleisten . Auf der anderen Seite kann es Vertraulichkeit bieten (oder Privatsphäre, wie andere gesagt haben).

Ein Sicherheitsmechanismus sollte für den Angreifer nicht nur ein Geschwindigkeitsschub sein, sonst ist er schlichtweg nutzlos. In diesem Fall können Sie möglicherweise sogar andere Funktionen nicht richtig verwenden (Crawler, Webanwendungsfirewall, die nach ungewöhnlichen Mengen von 403 Statuscodes suchen, um Benutzer zu blockieren ...).

Maxime Rossini
quelle