Best Practices für die JSON-Sicherheit?

77

Bei der Untersuchung des Problems JSON vs XML bin ich auf diese Frage gestoßen . Nun wurde einer der Gründe, JSON zu bevorzugen, als die einfache Konvertierung in Javascript aufgeführt, nämlich mit dem eval(). Dies kam mir aus Sicherheitsgründen sofort als potenziell problematisch vor.

Deshalb habe ich mich mit den Sicherheitsaspekten von JSON befasst und in diesem Blogbeitrag darüber, wie JSON nicht so sicher ist, wie die Leute denken . Dieser Teil ragte heraus:

Update: Wenn Sie JSON zu 100% ordnungsgemäß ausführen, befinden sich nur Objekte auf der obersten Ebene. Arrays, Strings, Numbers usw. werden alle umbrochen. Ein JSON-Objekt kann dann nicht ausgewertet werden (), da der JavaScript-Interpreter denkt, dass es sich eher um einen Block als um ein Objekt handelt. Dies trägt wesentlich zum Schutz vor diesen Angriffen bei. Es ist jedoch immer noch am besten, Ihre sicheren Daten mit nicht vorhersehbaren URLs zu schützen.

Ok, das ist also eine gute Regel für den Anfang: JSON-Objekte auf der obersten Ebene sollten immer Objekte sein und niemals Arrays, Zahlen oder Zeichenfolgen. Klingt für mich nach einer guten Regel.

Gibt es noch etwas zu tun oder zu vermeiden, wenn es um JSON- und AJAX-bezogene Sicherheit geht?

Der letzte Teil des obigen Zitats erwähnt unvorhersehbare URLs. Hat jemand mehr Informationen dazu, insbesondere wie Sie es in PHP machen? Ich bin in Java weitaus erfahrener als in PHP und in Java ist es einfach (da Sie eine ganze Reihe von URLs einem einzelnen Servlet zuordnen können), während alle PHPs, die ich durchgeführt habe, dem PHP-Skript eine einzige URL zugeordnet haben.

Wie genau verwenden Sie unvorhersehbare URLs, um die Sicherheit zu erhöhen?

Cletus
quelle
Ich verstehe das überhaupt nicht! Sicherlich kann jede Anfrage des Browsers (an eine beliebige URL - unvorhersehbar oder nicht) dem Benutzer gemeldet werden, entweder über eine Konsole oder ein ausgefallenes GM-Skript ...
James
"JSON ist nicht so sicher, wie die Leute denken" ist tot
Stephan Dollberg

Antworten:

19

Die Hauptsicherheitslücke im Blog (CSRF) ist nicht JSON-spezifisch. Es ist genauso ein großes Loch, stattdessen XML zu verwenden. In der Tat ist es genauso schlecht, wenn überhaupt keine asynchronen Anrufe getätigt werden. Regelmäßige Links sind ebenso anfällig.

Wenn Leute über eindeutige URLs sprechen, meinen sie im Allgemeinen NICHT http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement . Stattdessen ist es üblicher, etwas anderes an der Anfrage eindeutig zu machen. nämlich ein Wert im FORM-Beitrag oder ein URL-Parameter.

In der Regel handelt es sich dabei um ein zufälliges Token, das auf der Serverseite in das FORMULAR eingefügt und dann überprüft wird, wenn eine Anforderung gestellt wird.

Das Array / Objekt-Ding ist neu für mich:

Skript-Tags: Der Angreifer kann ein Skript-Tag einbetten, das auf einen Remote-Server verweist, und der Browser bewertet () die Antwort effektiv für Sie, wirft jedoch die Antwort weg, und da JSON nur eine Antwort ist, sind Sie sicher.

In diesem Fall muss Ihre Site JSON überhaupt nicht verwenden, um anfällig zu sein. Aber ja, wenn ein Angreifer zufälliges HTML in Ihre Site einfügen kann, stoßen Sie an.

Chase Seibert
quelle
55

Es gibt eine Reihe von Sicherheitsangriffen gegen JSON, insbesondere gegen XSRF.

Die Sicherheitsanfälligkeit tritt auf, wenn ein Webdienst Cookies zur Authentifizierung verwendet und als Antwort auf eine GET-Anforderung mit einem JSON-Array antwortet, das vertrauliche Daten enthält.

Wenn ein Angreifer einen Benutzer, der bei einem Dienst, naive-webapp.com, angemeldet ist, dazu verleiten kann, seine Website (oder eine Website, auf der ein von ihm kontrollierter IFRAME eingebettet ist, z. B. über eingebettete Anzeigen) zu besuchen, kann er ein <script>Tag mit einem SRC einfügen die naive-webapp.com, und möglicherweise die Daten des Benutzers zu stehlen. Dies hängt von einer Javascript-Eigenart mit dem JavaScript- ArrayKonstruktor wie folgt ab :

 <script>
   // Overload the Array constructor so we can intercept data
   var stolenArrays = [];
   var RealArray = Array;
   Array = function () {
     var arr = RealArray.apply(arguments);
     stolenArrays.push(arr);
     return arr;
   }
 </script>
 <!-- even though the attacker can't access the cookies,
   - he can cause the browser to send them to naive-webapp.com -->
 <script src="//naive-webapp.com/..."></script>
 <script>
   // now stolenArrays contains any data from the parsed JSON
 </script>

EcmaScript 5 hat das dadurch verursachte verwirrende Verhalten behoben [] aufblicken Arrayauf das globale Objekt und vielen modernen Browsern zu diesem Angriff sind nicht mehr anfällig.

Übrigens ist Oil in Bezug auf unvorhersehbare URLs falsch. Kryptografisch sichere zufällige Kennungen in URLs sind eine gute Möglichkeit, Ressourcen zu schützen. Identitätsbasierte Sicherheit ist kein Allheilmittel, wie Oil vorschlägt. Siehe http://waterken.sourceforge.net/ ein Beispiel für ein sicheres verteiltes Anwendungsschema, das auf kryptografisch sicheren Kennungen in URLs basiert, für die kein Identitätskonzept erforderlich ist.

BEARBEITEN:

Wenn Sie JSON vs XML in Betracht ziehen, sollten Sie auch XML-spezifische Angriffsvektoren kennen.

XXE , XML Angriffe externer Entitäten verwenden gestaltetes XML, um über die Firewall auf Dateisystem- und Netzwerkressourcen zuzugreifen.

<!DOCTYPE root 
[
<!ENTITY foo SYSTEM "file:///c:/winnt/win.ini">
]>
...
<in>&foo;</in>

Die Anwendung bettet die Eingabe (Parameter "in", der die Datei win.ini enthält) in die Webdienstantwort ein.

Mike Samuel
quelle
Ich sehe also, wenn der Webserver Daten sendet, die nur für einen angemeldeten Benutzer als Antwort auf eine GET-Anfrage bestimmt sind, selbst wenn diese Daten JSON sind, sollte er bedenken, dass ein Angreifer diese Daten mit einem <abrufen und analysieren kann Skript> Tag. Was ist die Lösung? Ihre Web-App sollte darauf achten, nichts zu versenden, das als Antwort auf eine GET-Anfrage als Javascript oder sogar JSON analysiert werden könnte. Es sollte nur POST sein (möglicherweise mit einem Token, das mit einem vom Server gesetzten Cookie übereinstimmt). Ich denke, das ist eine ähnliche Lösung wie bei einigen anderen Bedrohungen, nicht wahr, wie GIFAR?
Thomasrutter
1
Oder wie sicher wäre es, sich nur darauf zu verlassen, dass die äußerste Ebene ein Objekt ist und der Parser bricht, weil {} als Block interpretiert wird?
Thomasrutter
Wenn Sie wissen, dass die äußerste Ebene immer ein Objekt ist und Sie Eigenschaftsnamen richtig zitieren, sollte der Parser unterbrochen werden.
Mike Samuel
3

Es ist immer noch am besten , Ihre sicheren Daten mit nicht vorhersehbaren URLs zu schützen.

Hervorhebung von mir. Was für ein Unsinn! Es ist am besten , Ihre sicheren Daten mit einer ordnungsgemäßen Authentifizierung und möglicherweise einer Verschlüsselung zu schützen. JSON-Austausche können weiterhin vorhandene Authentifizierungstechniken (z. B. Sitzungen über Cookies) und SSL verwenden.

Sich darauf zu verlassen, dass jemand keine URL errät (worüber er effektiv spricht), ist nur dann eine vernünftige Technik (und selbst dann nur gerade), wenn Sie JSON verwenden, um Daten an einen anonymen Dritten (z. B. einen Webdienst) zu exportieren. . Ein Beispiel ist die verschiedene Webdienst-API von Google, mit der anonyme Benutzer über andere Websites auf Google-Daten zugreifen. Sie verwenden Domain-Referrer- und API-Schlüssel, um sicherzustellen, dass die Man-in-the-Middle-Website Gooogle-Daten bereitstellen darf.

Wenn Sie JSON nur zum Senden privater Daten an und von einem direkten, bekannten Benutzeragenten verwenden, verwenden Sie eine echte Authentifizierung und Verschlüsselung. Wenn Sie versuchen, einen Webservice bereitzustellen, hängt dies wirklich davon ab, wie "sicher" diese Daten sein werden. Wenn es sich nur um öffentliche Daten handelt und es Ihnen nichts ausmacht, wer sie lesen kann, sehe ich keinen Sinn darin, eine Hash-URL zu erstellen.


Bearbeiten: Um zu demonstrieren, was sie bedeuten, berücksichtigen Sie dies. Stellen Sie sich vor, Ihre Bank hat eine JSON-API zum Abrufen von Kontoauszügen bereitgestellt. Wenn ich nur tippen könnte http://yourbank.com/json-api/your-name/statement, wären Sie wahrscheinlich nicht besonders zufrieden.

Sie könnten jedoch eine eindeutige Zeichenfolge für Ihr Konto generieren, die für jede JSON-Anforderung erforderlich ist, z. http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement

Ich hätte weit weniger Chancen, das erraten zu können. Aber möchten Sie wirklich, dass dies der einzige Puffer zwischen Ihren wirklich sicheren Daten und potenziellen Identitätsdieben ist? Nein.

Oli
quelle
2
Ich denke, Sie müssen den Rest des Blogs lesen: Er befürwortet keine andere Sicherheit als unvorhersehbare URLs. Was er sagt ist, dass Sicherheit durch Cookies NICHT GENUG ist und er zeigt warum.
Cletus
4
Authentifizierung hilft nicht - das ist der Punkt der Frage. Wenn der Benutzer beispielsweise bei target.com angemeldet ist (dh ein Sitzungscookie hat), versucht attacker.com möglicherweise Folgendes <script type="text/javascript" src="http://target.com/secret-data-with-predictable-url.json"/>und verwendet den von Mike beschriebenen Array-Konstruktor-Trick, um an die Daten zu gelangen, wenn das Element der obersten Ebene vorhanden ist eine Anordnung.
Jo Liss
2
Zwei Probleme: Sie verwechseln die Authentifizierung mit der Autorisierung und gehen dann fälschlicherweise davon aus, dass Kennwörter weniger leicht zu erraten sind. Was ist leichter zu erraten: eine zufällig generierte Kennung mit normalerweise zwischen 128 Bit und 1024 Bit Entropie oder ein vom Menschen generiertes Passwort mit durchschnittlich 18 Bit Eingabe? Das Hauptproblem bei URLs besteht darin, dass Benutzer nicht so daran gewöhnt sind, URLs geheim zu halten, und dass einige Arbeiten durchgeführt werden müssen, um ein Auslaufen über einen Verweis und dergleichen zu verhindern. Waterken versucht, beide Probleme anzugehen.
Mike Samuel