 Hi, ich muss mich ganz am Anfang ein bisschen entschuldigen, weil das ein render der Vortrag gerade ist. Das war ein interner Vortrag bei uns in der Firma, ich habe es hingekriegt, dass ich ihn offen halten darf, weil es auch einfach öffentliche Daten sind und einfach offen sein sollte. Woraus basiert das Ganze? Ich bin seit ungefähr zehn Jahren in der IT-Security tätig. Ungefähr auch so lange existieren diverse Angriffe, die jeden Tag rauskommen, im Prinzip jedes Jahr rauskommen auch, zu Java-Serialisierungsformate, zu YAML, zu X6, also die X6-E-Attacken. Das wurde irgendwann auch in OWASP aufgenommen und dergleichen. Und ich höre jedes Mal von Entwicklern das Gleiche. Wir verwenden JSON. JSON ist sicher. Und damit will ich ein bisschen aufräumen, weil JSON hat ganz, ganz, ganz große Probleme an vielen Punkten. Es ist die Linguafranca im Web inzwischen, alle Sprachen unterstützen es, jeder, man kann es einsetzen, und als Entwickler kommt man eigentlich nicht dran vorbei. Und trotzdem sollte man die Probleme kennen, die man sich damit ins Haus holen könnte, wenn man das richtig einsetzt. Der ganze Vortrag basiert auf einem Pen-Test, den wir gemacht haben vor ungefähr einem Jahr, wo wir uns ein sehr komplexes System angeguckt haben, wo wir JSON-Daten von einer Stelle über mehrere Systeme hinweg, durch mehrere Sprachen hinweg betrachten mussten. Also es kam an einer Stelle rein und wurde dann durch einen Python-Parser durchgepackt, durch einen Rust-Parser, durch einen Go-Parser und dergleichen anderen JSON-Parsern, was zu massiven Problemen führen kann, wenn man es nicht richtig betreibt. Deswegen geht es jetzt hier auch nicht um einen Angriff auf die Pasa selber, sondern eher auf dieses Zwischending. Was passiert eigentlich in dem einen Pasa und was passiert eigentlich in dem anderen Pasa? Mal ganz kurz darüber reden, was JSON überhaupt ist. Es ist ein Serialisierungsformat. Es ist so 1997 rum entstanden, so 2001 am Ende, wo das Final auf JSON.org mal hochgeladen von Crockford. Und es ist so klein, dass man es auf eine Business-Karte packen kann. So war es auch gedacht. Es unterstützt ganz wenige Datenformate und es war wirklich, wirklich basic angelegt. Das ist auch super so. Inzwischen hat sich aber richtig viel drum entwickelt. Es gibt insgesamt sieben unterschiedliche Entwicklungspunkte an diesem ganzen Ding. Es gibt eine Seite JSON.org, was das erste Herausheben quasi war. Dann wurde es irgendwann später mal in einem RFC gegossen. Da war es dann erst mal da. Dann wurde das ECMA-Skript rausgegeben, ECMA 404. Ein bisschen später kamen wirklich nur so auf Druck raus, weil sie JSON anpassen wollten. So ist zumindest die Gerüchte dahinter stehen. Dann kamen nochmal ein RFC. Diese zweite RFC, die danach im gleichen Jahr kam, ist nur ein Typho gewesen, wo man quasi ein Typho angepasst hat. Und die letzte RFC, da stehen wir jetzt gerade 2017. Das ECMA 404 ist auch von 2017. Das ist die aktuelle RFC, so wie sie gilt für JSON im Endeffekt. Und das große Zitat, was man sich immer in diesem ganzen Ding vor Augen halten muss, kommt von Crockford selber. Er wollte nie eine Versionsnummer rausgeben. Und das macht unter Umständen so ein bisschen Probleme, weil niemand weiß, an welcher Pasa unterstützt, welches JSON und was unterstützt welcher Pasa. Und das ist echt gemein. Das ist echt fies. Ich weiß auch nicht, wie man da im Sinnfort umgehen will, außer man probiert es aus. Das sind so die vier Dinge, über die ich heute reden will. Einerseits, was passiert eigentlich, wenn man den gleichen Key reingibt? Also, da reden wir kurz drüber. Was passiert überhaupt mit Unicode-Charakteren? Inzwischen ist es auch ein bisschen verbessert. Aber wie gehen unterschiedliche Pasa damit um? Da steht Comment Truncation. Ja, manche Pasa in JSON unterstützen Kommentare. Aber alle irgendwie so ein bisschen anders. Und es ist nicht im RFC konform. Und wie geht man eigentlich mit großen Zahlen um? Und wie geht man mit Floats um? Und was ja immer irgendwie so ein Problem ist in der IT? Gehen wir mal ganz am Anfang rein. Was passiert eigentlich, wenn man einen JSON-Pasa zweimal den gleichen Key reingibt? Mit unter Umständen unterschiedlichen Werten. Was ist an der Stelle Test? Naja, lass uns mal in die RFC gucken. Die meisten Pasa sagen, ja, wir nehmen das letzte Element. Das gibt auch irgendwie Sinn, weil man überschreibt ja ein Element. Und es wird sogar in manchem Dokumentation beschrieben, ja, man kann ein Element setzen als Definition. Und dann später packt man das zweite Element dazu. Aber das ist nicht genormt. Der RFC sagt, ja, man kann das letzte nehmen. Manche Pase sagen auch einfach, es ist ein Fehler. Und andere geben auch einfach beide zurück. Und irgendwie ganz andere geben einfach das letzte zurück. Das ist zum Beispiel der Fall in Go. Go, der Standard Pase, gibt das letzte Element. Gibt, glaube ich, das erste Element zurück. Python gibt das letzte Element zurück. So unterscheidet sich das alles einfach ein bisschen. Das kann man jetzt auch wirklich für einen Angriff nutzen. Man stellt sich beispielsweise vor, man hat ein Bezahl-Service beziehungsweise man hat ein Order-Service und man hat ein Bezahl-Service. Und wenn man ein Element durchgereicht, dann kann ich irgendwie sowas reingehen. Wo ich eine Quantitie von minus eins reingehe und eine Quantitie von eins. Das geht vorne in einem Ein-Element durch und hinten geht es mit minus eins durch und mir wird irgendwas gut geschrieben. Aber vorne steht ja das Richtige. Ich kann später, wer gerne noch Fragen hat, auch gerne auf Labs verweisen, wo man das ausprobieren kann. Ich habe jetzt bewusst auch keine diversen Ausprobier-Sachen dabei. Das ist ja auch, weil sich da auch viel tut, gerade, genau. Das heißt, der Pasa muss entscheiden, was tut er überhaupt und du weißt es selber auch nicht. Das heißt, ja, das sollte man sich auf jeden Fall angucken, wenn man mehrere Entwickler hat oder wenn man unterschiedliche Systeme bewendet oder man einfach Elemente durchreicht. Es passieren einfach seltsame Dinge. Was passiert mit Charakteren, die nicht so definiert sind? So Unicode und diversen anderen Sachen. Zum Beispiel so was. Ja, es kommt darauf an. Selbst wenn man sich nur Python anguckt, dann ist JSON und UJSON macht es anders. Und das ist ein Problem. Also in der richtigen Entwicklungsumgebung setzt man wahrscheinlich ein Pasa ein. Ich glaube nicht, dass wenn man jetzt eine große Applikation schreibt, dann hat man irgendwie so eine Uniformität. Aber in einem komplexen System, wo man mehrere Systeme unterstützt und mehrere Clients hat und mehrere Entwickler hat und unterschiedliche Firmen vielleicht auch hat, die unterschiedliche Verfrenzen hat, gibt es ein Problem. Das Bild ist ein bisschen klein, aber im Endeffekt geht es darauf raus, dass man versucht, ein User als Superatman anzulegen. Es geht nicht, weil Superatman ist eine gesperrte Gruppe. Aber ich kann vielleicht eine Gruppe anlegen, die Superatman mit einem Charakter ist, der chunketed wird am Ende. Dann lege ich diese Superatmen-Gruppe an, kann plötzlich den User dagegen anlegen und kann mich aber einloggen und kriege aber den Superatman zurück, weil der im Hintergrund in der API chunketed wird und ich Superatman zurück kriege. Und dann bin ich plötzlich Atman, obwohl ich diese Gruppe nie hätte anlegen dürfen oder den Nutzer damit anlegen dürfen. Sollte so nicht sein. Aber RFC sagt dazu auch nichts. Es gibt keine Definition dafür, wie sich der Parse da verhalten sollte. Was passiert mit Comments? Wie schon gesagt, eigentlich, wenn man sich das Board anguckt für die Entwickler, Stack Overflow und man nach Kommentaren in Jason guckt, dann wird er immer gesagt, ja, Jason unterstützt keine Kommentare. Doch ein paar Pasa tun das und es wird auch genutzt und es wird auch teilweise so gesagt. Was passiert beispielsweise bei so einem Kommentar oder bei so etwas, wo wir am Ende quasi ein Key Extra haben und dann nochmal Test1 und Extra2 reinsetzen? Schauen wir uns mal ein Go lang Pasa an und den Java's Jason Iterator an der Stelle. Das sind einfach unterschiedliche Ausgaben und das Objekt, was erzeugt wird, ist einfach unterschiedlich. Und da kann ich nicht von ausgehen, dass ich ein sicheres Übertragung von Elementen habe, weil es einfach anders verhält. Das Gleiche ist auch mit Java Jason und SimDj Jason Ruby der Fall, dass ich einfach Elemente hinzufügen kann und auch duplige Keys an der Stelle hinzufügen kann, die sich dann unterschiedlich verhalten. Da kann man jetzt noch ganz viel darauf eingehen. Da gibt es noch endlos viele Fälle, was da noch passieren kann an der Stelle. Aber gehen wir mal zum Nächsten. Zum Beispiel Floats und Integer. Die sind immer problematisch. Floats und Integer, keine Frage. Ich habe mal Informatik studiert, aber da bleibt man irgendwann auch weg von denen. Das war zumindest die Aussage von meinen Profs. Wir geben einfach mal eine große Zahl rein. Was in dem Fall Objekt test? Er kommt halt auf die Sprache an. Aber das ist auch klar, manche unterstützen keine Big-Names, manche unterstützen keine und so weiter. Und der FC sagt es auch so, das kommt halt auf die Sprache an, kommt halt darauf an, wer damit umgeht und was man damit macht. Und das kann beispielsweise dabei rauskommen. Und das ist teilweise noch nicht mal JSON-conform. Das heißt, nur weil ein JSON-Encoder das so geschrieben hat, heißt es nicht, dass ein anderer das so lesen kann. Das kommt auf den Goodwill im Endeffekt von dem jeweiligen anderen Pasaan, ob der das unterstützt. Insgesamt hat ungefähr 2018 war es, hat ein Entwickler mal angefangen, alles zu sammeln. Er hat alle Pasa zusammengeschrieben, hat Testcases geschrieben, ich habe es hier verlinkt. Es ist eine endlose Liste, die machte unglaublich Spaß zu lesen. Danach hat man keinen Spaß mehr dran. Aber sein Fazit aus dem Ganzen ist, er hat keine zwei Pasa gefunden, die sich identisch verhalten haben bei seinen Testcases. Er hat immer Unterschiede gefunden und hat immer unterschiedliches Hasen gefunden. Und mit so schwammigen RFCs ist es auch nicht möglich, eigentlich etwas so zu schreiben, dass es funktioniert oder dass es identisch ist an der Stelle, dass es identisch rauskommt. Jetzt ist die Frage, was macht man damit? Jason ist da und Jason wird verwendet. Naja, ich als Pentester sehe das genauso wie Entwickler. Es ist nicht so wichtig, wenn man sich anguckt, was man verwendet und welche Pasa man verwendet und dass man dem Inhalt, der reingegeben wird in seine Api oder in seine Elemente, einfach nicht vertraut. Also alles, was vom User kommt, nicht vertraut. Weil das kann alles irgendwie kaputtgehen. Und wenn halt mehrere Pasa involviert sind, kann es halt ein bisschen mehr kaputtgehen. Da kann halt nicht nur die Logik kaputtgehen, dass man irgendwie, dass ein User minus eins rein gibt und das kann halt plötzlich irgendwo dahinter plötzlich minus eins werden. Das heißt nicht nur an der vordersten Stelle prüfen, sondern allen Stellen prüfen. Genau. Und das sollte eigentlich dieser ganze Take-Away darin sein. Und warum mir das so wichtig ist, ich sehe diese Diskussion um Jason im Endeffekt jedes Jahr oder alle zwei Jahre oder sowas, kommt das mal so kurz auf. Und dieses Jahr ist es wieder passiert, dass jemand darüber geschrieben hat. Und ich mir dachte, ist das nicht bekannt? Und man erst gemerkt hat, wie wenig Leuten so diese bewusst ist, was da kaputtgehen kann. Und das ist nur, weil es unterschiedlich gepasst wird. Wir reden hier noch nicht darüber, dass die Pase an sich kaputte Objekte bauen unter Umständen. Dass diese Schwachstellen gab es auch und gibt es unter Umständen auch noch. Das geht nur darum, dass sie sich unterschiedlich verhalten in unterschiedlichen Momenten. Genau. Ich war jetzt ein wenig schneller als eigentlich erwartet und wollte das sehr, sehr unterbrechen, das Ganze, um mal zu andenken oder zum Denken anzuregen. Aber wenn Fragen sind, könnt ihr gerne reinstellen, dann würde ich einfach eine Frage-Grunde eröffnen. Und wir machen das einfach einen sehr, sehr kurzen Talk. Ich hätte tatsächlich eine Frage. Und zwar bei XML gibt es ja sowas wie so eine Document-Type-Definition, mit der man festlegt, welche Attribute sind überhaupt möglich. Gibt es denn sowas bei Jason auch oder so Ideen dazu, so ein Paar so ein bisschen aufzubohren, dass der sicherer wird? Also manche Sprachen machen das. GoLang macht ein Structrum, beispielsweise. Und andere Sprachen auch. Aber ich bin mir nicht ganz sicher, ob man wirklich ein Schematat rumschreiben kann im allgemeinen Sinne, weil es der Paar so unterstützen muss an der Stelle. Aber ist es sicher möglich, einen zu schreiben, der das sicherer macht oder zumindest warnt, wenn sowas vorkommt. Es wird ja oft schon ausreichen, wenn ein seltsames Verhalten auftaucht und er nicht weiß, wie er damit umgehen soll oder failed. Das heißt genau dieses Thema mit dem fail. Das heißt, normalerweise gehen die so Daumen von wegen, so wie HTML. Der User soll nicht mit Fehlern belästigt werden. Und wir tun einfach mal so, als wüssten wir besser, was am Ende rauskommen soll. Aber eben dadurch, dass es eben nicht definiert ist, hat jeder eine andere Überlegung gehabt, was denn am Ende rauskommen soll, wenn unerwartetes Input oder Unkranktes. Wie stark ist denn im Moment die Initiative, dass das in einem RFC glattgezogen wird? Weil das, was in der Welt ist, ist da und wahrscheinlich hat keiner Bock, das anzupassen. Das heißt, es sind viele Konkurrenzpaser, die ja auch kein Interesse haben, dass die eine Lösung jetzt vorrang hat und die bei sich was ändern müssen und der andere gewinnt, weil er keine Arbeit hat, das anzupassen. Ich glaube, Jason wird so langsam abgelöst. Es ist immer noch da und es wird immer noch verwendet und es werden aber immer wieder, es kommen andere relevante Sprachen zustande oder andere relevante Datenformate gerade, die, ob es jetzt Protobuf ist, ob es jetzt Messageblock ist und so weiter. Da kommen ein paar, die interessant sind und die kleiner sind, die weniger Daten verbrauchen in der Übertragung. Aber eine Initiative, es gab einen Versuch, also der letzte RFC 2017, der hat schon sehr viel glatt gezogen, lustigerweise, aber noch nicht genug, aber mir ist auch keine Initiative bekannt, die sich damit auseinandersetzt, weil es ist nicht so wichtig. Also es ist wichtig zu wissen, es ist wichtig zu wissen, welcher Pasa was macht, in welchen Edge-Cases und dass man darauf Rücksicht nimmt, dass sowas passiert. Aber da streckt so viel dahinter. Ich kann mir gut vorstellen, dass, wenn man anfängt, daran was zu verändern an den einzelnen Pasern, dass ganz viel kaputt gehen wird. Weil natürlich unterschiedliche Elemente unterschiedlich laufen. Also ob es jetzt Default-Werte sind in JSON-Objekten am Anfang, wo dann einfach das zweite Element genommen wird und manche Pase dann plötzlich anders sich verhalten oder so. Deswegen ist es ganz schwer, da was anzupassen und deswegen wurde auch ECMAScript 4.04 ziemlich schnell rausgedrückt, 2013, 2014, weil sie Angst hatten, dass dann Initiative kommt, die JSON so krass verändert, dass es ganz viel kaputt machen wird. Ja, klar. Ich glaube, den meinst du, oder? Ja. Also es ist bewusst so klein, weil es ist einfach sehr viel. Deswegen habe ich den Link dazu gepackt, falls die Test-Cases werden auch automatisch generiert. Da kommen auch immer wieder neue Test-Cases dazu. Das werden immer wieder neue Pase dazu. Es ist eigentlich ganz spannend, sich das anzugucken und mal drüber nachzudenken, was da kaputt geht. Okay, super. Vielen Dank.