Bin ich überfordert, wenn ich das absichtliche Fehlverhalten des Benutzers in Betracht ziehe?

12

Ist es übertrieben, wenn ich den Benutzer vor absichtlichen Fehlverhalten schütze (um es milde auszudrücken), wenn der Schaden, den der Benutzer erleiden kann, nicht mit meinem Code zusammenhängt?

Zur Verdeutlichung stelle ich einen einfachen JSON RESTful-Service wie diesen bereit:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

Der Dienst selbst ist nicht für die Verwendung über einen Browser gedacht, sondern nur für Anwendungen von Drittanbietern, die vom Benutzer gesteuert werden (z. B. Telefon-Apps, Desktop-Apps usw.). Außerdem sollte der Dienst selbst statusfrei sein (dh ohne Sitzung).

Die Authentifizierung erfolgt mit der Standardauthentifizierung über SSL.

Ich spreche von einem möglichen "schädlichen" Verhalten wie diesem:

Der Benutzer gibt die GET-URL in einem Browser ein (kein Grund, aber ...). Der Browser fragt nach der Basisauthentifizierung, verarbeitet sie und speichert die Authentifizierung für die aktuelle Browsersitzung. Ohne den Browser zu schließen, besucht der Benutzer eine böswillige Website, die über ein böswilliges CSRF / XSRF- Javascript verfügt, das einen POST für unseren Service durchführt.

Das obige Szenario ist höchst unwahrscheinlich, und ich weiß, dass ich mir aus geschäftlicher Sicht keine allzu großen Sorgen machen sollte. Denken Sie jedoch, dass Sie zur Verbesserung der Situation helfen können, wenn der Benutzername / das Kennwort auch in den JSON-POST-Daten erforderlich sind?

Oder sollte ich Basic Auth komplett löschen, das GET entfernen und nur POST / PUT mit Autorisierungsinformationen verwenden? Da die durch GET abgerufenen Informationen auch sensibel sein können.

Wird die Verwendung benutzerdefinierter Header als reine REST-Implementierung betrachtet? Ich kann die Basisauthentifizierung löschen und benutzerdefinierte Header verwenden. Auf diese Weise kann zumindest ein CSRF-Angriff durch einen Browser vermieden werden, und die Anwendungen, die den Dienst verwenden, legen den Benutzernamen / das Kennwort in benutzerdefiniertem Format fest. Schlecht für diesen Ansatz ist, dass der Dienst nun nicht mehr von einem Browser aus genutzt werden kann.

Sonnig
quelle
3
Wie auch mit meiner Antwort möchte ich auch diese Aussage hinterlassen, ich denke, dies würde wahrscheinlich besser auf SO oder Security beantwortet werden
Jeff Langemeier
1
Ich denke, dass Sie PUT und POST gemäß RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ) umgestellt haben .
Svante

Antworten:

6

Überengineering? Überhaupt nicht. Anti-XSRF-Maßnahmen sind ein notwendiger Bestandteil einer sicheren Webanwendung oder eines sicheren Dienstes. Es ist wahrscheinlich oder auch nicht sehr unwahrscheinlich, dass jemand Sie angreift, aber das macht Ihre Software nicht weniger unsicher.

Systeme wurden häufig mit XSRF angegriffen, und obwohl die Ergebnisse weniger sofort offensichtlich schlecht sind als bei SQL-Injection oder XSS, sind sie ziemlich schlecht genug, um alle benutzerinteragierbaren Funktionen zu gefährden.

Das bedeutet, dass Sie keine "reine" REST-Schnittstelle haben können, bei der die einzigen Parameter die Eigenschaften des Aufrufs selbst sind. Sie müssen etwas in die Anfrage aufnehmen, das ein Angreifer nicht erraten konnte. Das könnte das Benutzername-Passwort-Paar sein, aber das ist bei weitem nicht die einzig mögliche Wahl. Sie könnten den Benutzernamen zusammen mit dem Token aus einem gesalzenen Hash des Passworts generieren lassen. Möglicherweise werden Token vom Dienst selbst zur Authentifizierungszeit ausgestellt (die in der Sitzung gespeichert oder kryptografisch überprüft werden können).

soll ich das GET loswerden

Nein, GET-Anforderungen werden für Leseanforderungen verwendet, die keine aktive Schreiboperation haben (sie sind "idempotent"). Es sind nur Schreibvorgänge, die einen XSRF-Schutz erfordern.

Bobince
quelle
Was ist, wenn die GET-Anforderung vertrauliche Informationen enthüllen kann?
Sunny
@Sunny: Was denkst du über sensible Daten?
Chris
2
Chris, wenn ich paranoid werde, sind alle Daten sensibel, wenn sie vom "falschen" Benutzer empfangen werden :). Es ist theoretisch.
Sunny
Bitte überprüfen Sie die Änderungen in der Frage, die ich hinzugefügt habe.
Sunny
1
Es ist in Ordnung, wenn die Antwort (ob GET oder eine andere Methode) Daten enthält, die nur der Benutzer sehen sollte. Bei einem XSRF-Angriff kann der Angreifer nur vom Benutzer eine bestimmte Anforderung ausführen lassen. Die Antwort, die von dieser Anforderung zurückkommt, kann nicht gelesen werden. Es sei denn, das Zielskript wurde auf spezielle Weise erstellt, damit Seiten von Drittanbietern es <script>absichtlich („JSONP“) oder versehentlich ( ungeschütztes JSON ) von einem Tag lesen können .
Bobince
32

Vertraue niemals etwas. Jede Anfrage ist ein Angriff. Jeder Benutzer ist ein Hacker. Wenn Sie mit dieser Denkweise entwickeln, ist Ihre Anwendung viel sicherer, stabiler und wird weniger wahrscheinlich von einem böswilligen Benutzer missbraucht. Alles, was Sie tun müssen, ist eine geschickte Person, die einen Weg findet, um Ihre Sicherheit zu verbessern, damit Sie ernsthafte Probleme mit Ihren Daten haben (eine Ihrer wertvollsten Ressourcen ).

Wenn Sie in Ihrer Anwendung eine Sicherheitslücke entdeckt haben, tun Sie alles, was Sie tun müssen, um die Lücke zu schließen. Insbesondere Ihre API sollte die nicht vertrauenswürdigste Software sein, die es gibt. Ich würde die Anmeldeinformationen benötigen und mit Post Anfragen gehen.

Jarrod Brennnesseln
quelle
4
YAY für Paranoia! Sie haben Feinde! (Und +1 für jede Anfrage ist ein Angriff )
Treb
0

Wenn der Code festgelegt und gepflegt ist, sollten Randfälle von Fall zu Fall geprüft und behandelt werden.

BEHEBUNG DURCH EINIGE FEHLER MEINES TEILS:

GET sollte weiterhin als Teil eines ordnungsgemäßen RESTful-Dienstes verwendet werden, die Authentifizierung muss auf jeden Fall noch vorhanden sein. Was ich zu vermuten versuchte, war, dass GET aus Sicherheitsgründen fast das Gleiche ist wie POST, aber post erledigt seine Arbeit, ohne die Informationen in eine Adressleiste zu schreiben, was den großen Sicherheitsunterschied darstellt (und warum ich GET nicht mag), aber als Gepostet von @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Da dies von Anwendungen von Drittanbietern verwendet wird, sollten bewährte Verfahren für einen RESTful-Service befolgt werden, damit der Endimplementierer in diesem Bereich nicht verwirrt wird.

Jeff Langemeier
quelle
3
Wie unterscheidet sich GET von POST hinsichtlich der Sicherheit? Beide werden einfach über den Transport (HTTP oder HTTPS) gesendet. Der einzige Unterschied besteht darin, dass GET-Abfragezeichenfolgen in der Adressleiste sichtbar sind.
Tdammers
1
@Sunny: POST ist in dieser Hinsicht genauso exponiert wie GET. Starten Sie Telnet und sprechen Sie mit einem Webserver, wenn Sie mir nicht glauben.
tdammers
1
@ Jeff: Der Grund, warum ich Telnet (oder Curl, Wget oder einen guten, altmodischen Sniffer) aufrufe, ist, dass Sie den gesamten Datenstrom sehen können. Ja, HTTPS verbirgt diese Informationen vor Abhörern, aber jeder an beiden Enden der SSL-Verbindung kann genau sehen, was Telnet sieht.
tdammers
1
@ Jeremy: POST zeigt die Parameter nicht in der Adressleiste an, aber da die Daten im eigentlichen HTTP-Stream genauso sichtbar sind, sind Sie im Großen und Ganzen richtig.
tdammers
7
GET-Anforderungen werden zum Abrufen von Ressourcen verwendet, und PUT / POST wird zum Hinzufügen / Aktualisieren von Ressourcen verwendet, sodass die Verwendung von PUT / POST zum Abrufen von Daten für eine RESTful-API völlig den Erwartungen widerspricht.
Lee
0

Sie sollten alle plausiblen Eventualitäten berücksichtigen, einschließlich der Tatsache, dass der Benutzer aktiv böswillig ist, und (erfolgreich) alle "Security by Obscurity" -Barrieren zurückentwickeln.

Gleichzeitig sollten Sie jedoch die Auswirkungen eines erfolgreichen Hacks und die Wahrscheinlichkeit eines Versuchs einschätzen. Zum Beispiel:

  • Ein interner Dienst, der durch eine solide Firewall geschützt ist, ist weniger anfällig für Angriffe als ein Dienst im öffentlichen Internet.

  • Die Auswirkungen eines Kunden-Diskussionsforums sind geringer als der Diebstahl von Kundenkreditkarten.


Mein Punkt ist, dass "absolute Sicherheit" "unendlich teuer" und praktisch unerreichbar ist. Idealerweise sollten Sie anhand einer gründlichen Kosten-Nutzen-Analyse entscheiden, wo die Grenze gezogen werden soll.

Stephen C
quelle
Vielen Dank. Es ging nicht darum, "vor" dem Benutzer zu schützen, sondern den Benutzer selbst zu schützen, wenn er verantwortungslos handelt. Aber Ihre Antwort macht nur wenige gute Punkte.
Sunny