WEBVTT

00:00:00.017 --> 00:00:03.777
Gerade bei Webstandards ist es uns bei Mozilla total wichtig,

00:00:03.937 --> 00:00:05.437
was zu machen, was auch bleiben kann.

00:00:05.677 --> 00:00:09.217
Und dann ist es halt manchmal besser zu sagen, wir haben Prototypen,

00:00:09.297 --> 00:00:12.217
wir lassen den testen oder im Zweifelsfall halt jemanden zu bitten,

00:00:12.477 --> 00:00:15.037
sagt mal, ihr habt das schon geschippt, aber können wir das nochmal zurückdrehen?

00:00:15.097 --> 00:00:18.817
Wir wollen das ändern und wir wollen das ändern mit einem guten Grund und wir wollen es verbessern.

00:00:19.917 --> 00:00:23.597
Auch übrigens einer der Gründe, warum wir nach fünf Jahren nochmal über die

00:00:23.597 --> 00:00:24.717
Sanitizer-API sprechen.

00:00:25.137 --> 00:00:29.137
Etwas, wo ich gehofft hatte zu sagen, wir machen nur HTML und lassen den Rest

00:00:29.137 --> 00:00:30.617
weg oder verbieten den oder so.

00:00:30.897 --> 00:00:34.557
Und da gab es relativ klares Feedback von Leuten, die tiefer in Webstandards

00:00:34.557 --> 00:00:38.217
sitzen und am HTML-Spec mitschreiben oder mitarbeiten.

00:00:46.967 --> 00:00:50.207
Wenn ihr es noch nicht getan habt, würden wir uns sehr darüber freuen,

00:00:50.307 --> 00:00:52.307
wenn ihr uns eine positive Bewertung geben könntet.

00:00:52.727 --> 00:00:56.267
Auf den einschlägigen Podcast-Portalen wie Spotify und Apple Podcast könnt ihr

00:00:56.267 --> 00:00:59.107
uns gerne ein paar Sternchen hinterlassen, damit das, was wir hier machen,

00:00:59.347 --> 00:01:01.067
von mehr Menschen gefunden und gehört werden kann.

00:01:01.547 --> 00:01:04.027
Danke für eure Unterstützung und danke für eure Sternchen.

00:01:09.567 --> 00:01:16.027
Revision 697. Wir wären heute zu zweit. aus dem Team bin nur ich dabei.

00:01:16.427 --> 00:01:18.887
Und das bedeutet, wir haben einen Gast, und zwar den Frederik Braun.

00:01:19.107 --> 00:01:21.307
Hallo Frederik, hi. Hallo, hi.

00:01:23.067 --> 00:01:29.047
Danke, dass du Zeit hattest und uns hier beehrst, eigentlich zum vierten Mal

00:01:29.047 --> 00:01:33.847
schon, aber die letzten Male sind schon so lange her, wie das immer so ist.

00:01:35.567 --> 00:01:42.227
Genau, also wir haben mit dir schon drei Folgen aufgenommen zum Thema Cross-Site-Scripting,

00:01:42.567 --> 00:01:47.067
zu den Themen Komplex so Cores und Co, also Cores-Header.

00:01:47.527 --> 00:01:53.907
Und dann haben wir auch mal über Abstract-Syntax-Trees, also ASTs und Linter und so gesprochen.

00:01:54.767 --> 00:02:02.247
Genau, und wir fanden, es war wieder Zeit, dich einzuladen. Da gibt es auch einen Anlass dazu.

00:02:02.907 --> 00:02:08.567
Aber bevor wir ins Thema gehen, erzähl doch nochmal kurz, wer du bist und was du machst.

00:02:09.482 --> 00:02:14.002
Ja, genau. Also ich heiße Frederik Braun. Ich arbeite jetzt seit ungefähr 13

00:02:14.002 --> 00:02:19.562
Jahren bei Mozilla an Firefox und bin dafür Security verantwortlich.

00:02:19.642 --> 00:02:25.482
Ich habe als Engineer angefangen nach dem Studium als Praktikant und habe diverse

00:02:25.482 --> 00:02:31.742
Security-Themen bearbeitet und bin dann irgendwann seit ein paar Jahren Manager

00:02:31.742 --> 00:02:33.722
des Firefox Security-Teams. Sehr cool.

00:02:33.942 --> 00:02:38.962
Und wir machen alles von Bug-A-Bounty, Security-Prozess, Reviews.

00:02:41.042 --> 00:02:46.882
Websicherheit und Spezifikation zur Websicherheit bis hin zu diversen Koordinierungsprojekten.

00:02:47.322 --> 00:02:51.302
Wahrscheinlich guckt ihr auch auf irgendwie neue Spec-Vorschläge. Genau.

00:02:53.262 --> 00:02:57.462
Das machen wir auch. Ja, und 13 Jahre bei Mozilla ist ja jetzt,

00:02:57.902 --> 00:03:01.082
also Mozilla hat ja auch so ein bisschen einen bumpy Road hinter sich.

00:03:01.282 --> 00:03:05.782
Also ich weiß noch, dass wir mal auch Folgen aufgenommen hatten mit dem Harald

00:03:05.782 --> 00:03:12.482
Kirschner damals und mit Kadir Topal und kurze Zeit später waren die dann nicht

00:03:12.482 --> 00:03:14.222
mehr bei Mozilla, das war dann so, oh no.

00:03:15.682 --> 00:03:21.142
Deswegen cool, dass du 13 Jahre da bei der Stange bist.

00:03:22.222 --> 00:03:25.762
Ja, auf jeden Fall. Und auch cool zu sehen, was bei euch jetzt gerade wieder

00:03:25.762 --> 00:03:27.722
alles passiert. Also es macht auch Spaß.

00:03:29.503 --> 00:03:34.823
Genau und wir hatten dich schon mal zu Gast, weil du bist, also oder ich hatte

00:03:34.823 --> 00:03:36.523
den Eindruck, du wirst das korrigieren,

00:03:36.863 --> 00:03:47.283
du bist sozusagen der Erdenker, der Erfinder der Sanitizer API eines Webstandards.

00:03:47.283 --> 00:03:52.903
Und das war vor, also wir haben nachgeguckt, also dein erster Besuch bei uns,

00:03:53.223 --> 00:03:57.263
wo wir über Cross-Sat-Scripting und auch die Sanitizer-API gesprochen haben,

00:03:57.463 --> 00:04:02.723
ist fünfeinhalb Jahre her und ich weiß, dass du damals irgendwie so einen Prototyp

00:04:02.723 --> 00:04:05.863
gebaut hast, wo du einen extra Firefox,

00:04:06.423 --> 00:04:11.363
also so einen aufgeburten Firefox gebaut hattest und einen Sanitizer-API-Playground,

00:04:11.643 --> 00:04:18.303
wo du sozusagen deine Ideen dargelegt hast und Und genau, das fanden wir super interessant.

00:04:18.743 --> 00:04:25.463
Aber was eben auch passiert ist, ist nämlich, dass nicht so viel passiert ist

00:04:25.463 --> 00:04:31.823
seitdem und die Sennetizer-API irgendwie immer noch nicht in den Browsern gelandet ist.

00:04:32.043 --> 00:04:37.463
Und bis heute und jetzt sind wir, glaube ich, an dem Punkt, wo sie kommt.

00:04:38.923 --> 00:04:40.123
Tatsächlich, oder? Ja.

00:04:41.743 --> 00:04:48.983
Definitiv in Firefox 148 und Chrome 145. Das ist beides im Februar 2027.

00:04:49.823 --> 00:04:53.383
Also je nachdem, wann die Folge rauskommt, quasi jetzt schon.

00:04:53.723 --> 00:04:58.383
Und wer es testen möchte, jetzt schon in Chrome, Canary, Firefox Nightly, Beta-Version.

00:04:59.383 --> 00:05:02.183
Sehr cool. Es ist spruchreif auf jeden Fall.

00:05:02.463 --> 00:05:04.663
Jetzt ist es nicht so, ich mach das und es wird gar nicht so schwer,

00:05:04.843 --> 00:05:07.403
sondern ich hab das gemacht und es ist jetzt endlich da.

00:05:08.683 --> 00:05:16.843
Und genau, der Grund ist letztlich, dass die Idee, die du ursprünglich hattest.

00:05:17.936 --> 00:05:21.316
Im Laufe der Zeit weiterentwickelt wurde. Es wurde auch geprototyped.

00:05:21.416 --> 00:05:26.736
Ich weiß noch, dass Chrome eine Zeit lang die Sanitizer-API geschippt hatte.

00:05:26.936 --> 00:05:33.396
Also interessanterweise Chrome, obwohl du als Initiator ja bei Mozilla beschäftigt bist.

00:05:33.456 --> 00:05:37.416
Ich hätte jetzt gedacht, Mozilla ist vielleicht der erste Browser, der die schippt.

00:05:37.516 --> 00:05:39.136
Also es war hinter Flag gab es das ja.

00:05:40.096 --> 00:05:45.176
Genau. Ich glaube, hinter einer Prev gibt es immer schon eine Implementierung

00:05:45.176 --> 00:05:46.616
von der Sanitizer-API in Firefox.

00:05:46.996 --> 00:05:52.816
Aber was die wirklich tut oder tun sollte, das hat sich halt einfach super stark verändert.

00:05:53.556 --> 00:05:58.076
Und da können wir, glaube ich, auch gut über Kollaborationen mit unter anderem

00:05:58.076 --> 00:06:01.336
Chrome reden. Ein guter Webstandard braucht halt mehr als eine Person.

00:06:01.816 --> 00:06:04.876
Und wenn man es ganz kritisch beäugen möchte, dann kann man auch sagen,

00:06:05.056 --> 00:06:07.956
die Idee, die ich ursprünglich hatte, ist halt nicht das, was wir jetzt geschippt haben.

00:06:08.336 --> 00:06:11.736
Das ist ja auch der Grund, warum es länger gedauert hat und auch der Grund,

00:06:12.276 --> 00:06:15.796
warum das, was Chrome mal geschippt hat, nicht das ist, was die jetzt schippen werden.

00:06:16.436 --> 00:06:20.576
Ja, ich glaube, das ist ja so ein bisschen so die Geschichte aller Webstandards,

00:06:20.716 --> 00:06:27.516
dass es gefühlt immer relativ lange dauert, wobei ich finde,

00:06:28.096 --> 00:06:32.156
also wir sehen das ja auch immer mit großer Verwunderung, wie viel Zeit vergeht

00:06:32.156 --> 00:06:35.376
irgendwie zwischen den Besuchen unserer Gäste, also bei dir ja auch.

00:06:35.376 --> 00:06:38.816
Also mittlerweile habe ich mich daran gewöhnt und sage nicht so,

00:06:39.116 --> 00:06:40.956
Hilfe, fünfeinhalb Jahre, wie kann das sein?

00:06:42.036 --> 00:06:45.276
Aber genau, Zeit vergeht dann irgendwie doch recht schnell.

00:06:46.756 --> 00:06:49.496
Fällt mir dann bei diversen Standards auf, wenn ich dann so gucke,

00:06:49.596 --> 00:06:52.776
wann haben wir denn eigentlich das erste Mal über was gesprochen und dann holy

00:06:52.776 --> 00:06:56.296
moly, so lange ist das schon her. Ja, genau. Und das kennen wir ja auch aus

00:06:56.296 --> 00:06:57.096
der Produktentwicklung.

00:06:57.236 --> 00:07:00.376
Also ich glaube, manche Features, auch die man sich so ausdenkt,

00:07:00.936 --> 00:07:03.736
bis die dann geschippt werden, sehen die dann auch wieder anders aus.

00:07:03.856 --> 00:07:08.276
Also auch in der Produktentwicklung ist das gang und gäbe. Ja.

00:07:09.240 --> 00:07:14.980
Ja, und manchmal ist es ja der Unterschied von simpel Aussehen und simpel Sein.

00:07:15.080 --> 00:07:19.400
Und manchmal muss man ja ein Design haben, was es für alle irgendwie halbwegs

00:07:19.400 --> 00:07:23.320
einfach macht, obwohl es ganz, ganz viel Komplexität irgendwie verbirgt.

00:07:24.860 --> 00:07:27.820
Und dann fragt man sich manchmal, warum dauert das so lange?

00:07:27.980 --> 00:07:30.460
Aber wenn man dann hinter die Türen guckt, dann weiß man, okay,

00:07:30.840 --> 00:07:34.800
vielleicht hat das einen Grund, warum man da nochmal nachgebessert und diskutiert

00:07:34.800 --> 00:07:40.100
hat. Und gerade bei Webstandards ist es uns bei Mozilla total wichtig,

00:07:40.240 --> 00:07:41.740
was zu machen, was auch bleiben kann.

00:07:42.000 --> 00:07:46.540
Also unsere Prämisse ist eigentlich, dass wir am aller, aller unliebsten Dinge

00:07:46.540 --> 00:07:51.020
wieder deprecaten, wieder aus dem Browser rausnehmen, weil das eigentlich das

00:07:51.020 --> 00:07:54.420
Versprechen vom Web ist, dass existierende Webseiten weiter funktionieren sollten.

00:07:54.760 --> 00:07:57.660
Bis zu einem gewissen Grad. Natürlich stimmt das nicht immer und hundertprozentig,

00:07:57.760 --> 00:08:00.480
aber das meiste soll halt so gut sein, dass es bleiben kann.

00:08:00.640 --> 00:08:04.160
Und dann ist es halt manchmal besser zu sagen, wir haben Prototypen,

00:08:04.260 --> 00:08:08.120
wir lassen den testen oder im Zweifelsfall halt jemanden zu bitten,

00:08:08.740 --> 00:08:11.420
sagt mal, ihr habt das schon geschippt, aber können wir das nochmal zurückdrehen?

00:08:11.460 --> 00:08:14.480
Wir wollen das ändern und wir wollen das ändern mit einem guten Grund und wir

00:08:14.480 --> 00:08:18.280
wollen es verbessern, weil sonst können wir es nicht mehr, wenn wir es jetzt nicht anschippen.

00:08:18.740 --> 00:08:21.920
Und das war eine, wie ich finde, sehr, sehr gesunde Diskussion mit Chrome und,

00:08:22.440 --> 00:08:25.600
ich glaube, es ist besser geworden, obwohl und es schon einen Prototyp gab,

00:08:25.700 --> 00:08:26.800
den Leute hätten benutzen können.

00:08:27.540 --> 00:08:32.940
Ja, ich weiß auch, dass ich auch, also als Chrome die Sanitizer-API geschippt

00:08:32.940 --> 00:08:36.140
hat, dachte ich so, ah ja, alles klar, scheint fertig zu sein,

00:08:36.260 --> 00:08:38.780
so sieht die aus. Ich habe die dann auch direkt verbaut.

00:08:40.880 --> 00:08:46.260
Entschuldigung. Schlimm. Aber genau, weil es war ja kein Origin-Trial oder sowas.

00:08:46.540 --> 00:08:50.800
Oder es sind ja keine Can-Reflex gewesen. So kennt man das ja von Dingen,

00:08:51.020 --> 00:08:55.500
die im Grunde, wo noch nicht klar ist, ob die das Interface behalten oder nicht.

00:08:56.220 --> 00:08:59.780
Genau, und dann hieß es irgendwann, ja, es kommt jetzt doch wieder weg.

00:09:00.900 --> 00:09:03.900
Genau, dann habe ich es halt wieder ausgebaut. Wundert mich nur,

00:09:03.960 --> 00:09:05.800
weil das doch nicht oft vorkommt, ja.

00:09:07.277 --> 00:09:11.357
Das stimmt. Aber darüber wollen wir ein bisschen gleich reden,

00:09:11.577 --> 00:09:19.237
also wie so der Weg war von eben deiner ersten Idee bis zu der Spec,

00:09:19.517 --> 00:09:20.637
die jetzt auch geschippt wird.

00:09:21.277 --> 00:09:27.017
Aber bevor wir das machen, müssten wir vielleicht nochmal, also einmal kurz,

00:09:27.277 --> 00:09:31.577
nur ganz kurz erklären, was man mit dieser API macht, wofür die gut ist,

00:09:31.757 --> 00:09:32.777
warum wir die haben wollen.

00:09:34.497 --> 00:09:38.177
Verweisen aber auch auf die Revision 447, die wir verlinken werden,

00:09:38.497 --> 00:09:40.657
wo du ja das erste Mal zu Gast warst

00:09:40.657 --> 00:09:44.457
und wo wir uns nochmal das Transkript durchgelesen haben und gesagt haben,

00:09:46.057 --> 00:09:49.937
die könnte man eigentlich genauso heute wieder rausbringen, die Folge.

00:09:50.797 --> 00:09:56.097
Wo wir beide auch tatsächlich dann nochmal tiefer ins Detail gehen.

00:09:56.417 --> 00:10:01.537
Genau, jetzt nur so ein schnell drüber Ding. Möchte ich nochmal ganz laut bestätigen.

00:10:02.117 --> 00:10:06.617
Inhaltlich ist es das, wo ich gedacht habe, hey, das besprechen wir jetzt heute.

00:10:06.997 --> 00:10:12.697
Und dann sagten die Shownotes und die Transkription, das haben wir bereits besprochen.

00:10:13.317 --> 00:10:19.977
Von daher, ja, wärmste Empfehlung, das ist noch gut. Wenn man sich für XSS-Sicherheitslücken,

00:10:20.277 --> 00:10:26.057
Mitigations, wie man das verhindern kann und die ganzen witzigen Angriffe, die damit zu tun haben,

00:10:26.617 --> 00:10:28.757
im Detail interessiert, gerne nochmal anhören.

00:10:30.177 --> 00:10:33.557
Genau. Oder durchführen möchte. Ja.

00:10:34.177 --> 00:10:39.057
Kann man sich auch inspirieren lassen. Genau, also du hast gerade das Stichwort schon genannt.

00:10:39.237 --> 00:10:50.957
Es geht um so eine Gruppe Security oder Attacken auf Webseiten und es sind die XSS-Angriffe,

00:10:51.217 --> 00:10:55.117
Cross-Site-Scripting ist sozusagen dann die Langform.

00:10:57.915 --> 00:11:01.595
Ist einfach ein stehender Begriff, der im Grunde nicht unbedingt was mit Cross-Site

00:11:01.595 --> 00:11:06.715
zu tun hat, sondern böse Angreifer finden Mittel und Wege,

00:11:07.015 --> 00:11:11.415
Dinge in eine Webseite einzuhängen, die da nicht hingehören und die da möglicherweise

00:11:11.415 --> 00:11:13.615
unangenehme Dinge tun mit Besuchern.

00:11:14.455 --> 00:11:17.315
Genau, ich glaube, wenn man den Namen heute wählen würde, dann würde man irgendwie

00:11:17.315 --> 00:11:21.895
sagen HTML Injection oder Script Injection oder so, aber der Name ist aus den 90ern.

00:11:23.095 --> 00:11:25.935
Wenn der als Begriff steht, dann erinnert man den nicht, das macht ja auch Sinn,

00:11:26.155 --> 00:11:27.755
dass alle wissen, worüber man redet.

00:11:27.915 --> 00:11:32.335
Aber genau, Cross-Site-Scripting heißt im Grunde genommen, jemand hat die Möglichkeit,

00:11:32.495 --> 00:11:37.175
HTML in die Webseite einzuschleusen und dann, wie man ja weiß,

00:11:37.895 --> 00:11:41.915
dann ist im Endeffekt Security-mäßig Game-Over, dann kann man halbliebig umprogrammieren als Angreifer.

00:11:42.595 --> 00:11:44.095
Und das gilt es zu verhindern.

00:11:44.855 --> 00:11:50.695
Und im ganz spezifischen Fall geht es um Cross-Site-Scripting-Schwachstellen,

00:11:50.995 --> 00:11:54.955
die in der Webseite in JavaScript implementiert sind.

00:11:55.455 --> 00:11:59.795
Also man kann sich ja gut und gerne vorstellen, dass das HTML irgendwie aus

00:11:59.795 --> 00:12:03.255
dem Formular kommt, was der Benutzer abgeschickt hat, dann in die Datenbank gespeichert wird.

00:12:03.635 --> 00:12:05.915
Da kommt der nächste Benutzer, ruft irgendwie eine Webseite auf,

00:12:06.015 --> 00:12:08.695
dem wird das Ergebnis angezeigt. Ich sage mal, ein Forenpost,

00:12:08.955 --> 00:12:10.495
ein Gästbuch, Kommentar, was auch immer.

00:12:10.715 --> 00:12:13.875
Und da ist dann das HTML drin und dann ist es halt vom Angreifer in die Datenbank

00:12:13.875 --> 00:12:15.455
oder in die Datenbank an das Opfer gegangen.

00:12:16.315 --> 00:12:20.635
Und das sind halt Sachen, die man im Browser im weitesten Sinne halt nicht so

00:12:20.635 --> 00:12:23.895
wirklich stark kontrollieren kann, außer vielleicht Skript an,

00:12:23.995 --> 00:12:25.095
Skript aus im weitesten Sinne.

00:12:25.875 --> 00:12:30.515
Da wieder Pointer auf die andere Revision und Content Security Policy.

00:12:30.755 --> 00:12:35.175
Sondern es geht spezifisch darum, man hat irgendwie HTML in JavaScript und möchte

00:12:35.175 --> 00:12:39.635
das in das aktuelle Dokument hinzufügen, in der HTML etc.

00:12:39.855 --> 00:12:43.335
Pp. Und wie kann man das vorher entschärfen? Darum geht es bei der Senators API.

00:12:44.935 --> 00:12:49.355
Genau, sodass man, dass sich quasi alles nur in dem Frontend-Stack abspielt

00:12:49.355 --> 00:12:53.315
und nicht den Umweg nimmt übers Backend. ganz genau,

00:12:54.243 --> 00:13:02.083
Im Grunde wäre das Szenario, wie würde denn so ein Szenario überhaupt aussehen?

00:13:03.063 --> 00:13:09.463
Ich müsste überredet werden, von wem irgendwas anzuklicken oder einzugeben und

00:13:09.463 --> 00:13:14.643
das wäre dann ohne Umweg über das Backend.

00:13:14.863 --> 00:13:17.463
Was sind da so die typischen Szenarien?

00:13:18.843 --> 00:13:22.603
Verschiedene Dinge, Single-Page-Application mit relativ viel vanilla JavaScript

00:13:22.603 --> 00:13:25.403
kann man sich vorstellen und dann kann es im Endeffekt natürlich doch wieder

00:13:25.403 --> 00:13:26.363
aus einer Datenbank kommen,

00:13:26.483 --> 00:13:30.583
aber dann über eine REST-API oder GraphQL oder sonst was, dass man sich irgendwelche

00:13:30.583 --> 00:13:31.743
schmutzigen Sachen eintritt und

00:13:31.743 --> 00:13:35.343
die dann aber im JavaScript-Kontext in ein bestehendes Dokument einfügt.

00:13:35.663 --> 00:13:39.063
Ich glaube, wir hatten in der Folge damals auch gesprochen über,

00:13:40.123 --> 00:13:45.803
Skripte, die extern von CDNs eingebunden werden, die man eventuell auch spufen

00:13:45.803 --> 00:13:49.243
kann oder verändern könnte, also gerade wenn man so,

00:13:50.223 --> 00:13:55.203
oder so Supply Chain Tucking mäßig, also das heißt, wenn immer das letzte Paket

00:13:55.203 --> 00:13:56.543
eingebunden wird über an,

00:13:57.603 --> 00:14:02.103
PKG oder so, dass du dann irgendwas, ein neues Paket hast, was irgendwas injectet,

00:14:02.403 --> 00:14:06.463
weil du immer die latest Version lädst von dem CDN oder sowas.

00:14:07.743 --> 00:14:09.323
Wahrscheinlich auch so ein Kandidat, oder?

00:14:11.311 --> 00:14:14.771
Ja, aber dann holst du dir ja gleich schon ein bösartiges JavaScript rein.

00:14:15.331 --> 00:14:20.111
Bei XSS ist es ja meistens das Problem, dass du irgendwie HTML hast und es dir

00:14:20.111 --> 00:14:21.391
in die Webseite einfügst.

00:14:21.491 --> 00:14:24.471
Das ist meistens schon irgendwie selbstgeschrieben ergockt. Okay.

00:14:26.751 --> 00:14:33.411
Genau. Und also das heißt, genau, es funktioniert im Grunde nur,

00:14:33.651 --> 00:14:41.631
wenn man dann dieses HTML über innerHTML in den DOM-Baum hineininjectet.

00:14:42.411 --> 00:14:46.991
Es gibt ja auch die DOM-Differ, die anders arbeiten, die ja so Document,

00:14:47.351 --> 00:14:50.971
Create Element und dann Attributes setzen und so weiter.

00:14:51.871 --> 00:14:55.471
Da kann das, glaube ich, nicht so leicht passieren. Da hängt das natürlich total

00:14:55.471 --> 00:14:59.351
vom entsprechenden Framework ab, aber wenn man jetzt sowas gut abgehangen ist, benutzt wie React,

00:14:59.851 --> 00:15:04.551
dann ist XSS im weitesten Sinne gelöst, wenn man nicht diese,

00:15:04.891 --> 00:15:10.191
ich glaube, da heißt es auch extra dangerously set inner HTML oder insert HTML oder so.

00:15:10.591 --> 00:15:13.851
Wenn man das halt nicht benutzt, dann nimmt React einem das vollkommen ab.

00:15:16.011 --> 00:15:18.171
Genau, die Sanitizer API ist in dem Sinne

00:15:18.171 --> 00:15:23.691
eine sehr low-level direkte JavaScript-Funktion, die man einsetzen kann.

00:15:23.891 --> 00:15:27.691
Und ich glaube, für Frameworks auch interessant ist, wenn halt nicht direkt

00:15:27.691 --> 00:15:31.371
DOM-Diffing gemacht wird, sondern HTML eingebunden wird, dann kann man sich

00:15:31.371 --> 00:15:33.291
überlegen, will man das sicher machen?

00:15:33.591 --> 00:15:38.791
Per Default mit Konfigurationsmöglichkeiten, dass es dann wiederum anders gemacht

00:15:38.791 --> 00:15:40.911
wird, wenn man dem HTML traut. Ja.

00:15:42.351 --> 00:15:46.751
Und genau klassischerweise ist es bisher so gewesen,

00:15:47.091 --> 00:15:52.271
dass man hingeht und das HTML versucht irgendwie zu,

00:15:52.591 --> 00:16:00.311
wahlweise zu entschärfen, was eben das Escaping wäre oder man bereicht es von

00:16:00.311 --> 00:16:03.711
Dingen, die unangenehm werden können.

00:16:03.711 --> 00:16:10.051
Also sowas wie irgendwelche Inline-Event-Händler oder Script-Tags sind an sich

00:16:10.051 --> 00:16:15.391
jetzt erstmal egal, weil die ja nicht ausgeführt werden, wenn man die per HTML reinhängt.

00:16:17.031 --> 00:16:22.371
Und dafür gibt es dann Libraries und wenn man aber dieses Reinigen durchführen

00:16:22.371 --> 00:16:24.931
möchte, was eigentlich die anständige Version des Ganzen ist,

00:16:25.151 --> 00:16:30.951
dann gab es dafür oder am Ende hat sich eine Library herauskristallisiert,

00:16:31.731 --> 00:16:40.211
die auch von Security Menschen geschrieben wurde und das ist DOM Purify. Genau.

00:16:42.891 --> 00:16:49.331
Die anständigere Variante ist irgendwie HTML zu sanitisen und wir haben gesehen,

00:16:49.451 --> 00:16:53.051
das ist nichts, was man dem Entwickler sagen kann, dass er das selber tun kann.

00:16:53.251 --> 00:16:56.611
Es ist gut, dass es dann eine sehr, sehr robuste Library gibt, die auch,

00:16:59.091 --> 00:17:05.311
wirklich alle absurden Unterarten von Angriffen standhalten kann.

00:17:06.351 --> 00:17:09.431
Aber es ist halt auch irgendwie schade, dass es nur eine Bibliothek gibt,

00:17:09.511 --> 00:17:12.491
von der man mit voller Gewissenheit sagen kann, okay, die machen es richtig.

00:17:12.871 --> 00:17:16.631
Wenn man halt weiß, dass es ein beliebter Use-Case ist und dass es irgendwas

00:17:16.631 --> 00:17:17.971
Wichtiges für die Web-Plattform ist.

00:17:18.591 --> 00:17:23.031
Dementsprechend halt den Ansatz zu überlegen, wie sieht ein Sanitizer aus. Und.

00:17:24.329 --> 00:17:28.569
Vielleicht reden wir nochmal ein bisschen über Motivation und Security und ein

00:17:28.569 --> 00:17:31.989
bisschen weiter weg vom Code an sich.

00:17:32.469 --> 00:17:36.309
Cross-Site-Scripting ist halt ein Problem. Ich habe gesagt, den Begriff gibt es seit den 90ern.

00:17:36.589 --> 00:17:39.809
Ist halt auch ein Problem seit den 90ern. Also es ist nicht so,

00:17:39.869 --> 00:17:42.789
als dass man sagen kann, dass es jetzt weitestgehend irgendwie gelöst.

00:17:43.469 --> 00:17:46.809
Obwohl ich ja gesagt habe, es gibt gute Libraries und ein Framework mit M-Desup,

00:17:47.009 --> 00:17:52.629
das ist seit über zehn Jahren eine von den topmost berichteten,

00:17:52.749 --> 00:17:54.949
meistgefundenen Schwachstellen in Software überhaupt.

00:17:56.129 --> 00:18:00.149
Also immer in den Top drei gewesen seit über zehn Jahren, wenn es darum geht,

00:18:00.329 --> 00:18:04.269
dass Leute messen oder zählen, was für Schwachstellen öffentlich bekannt gegeben werden.

00:18:04.829 --> 00:18:09.749
Das heißt, es ist unheimlich trivial zu sagen, oh, ich kriege hier einen HTML-String,

00:18:10.289 --> 00:18:13.009
ich bin, sehe mein Document ein, dann mache ich halt irgendwie in HTML,

00:18:13.309 --> 00:18:16.629
out HTML, insert, adjacent HTML, was es noch so für Funktionen gibt.

00:18:17.189 --> 00:18:20.629
Und es ist halt unheimlich leicht, sich die Schwachstelle einzutreten,

00:18:20.709 --> 00:18:22.189
weil es halt keinen sicheren Default gibt.

00:18:22.549 --> 00:18:25.329
Wenn man sagt, ich will HTML bei mir in die Seite einbinden,

00:18:25.769 --> 00:18:28.969
dann macht man das im Zweifelsfall, zumindest wenn man die Plattformen,

00:18:29.129 --> 00:18:31.449
die Web-Plattform-Methoden benutzt, dann ist es unsicher.

00:18:31.949 --> 00:18:35.309
Das heißt, man braucht immer eine Library, man braucht immer einen Sanitizer,

00:18:35.469 --> 00:18:37.609
ein Framework, sonst ist es per Default unsicher.

00:18:38.129 --> 00:18:41.389
Und das ist halt einfach kein zufriedenstellender Zustand.

00:18:41.589 --> 00:18:45.309
Und es ist jetzt nicht so, als hätten 10 Jahre lang oder vielleicht 30 Jahre

00:18:45.309 --> 00:18:48.229
lang, je nachdem, wo man anfängt, über XSS ernsthaft nachzudenken,

00:18:48.989 --> 00:18:51.329
Browser-Entwickler die Däumchen gedreht, sondern es gibt halt viele Sachen,

00:18:51.369 --> 00:18:56.249
die versucht wurden und viele Sachen, die von einer Security-Perspektive auch extrem robust sind.

00:18:56.449 --> 00:18:59.849
Also einmal genannt wäre vielleicht Content-Security-Policy,

00:19:00.149 --> 00:19:02.949
da würde ich dann auch wieder auf die Revision vom letzten Mal verweisen,

00:19:03.409 --> 00:19:05.049
was das relativ gut macht.

00:19:06.342 --> 00:19:11.402
Oder Trusted Types vielleicht. Aber das Problem ist halt, dass die halt nicht

00:19:11.402 --> 00:19:12.842
so richtig viel Adoption gefunden haben.

00:19:12.962 --> 00:19:16.882
Also es ist eigentlich wieder der Versuch, etwas zu bauen, was den Entwicklern

00:19:16.882 --> 00:19:19.642
oder den Frameworks mehr hilft als das, was es bereits gibt.

00:19:20.222 --> 00:19:24.362
Content Security Policy wird super selten eingesetzt.

00:19:24.442 --> 00:19:30.122
Es gibt ja diesen HTTP-AMANAC, wo Leute Browser-Telemetry und andere Daten benutzen,

00:19:30.142 --> 00:19:33.102
um zu studieren, wie entwickelt sich das Web, was machen die Entwickler,

00:19:33.182 --> 00:19:38.082
was wollen die Entwickler, was sind Trends, welche neuen APIs werden angenommen und so weiter.

00:19:38.442 --> 00:19:42.882
Und da wird einfach gesehen, dass super geringe Prozentzahlen,

00:19:42.882 --> 00:19:46.402
ich habe es leider nicht genau im Kopf, von Webseiten überhaupt sowas wie CSP

00:19:46.402 --> 00:19:49.902
einsetzen. und die, die es einsetzen, die benutzen es für andere Kontrollen.

00:19:49.982 --> 00:19:52.902
Es hat andere Kontrollmechanismen, auf die ich jetzt auch lieber nicht eingehen würde.

00:19:53.142 --> 00:19:57.922
Aber 90 Prozent von den CSPs, die es gibt, die machen gar nichts gegen Cross-Side Scripting.

00:19:58.622 --> 00:20:01.562
Also es ist einfach nicht so beliebt, wie man denkt.

00:20:03.062 --> 00:20:07.502
Und das war unsere Motivation zu überlegen, was wäre irgendwie noch ein fehlendes Puzzlestück.

00:20:08.942 --> 00:20:12.602
Was spannend ist, was ich glaube, ich auch ein bisschen erklärt habe,

00:20:12.642 --> 00:20:17.742
wo ich aber gerne noch ein bisschen zu aushole, was 2020 von Google vorgeschlagen

00:20:17.742 --> 00:20:20.322
und auch geschippt wurde, Trusted Types.

00:20:21.482 --> 00:20:25.082
Das greift die Sache auch nochmal von einer spannenderen Perspektive an,

00:20:25.122 --> 00:20:27.662
ist auch eher was für Single-Page-Applications.

00:20:28.382 --> 00:20:30.762
Und da geht es im Grunde genommen,

00:20:31.900 --> 00:20:36.480
Darum, dass der Browser dir über bestimmte Kontrollmechanismen,

00:20:36.580 --> 00:20:42.460
über einen Header dir sagt, HTML ist ab jetzt nicht mehr vertrauenswürdig.

00:20:42.660 --> 00:20:45.020
Wie ich gesagt habe, mit Bordmitteln ist es ja immer unsicher.

00:20:45.180 --> 00:20:48.980
Wenn ich in einer HTML gleich irgendwas mache, dann ist irgendwas im Zweifelsfall

00:20:48.980 --> 00:20:53.160
böse genug, dass es zu einem Security-Bug führt. Und Trusted Type sagt halt,

00:20:53.520 --> 00:20:54.680
das darf nicht mehr passieren.

00:20:54.860 --> 00:20:57.320
Es gibt einfach eine Exception oder ein Check.

00:20:58.540 --> 00:21:02.780
Exception in dem einfachen Fall, ein Check in einem komplizierteren Fall,

00:21:02.860 --> 00:21:06.480
dass ich mir so ein bisschen Code schreibe und sage, immer wenn HTML kommt,

00:21:06.640 --> 00:21:08.060
das nicht vertrauenswürdig ist,

00:21:08.460 --> 00:21:12.500
dann gibt es eine Funktion, die ich programmiert habe, die aus diesem unvertrauenswürdigen

00:21:12.500 --> 00:21:16.180
HTML einen sogenannten Trusted Type, daher der Name kommt,

00:21:16.600 --> 00:21:20.040
das quasi Untrusted HTML zu Trusted HTML wird.

00:21:20.040 --> 00:21:23.300
Und das Trusted-HTML-Objekt, das darf in mein Document run.

00:21:23.780 --> 00:21:26.720
Das ist erlaubt, da kann ich dann inner-HTML machen, mit den anderen nicht.

00:21:26.960 --> 00:21:31.300
Sodass man eine Kontrollfunktion hat von wegen, alles potenziell bösartige HTML

00:21:31.300 --> 00:21:35.680
habe ich gesehen, indem ich das durch diese Trusted-Type-Policy,

00:21:35.780 --> 00:21:38.900
durch dieses bisschen JavaScript als Kontrollfunktion durchgeschleust habe.

00:21:39.340 --> 00:21:46.540
Du setzt einen Header, der das aktiviert und dann sobald man eben inner-HTML

00:21:46.540 --> 00:21:48.980
oder eben die anderen Möglichkeiten verwendet,

00:21:48.980 --> 00:21:54.700
Und mit einem unbehandelten HTML-Snippet,

00:21:54.740 --> 00:21:58.780
dann verweigern die die Zusammenarbeit und werfen einen Error wahrscheinlich.

00:21:59.460 --> 00:22:02.380
Genau, im einfachsten Fall gibt es einen Error, was natürlich irgendwie doof

00:22:02.380 --> 00:22:03.860
ist. Man will ja nicht eine kaputte Webseite.

00:22:04.000 --> 00:22:07.600
Meistens wird Security ja leider nachträglich irgendwie bedacht.

00:22:07.760 --> 00:22:09.080
Und dann hat man ja schon eine Menge Code.

00:22:09.340 --> 00:22:13.140
Es gibt auch eine sogenannte Default-Policy, die man schreiben kann in Trusted Types.

00:22:13.200 --> 00:22:16.840
Dann sagt man im Endeffekt, wenn es keinen Trusted Type gibt,

00:22:16.940 --> 00:22:18.600
dann ruft folgenden Callback auf.

00:22:18.980 --> 00:22:21.620
Und der sorgt dann dafür, dass es was Trustworthy gibt.

00:22:22.120 --> 00:22:26.760
Okay, das heißt, da könnte man zum Beispiel DOM Purify respektive in Zukunft

00:22:26.760 --> 00:22:29.100
vielleicht dann auch die Sanitizer-API.

00:22:29.910 --> 00:22:33.990
Ganz genau. Heranziehen und dieses quasi sagen so, hey, wenn du so ein HTML

00:22:33.990 --> 00:22:38.830
bekommst, dann, und das ist noch nicht trusted, dann schick das einmal da durch

00:22:38.830 --> 00:22:42.430
und was dann hinten rauskommt, das ist dann trusted und okay.

00:22:43.330 --> 00:22:46.050
Ganz genau. Und das war auch so ein bisschen meine Motivation,

00:22:46.130 --> 00:22:48.490
dass ich gesehen habe, okay, es gibt jetzt diesen Kontrollmechanismus,

00:22:48.670 --> 00:22:53.430
aber was der eigentlich macht, ist, der wirft das Problem zurück an den Entwickler.

00:22:53.430 --> 00:22:55.850
Okay, du kannst es jetzt kontrollieren, aber was machst du?

00:22:56.270 --> 00:22:59.330
Und für Google funktioniert es extrem

00:22:59.330 --> 00:23:02.590
gut und für viele andere große Organisationsfunktionen ist es auch gut.

00:23:02.990 --> 00:23:05.210
Trusted Type ist auch nicht bei allen Entwicklern angekommen.

00:23:05.470 --> 00:23:11.730
Es kommt aber wirklich gut an bei großen Webplattformen, Webseiten,

00:23:11.730 --> 00:23:14.970
Social Media und so weiter, die ein separates Security-Team haben.

00:23:15.070 --> 00:23:17.290
Weil die sagen halt, programmiert, was ihr wollt.

00:23:17.510 --> 00:23:20.510
Solange ihr Trusted Types habt und wir die Policy stellen,

00:23:21.340 --> 00:23:24.040
Könnt ihr alles tun, weil die Policy wird vom Security-Team geschrieben.

00:23:24.400 --> 00:23:27.480
Leider kann sich aber nicht jeder Frontend-Entwickler ein Security-Team leisten.

00:23:27.760 --> 00:23:30.880
Das ist halt leider auch eine bittere Realität.

00:23:31.100 --> 00:23:34.440
Und Sanitizer sind halt schwer zu bauen. Also wenn man naiv sagt,

00:23:34.980 --> 00:23:38.500
so einfach ist es, so kompliziert ist es nicht, ich iteriere jetzt mal über

00:23:38.500 --> 00:23:43.600
ein bisschen HTML, werfe das in irgendein Dokument, das nicht aktiv ist und

00:23:43.600 --> 00:23:46.260
mache dann meine While-Schleife und gucke, welche Elemente erlaubt sind.

00:23:46.260 --> 00:23:49.560
Gibt es erstaunlich viele Fallstricke, auf die ich vielleicht jetzt auch lieber

00:23:49.560 --> 00:23:54.000
nicht im Detail alle eingehe, sodass für mich persönlich relativ klar war,

00:23:54.060 --> 00:23:55.780
ein fehlendes Puzzlestück ist eine Sanitizer API.

00:23:56.480 --> 00:23:59.820
Und ich glaube, dass es halt ganz gut mit Trusted Types zusammenspielen kann,

00:23:59.940 --> 00:24:02.260
aber auch ohne seine Berechtigung haben kann.

00:24:03.020 --> 00:24:07.040
Und genau, das ist so ein bisschen die Origin-Story und ein bisschen die Motivation.

00:24:08.740 --> 00:24:16.480
Und diese Sanitizer API, die backt in die Browser ja ein, was Dom Purify bisher getan. hat.

00:24:16.660 --> 00:24:20.860
Manchmal passiert das ja, dass Browser-Vendoren sowas machen,

00:24:20.980 --> 00:24:25.940
also dieses Paving-the-Cow-Path, so wie Document Query, Selector und Selector

00:24:25.940 --> 00:24:30.180
All irgendwie jQuery inspiriert waren und den Weg da reingefunden haben.

00:24:32.200 --> 00:24:36.600
Passiert das hier auch? Aber was würde denn dagegen sprechen,

00:24:37.200 --> 00:24:44.480
DOM Purify weiterhin zu nutzen, dass ja so die einzige Library ist, die das vernünftig tut?

00:24:44.740 --> 00:24:50.240
Also die Awareness ist ja, muss ja trotzdem für beides gegeben sein bei den entwickelnden.

00:24:50.440 --> 00:24:56.080
Also wer sich darüber keine Gedanken macht, für den ist das vielleicht so ein Unknown-Unknown.

00:24:56.220 --> 00:25:01.640
Das heißt, man weiß weder, dass man DOM Purify einsetzen müsste an einer gewissen

00:25:01.640 --> 00:25:07.000
Stelle und man weiß genauso wenig, dass man aber auch alternativ die Sanitizer-API einsetzen könnte.

00:25:07.620 --> 00:25:11.200
Was spricht dagegen, einfach Wertes weiter zu benutzen? Ja.

00:25:12.330 --> 00:25:17.130
Und grundsätzlich spricht nichts dagegen. Was Security angeht,

00:25:17.190 --> 00:25:19.290
ist DOM Purify ziemlich okay.

00:25:19.670 --> 00:25:21.990
Es gibt ein paar Sachen, auf die kann man jetzt eingehen.

00:25:22.630 --> 00:25:27.490
Natürlich gibt es noch andere Übererwägungen von wegen DOM Purify ist halt eine

00:25:27.490 --> 00:25:30.370
Third-Party-Library, muss man die immer mit sich herumschleppen.

00:25:30.550 --> 00:25:34.310
Es ist nicht schöner, sich auf den Browser zu verlassen, dass es irgendwie auch zum Browser passt.

00:25:35.015 --> 00:25:44.375
Und eine Sache, die wir relativ spät gemerkt haben, leider im Rahmen der Sanitizer-API-Standardisierung

00:25:44.375 --> 00:25:47.995
und weswegen das auch, wenn wir das letzte Mal vor fünf Jahren gesprochen haben,

00:25:48.335 --> 00:25:49.495
weswegen es länger gedauert hat,

00:25:49.855 --> 00:25:55.815
ist, dass es nicht so richtig gut zu den Semantiken passt, wie andere Teile

00:25:55.815 --> 00:25:59.915
im Web standardisiert sind und wie wirklich der Cow-Path aussieht.

00:25:59.915 --> 00:26:04.555
Also was DOM Purify anbietet, ist im Endeffekt eine Sanitize-Funktion.

00:26:04.775 --> 00:26:09.095
Ich werfe böses HTML raus und kriege gutes HTML rein und das kann ich dann beliebig benutzen.

00:26:09.675 --> 00:26:12.775
In beidem Fall ist es ein einfacher JavaScript-String und damit können Entwickler

00:26:12.775 --> 00:26:17.055
umgehen und das String kann man sich ganz gut angucken und debuggen und printen und so weiter.

00:26:17.715 --> 00:26:21.795
Was wir aber gemerkt haben, ist relativ spannend und hat tatsächlich auch einen

00:26:21.795 --> 00:26:23.235
Grund, der aus der Security kommt.

00:26:23.355 --> 00:26:27.735
Aber ich hole mal kurz aus, was DOM Purify macht im Endeffekt.

00:26:27.935 --> 00:26:30.715
Es nimmt ja ein String an als Argument und sonst nicht viel mehr.

00:26:30.855 --> 00:26:32.455
Vielleicht noch eine bestimmte Konfiguration.

00:26:32.695 --> 00:26:35.695
Folgende Elemente möchte ich noch erlauben, folgende nicht. Gehen wir einfach

00:26:35.695 --> 00:26:37.535
davon aus, irgendein sicherer Default.

00:26:37.675 --> 00:26:42.555
Es nimmt einen String an und dieser String muss dann ja bereinigt werden.

00:26:42.555 --> 00:26:46.715
Das kann so eine Library oder kann man grundsätzlich bei HTML nicht,

00:26:46.815 --> 00:26:51.035
indem man die Zeichenkette abläuft und nach Substrings sucht oder so.

00:26:51.255 --> 00:26:55.915
Der vernünftige Weg ist zu sagen, das ist HTML, ich werfe das durch einen HTML-Parser

00:26:55.915 --> 00:26:57.795
und kriege dann eine Art Baumstruktur.

00:26:58.915 --> 00:27:04.095
Das ist in so einem Document-Fragment gemacht, das quasi einfach isoliert im

00:27:04.095 --> 00:27:06.335
Speicher liegt und nicht eingehängt ist im DOM.

00:27:06.835 --> 00:27:10.455
Und da kann man dann alles explodieren. Mit einem Template-Element könnte man

00:27:10.455 --> 00:27:12.755
das machen oder es gibt die DOM-Parser-API.

00:27:14.315 --> 00:27:19.135
Verschiedene Varianten. Und wenn man dann dieses Fragment hat,

00:27:19.215 --> 00:27:22.515
dann kann man das ablaufen und sagen, okay, ich mache eine Vorschleife für jedes

00:27:22.515 --> 00:27:25.255
Element und dann mache ich für jedes Element nochmal eine Vorschleife für jedes

00:27:25.255 --> 00:27:28.555
Attribut und dann gucke ich mir an, was es erlaubt, was es nicht erlaubt.

00:27:31.099 --> 00:27:35.619
Und dann wird dieses ganze HTML bereinigt, diese ganze Baum bereinigt,

00:27:35.719 --> 00:27:37.279
bis der ganz fein und sauber ist.

00:27:37.439 --> 00:27:41.339
Und dann wird der wieder serialisiert, also zurückverwandelt in einen String

00:27:41.339 --> 00:27:42.519
und dann zurückgegeben.

00:27:43.079 --> 00:27:50.059
So, der Cowpath ist aber, dass Leute machen div.innerHTML gleich, drum purify.sanitize.

00:27:50.379 --> 00:27:54.679
Die zweite Frage ist, was macht denn innerHTML gleich?

00:27:55.139 --> 00:28:01.059
Es nimmt einen String, pares das in DocumentFragment und hängt es dann ins aktuelle Dokument ein.

00:28:01.279 --> 00:28:06.579
Das heißt, was wir im Ganzen machen, ist, wir parsen, wir durchsuchen einen

00:28:06.579 --> 00:28:10.639
Baum, dann serialisieren wir das wieder in einen String, dann geht es an Inhalte

00:28:10.639 --> 00:28:12.039
mit, dann wird es erneut geparsed.

00:28:12.259 --> 00:28:15.919
Das kommt einem ja intuitiv schon nicht so ganz elegant vor,

00:28:16.019 --> 00:28:19.319
wenn man das zweimal machen muss, wenn wir wissen, dass die Leute das hier im

00:28:19.319 --> 00:28:20.259
Endeffekt einfügen wollen.

00:28:20.679 --> 00:28:24.219
Das ist der erste Grund. Und der zweite Grund, der ist ein bisschen subtiler

00:28:24.219 --> 00:28:29.359
und auch ein bisschen trickreicher, das Parsing in einer Library wie DOM Purify

00:28:29.359 --> 00:28:33.219
und im Browser bei innerHTML ist anders.

00:28:33.439 --> 00:28:35.959
Es kann nie genau gleich sein.

00:28:36.719 --> 00:28:43.719
Und ich finde ein ganz gutes Beispiel, was das schön motiviert ist, DOM Purify nimmt halt im,

00:28:44.324 --> 00:28:48.904
normalen Zustand nichts anderes ein als Input, diesen String,

00:28:49.024 --> 00:28:49.904
von dem wir gerade gesprochen haben.

00:28:50.304 --> 00:28:54.284
Das heißt, es weiß gar nicht, in welchem Kontext das HTML gerade irgendwie aufgefasst werden soll.

00:28:54.484 --> 00:28:57.384
Er stellt halt ein neues Dokument und sagt, okay, und dann hole ich aus dem

00:28:57.384 --> 00:29:02.204
Dokument den Body raus und das kommt halt ungefähr, das ist dann halt HTML.

00:29:03.184 --> 00:29:10.764
Wie aber vermutlich die meisten Zuhörer wissen, HTML Parsing in innerHTML ist

00:29:10.764 --> 00:29:14.244
sehr abhängig davon, wo ich innerHTML drauf Aufrufe.

00:29:14.444 --> 00:29:19.384
Also TableElement.inHTML erlaubt zum Beispiel trivial Tabellen,

00:29:19.464 --> 00:29:22.304
Zeilen und Zellen und so weiter. Das tut ein Diff nicht.

00:29:22.664 --> 00:29:27.624
Und es gibt noch viele, viele andere Beispiele, dass innerHTML subtil anders

00:29:27.624 --> 00:29:29.904
ist, je nachdem, welches Element man erlaubt.

00:29:30.224 --> 00:29:34.324
Eine OptionSelect, die gibt es auch irgendwie nur im Paar und nicht einzeln

00:29:34.324 --> 00:29:36.104
und so weiter und so weiter.

00:29:36.304 --> 00:29:40.604
Und immer, wenn es subtile Unterschiede gibt in der Interpretation von etwas,

00:29:40.824 --> 00:29:43.484
das irgendwie wie für Security gecheckt werden soll.

00:29:43.824 --> 00:29:46.984
Da leuchten bei dem Security-Ingenieur auf jeden Fall die Arme lahmen Glocken.

00:29:47.044 --> 00:29:50.064
Da wird gesagt, okay, wir machen zweimal eine Entscheidung und sagen,

00:29:50.304 --> 00:29:54.064
ist es jetzt akzeptabel oder nicht? Wir gucken uns das aber unterschiedlich an.

00:29:56.054 --> 00:29:59.074
Und das hat dazu geführt, dass wir gesagt haben, wir wollen eigentlich keine

00:29:59.074 --> 00:30:01.914
Sanitizer-API bauen, die genauso aussieht wie Dom-Pure-File.

00:30:02.074 --> 00:30:04.794
Wir wollen halt nicht String-Input, String-Output.

00:30:04.954 --> 00:30:09.994
Und das ist auch einer der Gründe, von mehreren Gründen, warum wir das nicht

00:30:09.994 --> 00:30:14.154
sofort shippen konnten und warum das nicht vor Jahren schon in Chrome und anderen

00:30:14.154 --> 00:30:15.134
Browsern zur Verhöhung steht.

00:30:15.354 --> 00:30:19.934
Sondern warum es halt jetzt erst Februar 2026 in Chrome und Firefox landet.

00:30:21.634 --> 00:30:25.314
Und die Lösung, die wir gefunden haben, Ja, ich wollte sagen,

00:30:25.454 --> 00:30:26.834
ich kann mich erinnern an einen

00:30:26.834 --> 00:30:30.114
Zeitpunkt, also weil ich das auch immer mitverfolgt habe so ein bisschen,

00:30:30.754 --> 00:30:37.914
wo man, glaube ich, das also angegeben hat, in welches Element dann dieser String

00:30:37.914 --> 00:30:39.994
später reingesteckt wird.

00:30:40.234 --> 00:30:42.694
Also ich glaube, so eine Zwischenstufe gab es auf jeden Fall mal.

00:30:43.114 --> 00:30:46.374
Genau, es gab eine Zwischenstufe, die hieß, glaube ich, Sanitize for und dann

00:30:46.374 --> 00:30:49.194
hast du einen Kontext übergeben und hast gesagt, das soll jetzt für eine Tabelle

00:30:49.194 --> 00:30:50.234
zum Beispiel genutzt werden.

00:30:50.434 --> 00:30:54.434
Ja, stimmt, das war es. Und dann hast du einen tabellenspezifischen Sanitizer gehabt.

00:30:55.374 --> 00:30:58.354
Ich habe dir wahrscheinlich gesagt, das ist irgendwie auch doof,

00:30:58.534 --> 00:31:03.114
weil irgendwie verliert sich ja die Spur, wofür man was gesanitized hat und

00:31:03.114 --> 00:31:05.754
dann steckt man es doch wieder ins Falsche rein. Genau.

00:31:06.034 --> 00:31:08.514
Die einzige Variante, wie man dann sicher sein könnte, dass das,

00:31:08.594 --> 00:31:12.074
was für eine Tabelle sanitized wurde, auch wirklich nur in der Tabelle landen

00:31:12.074 --> 00:31:15.874
könnte, wäre ja, wenn du starke Typen überprüfen musst, was zu JavaScript nun

00:31:15.874 --> 00:31:16.774
einmal nicht dazu gehört.

00:31:16.954 --> 00:31:20.934
Und zweitens kann ich mir nicht gut vorstellen, dass es ins Web passt,

00:31:21.034 --> 00:31:24.234
geschweige den Leuten gefällt, wenn es dann HTML sanitized Typ gibt,

00:31:24.234 --> 00:31:26.594
wie jedes Kontextelement, das HTML zu überprüfen steht.

00:31:27.094 --> 00:31:29.374
Das ist ja absurd. Und...

00:31:31.784 --> 00:31:36.604
Ich war lange grummelig und wir haben überlegt und ich muss dazu sagen,

00:31:36.684 --> 00:31:39.384
ich sage sehr, sehr oft ich, es war definitiv nicht nur ich.

00:31:39.564 --> 00:31:43.704
In einer großen Gruppe treffen wir uns seit fünf Jahren, alle zwei Wochen und

00:31:43.704 --> 00:31:46.644
es haben viele Leute beigesteuert, vielleicht hätte ich damit sogar früher anfangen sollen.

00:31:47.004 --> 00:31:50.364
Daniel Vogelheim von Google, Mike West von Google hat ursprünglich auch mitgemacht.

00:31:50.724 --> 00:31:53.764
Anna van Kesteren, der, als er angefangen hat, noch bei Mozilla arbeitet,

00:31:53.904 --> 00:31:56.424
mittlerweile bei Safari, für Webstandards verantwortlich ist.

00:31:56.424 --> 00:32:01.244
Tom Schuster bei mir aus dem Team, Simon Peters, der ursprünglich auch nicht

00:32:01.244 --> 00:32:05.204
bei Mozilla war, mittlerweile bei Mozilla ist und herausgeworden das HTML-Easternetz ist.

00:32:05.604 --> 00:32:10.744
Viele Leute haben da sehr viel Hirtschmalz drauf investiert und irgendwann sagte

00:32:10.744 --> 00:32:13.944
einer, ja, aber warum machen wir da nicht einfach ein Safe-Inner-HTML?

00:32:15.121 --> 00:32:18.701
Und werfen da einfach das Böse rein und der Browser macht den Rest und macht

00:32:18.701 --> 00:32:21.981
Insertion und den ganzen Kram komplett.

00:32:22.601 --> 00:32:25.921
Und für einen Moment dachte ich so, ja, aber es ist das, was Entwickler wollen.

00:32:26.121 --> 00:32:28.501
Aber es ist halt im Endeffekt, es ist halt genau der Cow-Path.

00:32:28.641 --> 00:32:33.101
Wir sagen, was wir sehen, ist ständig innerHTML gleich donpureify, sanitize und dann.

00:32:34.321 --> 00:32:37.221
Und warum dann nicht alles genau

00:32:37.221 --> 00:32:42.041
zusammenfassen? Und deswegen ist die Sanitizer-API einfach nur .zhtml.

00:32:42.681 --> 00:32:46.901
Das heißt, du hast, wo du vorher div.innerHTML gleich hattest,

00:32:47.201 --> 00:32:50.161
kannst du jetzt sagen div.setHTML, und das ist eine Funktion,

00:32:50.281 --> 00:32:54.241
also Klammer auf, böser Input, Klammer zu, und der Browser macht den Rest.

00:32:54.441 --> 00:32:58.741
Und dann muss der Browser nur einmal parsen, nur einmal den Baum ablaufen und dann einfügen.

00:32:59.161 --> 00:33:03.781
Und natürlich kann man das beliebig konfigurieren, und es gibt natürlich weitere

00:33:03.781 --> 00:33:06.021
Parameter, die man an setHTML hinzufügen kann.

00:33:06.141 --> 00:33:11.021
Aber im allereinfachsten Fall kann man sagen, überall, wo jetzt innerHTML steht,

00:33:12.041 --> 00:33:15.761
Werfe ich raus, ersetze ich durch SetHTML und dann ist meine Web-Anwendung auf

00:33:15.761 --> 00:33:17.881
jeden Fall gegen diesen Angriff gesichert.

00:33:18.401 --> 00:33:24.881
Wobei das eine DOM-Element-Methode in dem Fall ist und nicht so ein Getter-Setter-Konstrukt.

00:33:26.141 --> 00:33:30.141
Genau. Das ist ja gerade gesagt, weil man eben auch die Möglichkeit haben muss,

00:33:30.901 --> 00:33:33.161
ein Options-Objekt zu übergeben oder sowas.

00:33:33.281 --> 00:33:35.421
Das geht ja einfach nicht, wenn man nur assigns.

00:33:35.761 --> 00:33:37.901
Das funktioniert ja nicht. Ganz genau.

00:33:38.341 --> 00:33:40.861
Ganz genau. Es hängt am Element-Prototype. Also man kann wirklich,

00:33:40.981 --> 00:33:43.621
wenn man mit Create noch etwas erstellt hat oder eine Referenz hat,

00:33:43.701 --> 00:33:46.261
die man über einen Query-Selector oder sonst was bekommt, dann kann man darauf

00:33:46.261 --> 00:33:47.761
direkt zHTML ausführen.

00:33:48.041 --> 00:33:52.821
Und eben, weil es verschiedene Optionen geben muss, ist es für die,

00:33:52.941 --> 00:33:57.401
die jetzt gerade den Podcast schon gestoppt haben und die jetzt weiterhören, nachdem die,

00:33:58.041 --> 00:34:03.361
erfolglos einfach Search-and-Replace gemacht haben, in der HTML gegen zHTML.

00:34:03.941 --> 00:34:05.461
Genau, und das dann nicht funktioniert

00:34:05.461 --> 00:34:11.741
hat, weil man eben dann doch die Parameter-Klammern dann braucht. Genau.

00:34:14.185 --> 00:34:16.965
Aber da gibt es ja auch Mittel und Wege. Manchmal sprechen wir darüber,

00:34:17.165 --> 00:34:22.985
dass wir hier so Dirty-Tricks machen, wie dass wir native DOM-Methoden patchen.

00:34:24.225 --> 00:34:27.865
Das kann man ja dann auch machen, wenn das das eigene Projekt ist,

00:34:27.925 --> 00:34:32.185
wenn man alles im Griff hat. Wenn man Dirty Tricks möchte, dann befürworte ich

00:34:32.185 --> 00:34:33.485
das sehr und dann soll man das tun.

00:34:35.585 --> 00:34:41.845
Aber natürlich, alles hat seine Trade-Offs. Ich habe ja, wie wir vorhin festgestellt

00:34:41.845 --> 00:34:46.925
haben, war ich ja schon ein paar Mal hier und habe ja mal was über AST und Linter

00:34:46.925 --> 00:34:47.885
und so weiter gesprochen.

00:34:47.885 --> 00:34:51.065
Ich glaube, man könnte sich auch relativ trivial vorstellen,

00:34:51.365 --> 00:34:54.225
einen Linter zu schreiben oder ein Plugin für ESLint oder sonst was,

00:34:54.405 --> 00:34:59.685
der tatsächlich nichts anderes macht, als innerHTML durch setHTML als Function Callout zu ersetzen.

00:35:01.545 --> 00:35:04.665
Ich habe mal in Weihnachtsferien tatsächlich so einen kleinen Prototypen geschrieben.

00:35:04.865 --> 00:35:06.285
Der funktioniert nicht so richtig gut.

00:35:06.525 --> 00:35:09.525
Es gibt so ein paar Trade-offs, wo ich mir unklar bin, wollen die Leute wirklich

00:35:09.525 --> 00:35:11.125
nur eins durch das andere ersetzen.

00:35:11.325 --> 00:35:16.025
Aber was ist, wenn die setHTML funktioniert gut für innerHTML?

00:35:16.025 --> 00:35:19.625
Aber was ist, wenn die Leute Auto-HTML benutzen oder Document-Write-Code bewahre

00:35:19.625 --> 00:35:21.685
oder irgendwas ganz anderes.

00:35:23.785 --> 00:35:27.225
Was ist dann wirklich der Ersatz? Wollen die Leute dann ganz sicher und hässlichen

00:35:27.225 --> 00:35:29.085
Code oder wirklich nur das eine und das andere ersetzen?

00:35:30.265 --> 00:35:31.145
Dementsprechend habe ich es nicht

00:35:31.145 --> 00:35:34.965
wirklich weiterverfolgt, weil ich nicht sicher war, was Leute wollen.

00:35:35.885 --> 00:35:41.285
Von daher nehmen wir jetzt den Podcast einfach zum Anlass. Wenn Leute eine Meinung

00:35:41.285 --> 00:35:43.185
haben, ich bin super gespannt.

00:35:43.625 --> 00:35:48.585
E-Mail an freddy-at-mozilla.com Wollt ihr sowas haben? Wie würde das für euch aussehen?

00:35:49.245 --> 00:35:52.205
Schreibt mir die E-Mail, aber dann seid ihr euch darauf gefasst,

00:35:52.265 --> 00:35:53.945
dass ich ganz viele Folgefragen haben werde.

00:35:54.845 --> 00:35:56.725
Dann hätte ich tatsächlich Lust, das nochmal zu bauen.

00:35:59.557 --> 00:36:05.937
Ich habe letztens bei dem Projekt, in dem ich bin, habe ich auch hier so ein

00:36:05.937 --> 00:36:14.217
Patching durchgeführt für, das war Insert Before, habe ich getauscht eben mit Move Before.

00:36:15.857 --> 00:36:22.717
Ja. Um das sozusagen überall standardmäßig, also genau, habe ich dann Prototype-Patching gemacht.

00:36:22.817 --> 00:36:24.877
Da gibt es dann bestimmte Regeln. Ich mache das nicht immer,

00:36:25.017 --> 00:36:29.617
aber im Grunde, sobald auch irgendeine Third-Party-Library, die halt Erzeug

00:36:29.617 --> 00:36:34.437
erstellt wurde, bevor es eben Move-Before gab, eben Insert-Before macht,

00:36:35.497 --> 00:36:40.697
dass der das dann sozusagen umwandelt im Hintergrund in Move-Before.

00:36:41.797 --> 00:36:47.317
Ja, das ist cool. Ja, sowas kann ich mir da eigentlich auch für manche Use-Cases vorstellen.

00:36:47.597 --> 00:36:52.337
So einfach, weil man da auch nicht immer weiß, welche Third-Party macht ein

00:36:52.337 --> 00:36:56.717
innerer HTML, die auch noch nichts von ZHTML wusste oder so.

00:36:57.857 --> 00:37:01.097
Das stimmt, das stimmt. Das ist natürlich eine gute Methode,

00:37:01.237 --> 00:37:04.237
um da die vollständige Kontrolle zu haben.

00:37:05.337 --> 00:37:10.297
Mit dann aber auch der von Verantwortung dafür, falls dann Dinge unerwartet anders sind.

00:37:10.717 --> 00:37:13.577
Ja, absolut. Ja.

00:37:15.086 --> 00:37:20.646
Die Benutzung der Sanitizer-API, also ich mache, es funktioniert so,

00:37:20.746 --> 00:37:29.786
dass ich tatsächlich nur setHTML mache und dann habe ich quasi eine Default-Konfiguration.

00:37:30.766 --> 00:37:37.586
Ist die denn auch spezifiziert oder wechselt die von Browser zu Browser? Nee, ist gespeckt.

00:37:38.046 --> 00:37:40.986
Die ist spezifiziert. Wenn ihr wechseln würdet von Browser zu Browser,

00:37:41.086 --> 00:37:44.446
dann wäre die API ja nicht wirklich benutzbar.

00:37:44.706 --> 00:37:46.826
Also dann wüsste man ja nicht, wie die Webseite sich verhält.

00:37:46.966 --> 00:37:48.186
Das wollen wir halt ganz genau nicht.

00:37:48.826 --> 00:37:53.126
Nee, die ist spezifiziert und die ist, das muss man vielleicht dazu sagen, relativ streng.

00:37:53.346 --> 00:37:57.446
Die nimmt nicht nur Cross-Site-Scripting weg, sondern die guckt auch auf andere

00:37:57.446 --> 00:38:00.006
Angriffe, auf die wir gerne ein bisschen eingehen können.

00:38:00.506 --> 00:38:03.806
Die ist aber konfigurierbar zu einem gewissen Grad.

00:38:06.566 --> 00:38:13.346
Die Verabredung, die wir getroffen haben, ist, setHTML lässt sich niemals so,

00:38:13.866 --> 00:38:16.326
konfigurieren, dass es dann am Ende Crosshead-Scripting gibt.

00:38:16.686 --> 00:38:18.686
Das war so unser Versprechen zueinander.

00:38:19.146 --> 00:38:22.346
Das passt dann halt auch ganz gut zu Trusted Types zum Beispiel,

00:38:22.486 --> 00:38:27.726
weil setHTML ist nicht durch Trusted Types kontrolliert, weil wir sagen, es ist immer sicher.

00:38:28.146 --> 00:38:31.246
XSS kannst du mit setHTML nicht kriegen.

00:38:31.406 --> 00:38:34.766
Und wenn du es kriegst, dann ist es ein Browser-Bug und dann wollen wir das

00:38:34.766 --> 00:38:36.946
unbedingt wissen und dann gibt es sogar eine Belohnung.

00:38:37.166 --> 00:38:43.206
Also so ernst meinen wir das, aber man kann es schon relativ wild konfigurieren.

00:38:43.406 --> 00:38:49.066
Also wenn man ein leeres Konfigurations-Dictionary übergibt, dann sagt man halt, ich,

00:38:49.924 --> 00:38:53.144
Ich will im Endeffekt, dass das Sanitizer quasi nichts macht, sozusagen.

00:38:53.544 --> 00:38:56.464
Ich sage ihm weder, was er zu erlauben, noch was er zu entfernen hat.

00:38:56.824 --> 00:39:01.644
Dann erlaubt der Sanitizer wirklich alles, außer Event-Händler-Attribute,

00:39:02.144 --> 00:39:05.604
Script-Elemente und dann gibt es noch zwei, drei Corner-Cases.

00:39:05.784 --> 00:39:08.824
Da bin ich mir nicht sicher, ob ich die alle perfekt auswendig kenne.

00:39:10.924 --> 00:39:16.464
Iframe mit Source, JavaScript-URL und ahrefs mit JavaScript-URL.

00:39:16.664 --> 00:39:19.924
Also alles, was zu XSS finden kann, wird rausgenommen. Der Rest kann dann drinbleiben.

00:39:20.644 --> 00:39:28.564
Okay. Und nur so nochmal für mich. Also ich habe hier die MDN-Seite für ZHTML auf.

00:39:28.744 --> 00:39:33.044
Und da ist dokumentiert, ich weiß nicht, ob das Stand der Dinge ist,

00:39:33.144 --> 00:39:41.364
dass man dieses Options-Objekt im Grunde derzeit nur einen Sanitizer-Key reinstecken kann.

00:39:41.744 --> 00:39:47.824
Und darauf liegt dann entweder ein Sanitizer-Config oder ein Sanitizer-Instanz.

00:39:47.824 --> 00:39:52.744
Also das ist auch eine API, die man instanzieren kann mit wahrscheinlich einer Konfiguration.

00:39:53.344 --> 00:39:58.884
Und dann kann man das sozusagen je nach Use Case mal die andere Instanz nutzen.

00:40:00.284 --> 00:40:06.964
Und da könnte man aber eben auch einfach ein leeres Objekt übergeben.

00:40:07.124 --> 00:40:08.884
Das wäre dann eine Sanitizer-Config.

00:40:10.084 --> 00:40:14.224
Und das wäre aber dann eben anders, als wenn man nichts übergeben würde.

00:40:14.384 --> 00:40:18.104
Da ist es, wenn man nichts übergibt, dann habt ihr ein bestimmtes Ruleset und

00:40:18.104 --> 00:40:24.564
wenn man ein leeres Objekt übergibt, dann sagt man quasi geh ans Maximum, was du zulässt. Genau.

00:40:26.164 --> 00:40:27.684
Vielleicht gehen wir da noch,

00:40:28.976 --> 00:40:32.916
Ganz kurz drauf ein. Es gibt das Sanitizer-Objekt, das kann man installieren,

00:40:33.036 --> 00:40:37.776
New Sanitizer, und dann kann man beliebig übergeben und die Parameter lauten

00:40:37.776 --> 00:40:41.796
im Endeffekt Elements und dann sagt man, was man erlauben möchte.

00:40:42.496 --> 00:40:45.716
Entweder nur mit dem Namen als String, man kann es beliebig kompliziert machen

00:40:45.716 --> 00:40:49.736
und auch Namespaces übergeben und spezifische Attribute, die dazu gehören sollen oder nicht.

00:40:50.376 --> 00:40:53.336
Und dann gibt es das Gegenstück Remove Attributes, was sind all die Dinge,

00:40:53.436 --> 00:40:56.096
die der Sanitizer auf jeden Fall entfernen soll oder Remove Elements,

00:40:56.316 --> 00:40:59.016
was sind Elemente, die der Sanitizer auf jeden Fall entfernen soll.

00:40:59.356 --> 00:41:02.536
Und dann wird es beliebig kompliziert. Und das ist so eine Sache,

00:41:02.636 --> 00:41:06.976
wo ich gerne im Format wie Podcast sagen würde, du liest es euch auf MDN durch.

00:41:07.296 --> 00:41:09.396
Da kann man sich austoben.

00:41:09.976 --> 00:41:13.556
Und dieses Sanitizer-Objekt kann man dann wieder verwenden. Wenn es besonders

00:41:13.556 --> 00:41:14.676
kompliziert wurde, dann schreibt

00:41:14.676 --> 00:41:17.436
man das in eine globale Variable und kann immer darauf referenzieren.

00:41:17.616 --> 00:41:20.696
Oder wenn man weiß, man hat immer drei Use Cases, dann kann man die alle irgendwo

00:41:20.696 --> 00:41:23.056
gut sich merken und dann...

00:41:24.052 --> 00:41:28.772
Und dann weiterverwenden. Und das Sanitizer-Objekt erlaubt es auch,

00:41:28.932 --> 00:41:33.152
gefragt zu werden, wie ist deine Konfiguration, würdest du das hier erlauben und so weiter.

00:41:33.452 --> 00:41:37.752
Aber im Endeffekt hält es halt eine Konfiguration, die nicht viel mehr ist als

00:41:37.752 --> 00:41:39.792
ein Dictionary mit komplizierten Listen.

00:41:41.252 --> 00:41:47.412
Was ich gerne als Security Engineer als Hinweis noch mitgebe,

00:41:47.592 --> 00:41:50.632
ist, dass es natürlich immer besser ist, sich zu überlegen, was sind all die

00:41:50.632 --> 00:41:54.112
Elemente, die ich erlauben möchte, als sich zu überlegen, was sind alle die,

00:41:54.152 --> 00:41:55.192
die ich entfernen möchte.

00:41:56.392 --> 00:41:59.752
Weil HTML verändert sich natürlich, insbesondere wenn man selber eine Config

00:41:59.752 --> 00:42:01.932
schreibt, dann hat man das zu einem Zeitpunkt geschrieben, wo man weiß,

00:42:01.992 --> 00:42:03.412
es gibt alle diese HTML-Elemente.

00:42:03.552 --> 00:42:05.452
Es kommen immer mal wieder welche hinzu.

00:42:05.972 --> 00:42:10.212
Sicher ist es immer, wenn man sagt, okay, das sind die, die ich beibehalten möchte.

00:42:10.472 --> 00:42:13.292
Und dann kann man sich sehr, sehr gut eine sichere Config bauen,

00:42:13.472 --> 00:42:16.212
für welchen Use Case man auch immer hat.

00:42:17.032 --> 00:42:19.852
Ja, die Regel, die kenne ich auch. Deswegen wunderte ich mich gerade,

00:42:19.952 --> 00:42:23.832
dass ihr euch dann entschieden habt, doch auch den anderen Weg anzubieten,

00:42:24.032 --> 00:42:29.732
eben nur zu definieren, was herausgenommen werden muss,

00:42:29.912 --> 00:42:35.272
weil das im Grunde früher oder später immer schief geht, weil einem ja was durch

00:42:35.272 --> 00:42:39.512
die Lappen geht, Weil irgendwie neue Events kommen und die kann man dann per

00:42:39.512 --> 00:42:43.872
On-Event-Name dann als Attribut setzen oder sowas.

00:42:44.072 --> 00:42:49.912
Aber wahrscheinlich ist ja Default so, dass sowas schon mal in jedem Fall auch nicht möglich ist.

00:42:49.912 --> 00:42:53.812
Event-Händler können niemals hinzukommen, auch wenn man einen Sanitizer baut,

00:42:54.072 --> 00:42:57.832
der nach unserer Auffassung nicht so super sicher ist, indem er halt als Blockliste

00:42:57.832 --> 00:43:02.592
bestimmt nummeriert, was man nicht haben möchte, kann XSS auf jeden Fall niemals nie dazukommen.

00:43:02.592 --> 00:43:05.512
Das ist etwas, das der Sanitizer als API garantiert.

00:43:06.092 --> 00:43:09.972
Aber wenn man jetzt einen besonders streckten Use Case hat, wenn man sagt,

00:43:10.072 --> 00:43:11.632
ich möchte das keine Arten von ...

00:43:12.836 --> 00:43:16.096
In Medien geladen werden, ob es jetzt Audio, Video, sonst was ist.

00:43:16.416 --> 00:43:19.516
Und dann deswegen verbiete ich dann das Audio, Picture, Video,

00:43:19.776 --> 00:43:22.636
Image, Element und vielleicht SVG und ich weiß nicht was noch.

00:43:22.976 --> 00:43:24.016
Dann kommt aber was dazu.

00:43:24.456 --> 00:43:28.556
Dann Pech gehabt, nicht fleißig aufgepasst.

00:43:28.616 --> 00:43:31.496
Dann wäre es natürlich besser gewesen zu sagen, nee, ich baue mir lieber einen

00:43:31.496 --> 00:43:34.616
Sanitizer, der all das erlaubt, was ich haben will, anstatt aufzulisten,

00:43:34.756 --> 00:43:37.056
was alles potenziell problematisch ist für meinen Use Case.

00:43:37.196 --> 00:43:39.756
Und dann sagt man halt lieber, okay, ich möchte keine Bilder.

00:43:40.096 --> 00:43:46.056
Dann überlege ich mich, was möchte ich denn? Ich möchte vielleicht nur Textbeiträge,

00:43:46.136 --> 00:43:49.416
also erlaube ich Listen, Zitate...

00:43:51.798 --> 00:43:59.818
Block Quotes, Sites, Bold Text, Emphasis, Italics, Strike-Through, was auch immer.

00:44:00.158 --> 00:44:03.638
Irgendwie so. Und erlaube auch wirklich nur, nur die. Und wenn da was Spannendes

00:44:03.638 --> 00:44:06.298
dazukommt, dann muss ich halt meinen Zenitizer updaten.

00:44:06.418 --> 00:44:09.038
Aber dann kann es halt nicht irgendwie meine Annahme kaputt gehen,

00:44:09.158 --> 00:44:14.478
sondern dann fehlt da ein schönes Feature. Ja, genau. Das sind so die Konfigurationsmöglichkeiten.

00:44:15.558 --> 00:44:21.598
Und dann angefangen haben wir eigentlich mit, was ist der Default?

00:44:21.698 --> 00:44:25.098
Und ich hatte ja schon gesagt, der Default ist nicht nur, wir machen alles JavaScript

00:44:25.098 --> 00:44:28.758
raus, also Script-Element und Event-Händler, sondern noch viel mehr.

00:44:28.758 --> 00:44:35.878
Und da macht es wahrscheinlich Sinn, im Detail reinzugucken und vielleicht auch

00:44:35.878 --> 00:44:41.858
nochmal ein bisschen individuell auszuholen, was sind denn die spannenden Angriffe, warum machen wir das?

00:44:43.298 --> 00:44:50.078
Und ein witziges Ding, wie ich finde, ist ein Angriff, der heißt Dom Clobbering.

00:44:51.118 --> 00:44:53.838
Das kann sein, das wird da schon

00:44:53.838 --> 00:44:56.778
mal, ne, da hattet ihr eine Revision mit Mario Heiderich, nicht wahr?

00:44:57.598 --> 00:45:02.498
Also ich glaube auch, dass wir mit, also Mario war auf jeden Fall bald zu Gast

00:45:02.498 --> 00:45:05.618
und ich glaube, dass wir auch über Dom Clobbering gesprochen haben,

00:45:05.758 --> 00:45:09.958
weil es ist nicht auch sogar eine Schweinerei, die er sich überlegt hatte?

00:45:09.958 --> 00:45:11.758
Mit überlegt, auf jeden Fall.

00:45:12.218 --> 00:45:15.938
Ich lese gerade, es ist Revision 202 Dom-Clobbering. Wir fassen es trotzdem

00:45:15.938 --> 00:45:17.258
noch mal in drei Sätzen zusammen.

00:45:17.918 --> 00:45:20.838
Wenn man ein hrtem Element mit einer ID hat,

00:45:21.538 --> 00:45:27.338
zum Beispiel gebe ich einem bestimmten Link oder einem bestimmten Knopf,

00:45:27.418 --> 00:45:30.638
gebe ich den Namen Submit-Button, sage ich mal Submit-Button für meinen Submit-Knopf

00:45:30.638 --> 00:45:35.358
als ID, dann gibt es automatisch, das macht der Browser hilfreicherweise,

00:45:36.178 --> 00:45:39.638
die Variable window.submit-Button oder einfach nur Submit-Bahn,

00:45:39.738 --> 00:45:41.138
die halt auf dieses Element zeigt.

00:45:42.120 --> 00:45:48.400
Das machen sich manchmal Angreifer zu Nutze, um JavaScript zu verwirren,

00:45:48.560 --> 00:45:51.980
wenn es denkt, eine Variable gibt es, die es aber gar nicht gibt,

00:45:52.320 --> 00:45:55.620
sondern stattdessen verweist die halt auf HTML, dass der Angreifer eingeschleust hat.

00:45:56.360 --> 00:46:01.780
Und dadurch kann es sein, dass dann Code Pfade abläuft oder sich bestimmte Objekte

00:46:01.780 --> 00:46:04.660
anguckt, die halt gar nicht das sind, was der Code ursprünglich gedacht hat,

00:46:04.760 --> 00:46:08.800
sondern was halt dann im Endeffekt DOM-Nodes sind, die eine bestimmte Variable überschreiben.

00:46:09.320 --> 00:46:16.480
Das ist DOM-Clobbering. Das kann man absurd weit treiben mit wirklich komplizierten Methoden.

00:46:16.780 --> 00:46:24.580
Ein schönes Beispiel ist ein Form-Element mit Radio-Buttons,

00:46:24.840 --> 00:46:26.480
die alle die gleiche ID haben.

00:46:27.636 --> 00:46:32.336
Und ich nenne die Radio-Buttons Children als ID.

00:46:32.716 --> 00:46:37.576
Und wenn ich dann Form.Children mache und darüber iteriere, dann iteriere ich

00:46:37.576 --> 00:46:42.056
nicht über alle Kind-Elemente von diesem Formular, sondern nur über diese Radio-Buttons,

00:46:42.156 --> 00:46:43.316
die jemand eingeschleust hat.

00:46:43.656 --> 00:46:48.656
Das heißt, man kann auch sehr, sehr absurde, komplizierte Konstrukte von Objekten

00:46:48.656 --> 00:46:55.836
über eingeschmuggeltes HTML erzeugen und dann auch viele Varianten von Code

00:46:55.836 --> 00:46:57.436
verwirren. Ja, verwirrend.

00:46:57.576 --> 00:47:00.156
Das ist ja auch so überzeugend, dass das total legitim ist.

00:47:01.596 --> 00:47:04.316
So Archäologenwissen, weil das ja alles, glaube ich, so... Das ist absurd.

00:47:04.636 --> 00:47:05.596
Das ist total absurd, ja.

00:47:06.136 --> 00:47:10.776
Genau, das ist ja alles Kram. Also diese Effekte gibt es ja schon seit Ewigkeiten.

00:47:11.156 --> 00:47:15.296
Und die muss man natürlich eben auch weiter durchschleifen, weil das Web ist

00:47:15.296 --> 00:47:16.536
ja immer rückwärtskompatibel.

00:47:17.476 --> 00:47:21.636
Und deswegen hat man diesen Mist eben für immer an der Backe.

00:47:21.896 --> 00:47:25.356
Wobei man natürlich da auch so liegen könnte, ob man mit einem Flag oder so

00:47:25.356 --> 00:47:27.316
sowas auch deaktiviert.

00:47:27.776 --> 00:47:29.736
Weil eigentlich programmiert ja kein Mensch mehr so.

00:47:30.576 --> 00:47:32.676
Da gibt es Bestrebungen, aber.

00:47:35.236 --> 00:47:38.156
Rückwärtskompatibilität und gerade so Use-Counter, die wir eingebaut haben,

00:47:38.316 --> 00:47:40.876
sagen, programmieren leider noch genug Leute.

00:47:41.496 --> 00:47:44.256
Also wir hätten es gerne schon lange entfernt. Ja, ich meine,

00:47:44.336 --> 00:47:47.176
das Web ist halt für alle da. Also es ist halt sehr zugänglich.

00:47:47.536 --> 00:47:52.596
Das finde ich toll. Das muss es auch unbedingt sein. Das Web ist für alle da. Ja, sehr schön.

00:47:53.616 --> 00:47:58.596
Das können wir uns einrahmen. Aber leider können wir es nicht entfernen. Ich glaube, für...

00:48:00.677 --> 00:48:05.137
Für Windows und für Forms geht es. Ich glaube, es gibt nur ein paar absurde

00:48:05.137 --> 00:48:10.537
Corner-Cases, dass man auch Document-Properties, also vom Document-Objekt überschreiben kann.

00:48:10.677 --> 00:48:13.737
Und ich glaube, das haben wir geschafft, in Firefox rauszupatchen.

00:48:14.037 --> 00:48:16.857
Und ich glaube, vorgeschlagen im HTML-Standard, dass das weggenommen wird.

00:48:16.997 --> 00:48:19.077
Aber das löst leider DOM-Clubbering nicht. Wir haben gesehen,

00:48:19.137 --> 00:48:21.297
bei Document kann man das machen. Das machen die wenigsten Leute.

00:48:22.837 --> 00:48:25.097
Aber wir können es leider nicht so ohne weiteres deprecaten.

00:48:25.157 --> 00:48:26.217
Da haben wir auch drüber nachgedacht.

00:48:26.597 --> 00:48:30.757
Und das heißt also, der Sanitizer, Der Sanitizer, der würde dann,

00:48:31.037 --> 00:48:36.457
genau, also der würde, oder nimmt er alle IDs, alle ID-Attribute grundsätzlich raus?

00:48:36.677 --> 00:48:40.617
Ja, tatsächlich ist unsere Lösung, wir erlauben das ID und das Name-Attribut

00:48:40.617 --> 00:48:43.597
nicht. In bestimmten Kontexten ist es auch mit dem Name-Attribut möglich.

00:48:43.697 --> 00:48:46.797
Die sind einfach nicht erlaubt. Wenn man merkt, hey, der Sanitizer stibitzt

00:48:46.797 --> 00:48:48.737
mir die, ich brauche die aber, dann kann man die wieder erlauben.

00:48:50.697 --> 00:48:55.197
Dann sollte man aber sich Gedanken darüber machen, was hat das für Konsequenzen.

00:48:55.777 --> 00:48:58.837
Für mich ist das jetzt leicht gesagt, als jemand, der gerne Security macht,

00:48:58.897 --> 00:49:03.177
wird man auch so ein bisschen Experte in Legacy-Technology, wie du sagst, Code-Archäologe.

00:49:04.497 --> 00:49:11.497
Ja, das wäre was, was ich brauchen würde, glaube ich. Ich habe halt den Use-Case, dass eben einfach ein,

00:49:12.485 --> 00:49:18.365
quasi kleinseitig gerendertes HTML aus einer Template, eben entweder per,

00:49:18.605 --> 00:49:22.425
also wenn noch gar nichts da ist, dann donnere ich das halt per InHTML rein,

00:49:23.545 --> 00:49:29.805
und ansonsten nutze ich eben einen DOM-Diffing-Algorithmus und wenn man jetzt

00:49:29.805 --> 00:49:33.265
zum Beispiel Formulare erinnert, braucht man ja IDs, allein um die Labels,

00:49:33.345 --> 00:49:37.545
um dir sozusagen die Beziehungen aufzuzeigen und Name-Attribute natürlich auch.

00:49:39.105 --> 00:49:44.025
Das genau, muss ich mir gerne abspeichern für, wenn ich den Code dann update.

00:49:44.485 --> 00:49:49.545
Ja, und die Sanitizer API als Spezifikation, wie sie jetzt geschrieben ist,

00:49:49.605 --> 00:49:51.645
hat ein Kapitel Security Considerations.

00:49:52.005 --> 00:49:55.145
Da steht exakt drin, was wir tun und warum wir das tun.

00:49:56.265 --> 00:50:00.345
Und idealerweise dann, dass Leute lesen, ah, okay, DOM-Klobbering.

00:50:00.565 --> 00:50:05.365
Und da steht halt gerade drin, ja, wir schützen nur DOM-Klobbering,

00:50:05.405 --> 00:50:08.385
indem wir die Elemente entfernen, Attribute, Entschuldigung, Attribute entfernen.

00:50:08.525 --> 00:50:11.285
Man kann die wieder hinzufügen, aber dann sollte man halt gut überlegen,

00:50:11.345 --> 00:50:15.525
was da für Werte drinstehen und ob das für Probleme sorgen kann.

00:50:18.922 --> 00:50:24.462
Genau, und dann gibt es natürlich, ach, zu DOM Clobbering noch ein schönes Beispiel übrigens.

00:50:25.102 --> 00:50:29.782
DOM Purify selber als Library, weil es ja genau sowas tut, es guckt sich ja

00:50:29.782 --> 00:50:33.462
zum Beispiel ein Form-Element und alle diese Kinder an, hatte auch mal Probleme

00:50:33.462 --> 00:50:36.142
mit DOM Clobbering, hatte auch mal Sicherheitslögen zu dem Thema.

00:50:36.142 --> 00:50:47.242
Entfernt deswegen auch immer ID und Name-Attribute, wenn die heißen wie etwas, das DOM Purify braucht.

00:50:47.342 --> 00:50:52.262
Nämlich zum Beispiel .children.childnodes.child-aluminium sind sozusagen in

00:50:52.262 --> 00:50:57.422
DOM Purify immer verbotene Attributwerte für ID und Name, weil sie es verboten

00:50:57.422 --> 00:50:58.762
müssen, um funktionieren zu können.

00:50:58.902 --> 00:51:01.262
Um ein funktionierendes Ding zu sein, was nicht kaputt geht.

00:51:02.322 --> 00:51:06.882
Den Luxus hat die Sanitizer API, das nicht immer verbieten zu müssen,

00:51:06.962 --> 00:51:11.802
weil es halt in C++ geschrieben ist und anders irgendwie über so ein Document

00:51:11.802 --> 00:51:12.862
Fragment iterieren kann.

00:51:14.610 --> 00:51:19.270
Cool wäre ja auch, wenn es einfach guckt, ob es eine Property mit dem Namen

00:51:19.270 --> 00:51:25.230
auf dem Global This gibt und dann eben das Ding rausnimmt und ansonsten drin lässt.

00:51:25.770 --> 00:51:31.110
Aber das ist jetzt nur so ein kurzer Gedanke von mir. Das könnte man vermutlich auch machen.

00:51:31.590 --> 00:51:37.490
Was für uns bei der API immer schwierig war, wie kann man das konfigurierbar machen?

00:51:37.730 --> 00:51:41.870
Wie kann man das an oder aus machen? Und ein einfacher On-Off-Switch,

00:51:41.930 --> 00:51:44.810
in dem wir sagen, Attribut erlaubt oder nicht, und der Benutzer kann das ändern.

00:51:46.050 --> 00:51:50.730
Lässt sich halt gut darstellen in einem Konfigurations-Dictionary,

00:51:50.870 --> 00:51:54.990
besser als eine bestimmte Logik mit einem bestimmten Verhalten für bestimmte Werte.

00:51:56.110 --> 00:52:00.710
Dementsprechend haben wir das so gelöst eine schönere Variante wäre das definitiv

00:52:00.710 --> 00:52:05.190
und das wäre dann wahrscheinlich auch sicherer und robuster ist aber glaube

00:52:05.190 --> 00:52:10.750
ich außer jetzt in einem längeren Podcast schwer zu vermitteln ja klar, das ist natürlich,

00:52:11.630 --> 00:52:17.310
kompliziert zu konfigurieren definitiv, dann fangen wir wahrscheinlich an JavaScript-Funktionen

00:52:17.310 --> 00:52:22.170
in seinem Konfigurationsobjekt zu hinterlegen oder sowas genau und dann wollen Leute,

00:52:22.830 --> 00:52:29.370
dann vielleicht irgendwie Callbacks oder Events und das kann ich mir alles als

00:52:29.370 --> 00:52:31.350
interessant vorstellen,

00:52:32.090 --> 00:52:37.050
passte aber auch nicht so ganz zu unserem Ansatz, was zu machen,

00:52:37.150 --> 00:52:39.170
was nah an diesem Cowpath dran ist, wie gesagt.

00:52:39.250 --> 00:52:45.230
Und vermutlich wandert das ja einmal instanziert dann irgendwie oder es wird dann wahrscheinlich,

00:52:45.410 --> 00:52:51.030
oder es ist in nativen Code läuft es ja und dann irgendwie immer den Sprung

00:52:51.030 --> 00:52:54.970
wieder in die JavaScript Script-Umgebung, rein und wieder raus.

00:52:55.330 --> 00:53:00.550
Das ist ja auch bei so in Rust geschriebenen Tools oder so quasi Lintern.

00:53:01.330 --> 00:53:04.310
Sobald man die mit Plugins erweitern will, dann stehen die ja immer vor der

00:53:04.310 --> 00:53:10.270
Fragestellung, wie die das machen, ohne dass die Performance in den Keller geht. Genau.

00:53:11.792 --> 00:53:17.952
Und deswegen haben wir entschieden, es ist halt schön, irgendwie so eine a priori

00:53:17.952 --> 00:53:19.552
Entscheidung zu haben. Ja, nein.

00:53:19.752 --> 00:53:22.232
Und dann werden die halt einfach abgefrühstückt und können irgendwie hin und

00:53:22.232 --> 00:53:23.152
her transformiert werden.

00:53:23.152 --> 00:53:29.072
Und momentan ist es auch unsere Antwort, wenn man es selektiver haben möchte,

00:53:29.232 --> 00:53:35.032
für spezifische Attributwerte oder bestimmte Verhältnisse von dieses Elternelement

00:53:35.032 --> 00:53:38.772
auf dieses Kind-Element ganz bestimmt nicht haben, aber andere schon und so weiter.

00:53:40.432 --> 00:53:44.852
Dann geht es nicht direkt, aber das ist ja ein bisschen auch das Schöne,

00:53:45.052 --> 00:53:49.572
es lässt sich irgendwie bauen, wenn man kurz kreativ nachdenkt.

00:53:49.752 --> 00:53:54.172
Und eine Methode wäre halt, ich lege was in Template-Element,

00:53:54.732 --> 00:53:58.292
sanitize das, was im Template-Element ist und füge dann nochmal manuell nach,

00:53:59.392 --> 00:54:02.972
kann nochmal selber mal eine Schleife bauen, da die Elemente durchzugehen.

00:54:04.348 --> 00:54:08.968
Und dann kommt man relativ weit. Genau. Genau.

00:54:09.048 --> 00:54:14.388
Gibt es noch irgendeinen Cross-Set-Scripting-Flavor, den ihr noch abfangt?

00:54:14.508 --> 00:54:17.568
Also wir hatten am Anfang auch, oder in der Vorbesprechung war das,

00:54:17.708 --> 00:54:23.008
glaube ich, einmal kurz den Begriff Mutated-XSS angesprochen.

00:54:24.328 --> 00:54:30.708
Das macht sich zunutze, dass HTML-Parser nicht gleich HTML-Parser ist und der

00:54:30.708 --> 00:54:34.468
eine vielleicht was durchlässt, was dem anderen nicht gut bekommt.

00:54:35.648 --> 00:54:42.028
Da sind wir wieder bei dem Kontext, was wir vorhin hatten, dass wir gesagt haben,

00:54:42.168 --> 00:54:46.428
wir bauen das Parsing halt mit in den Sanitizer ein und parsen nur einmal und

00:54:46.428 --> 00:54:48.888
sagen, das soll nicht wieder in HTML geworfen werden.

00:54:49.348 --> 00:54:53.008
Damit haben wir einen großen Teil von Mutated Accesses abgefrühstückt,

00:54:53.208 --> 00:54:57.608
wo halt genau die Idee ist, wenn es zweimal geparst wird, dann ist es vielleicht

00:54:57.608 --> 00:54:59.148
problematisch, weil unterschiedlich.

00:54:59.148 --> 00:55:06.168
Ja, aber es schützt halt nur in diesem, ich sag mal, engem spezifischen Use Case.

00:55:06.388 --> 00:55:12.228
Man kann natürlich trotzdem noch das, was der Sanitizer IM irgendwo eingefügt

00:55:12.228 --> 00:55:15.948
hat über SetHTML, kann man sich natürlich noch irgendwo rausholen und später

00:55:15.948 --> 00:55:17.988
woanders wieder in einem anderen Kontext reinlegen.

00:55:18.568 --> 00:55:21.408
Davor ist es natürlich nicht komplett gefeit. Ja.

00:55:22.695 --> 00:55:25.795
Aber es ist auf jeden Fall, man muss es schon sehr stark wollen.

00:55:26.535 --> 00:55:30.015
Genau, man muss es wollen. Aber es ist jetzt auch nicht super abwegig zu sagen,

00:55:30.095 --> 00:55:36.555
jemand findet die Sanitizer-API als setHTML doof, macht deswegen Template-Element-setHTML,

00:55:37.295 --> 00:55:40.855
iteriert dann irgendwie hin und her und popelt sich dann String wieder raus

00:55:40.855 --> 00:55:43.315
und macht dann damit Sachen und wirft den dann wieder in ein Dokument.

00:55:43.775 --> 00:55:47.435
Dann kann man wieder Mutated-XSS haben. Dann hat man vielleicht wieder ein Problem.

00:55:48.075 --> 00:55:51.735
Die Empfehlung wäre da, wenn man denkt, man möchte sowas in der Art tun,

00:55:51.735 --> 00:55:54.515
ist an der Stelle ganz klar, ein Template-Element ist super,

00:55:54.795 --> 00:55:59.175
weil ein Template-Element hat halt dieses Punkt-Content- Attribut und das gibt

00:55:59.175 --> 00:56:00.275
dir ein Document-Fragment zurück.

00:56:00.535 --> 00:56:05.115
Und ein Document-Fragment kannst du auch kopieren und woanders einfügen mit

00:56:05.115 --> 00:56:10.075
Append Node oder Pre-Pend und was es dann noch alles gibt, before, after.

00:56:10.755 --> 00:56:13.895
Für Nodes gibt es ja, glaube ich, in jede Richtung irgendwie eine Funktion.

00:56:14.555 --> 00:56:17.355
Und dann wird es halt nicht gepasst, sondern es ist wirklich ein Objekt,

00:56:17.435 --> 00:56:21.755
was unter ein anderes Objekt gehangen wird und Und diese Baumstruktur kann beibehalten

00:56:21.755 --> 00:56:24.975
werden, was ja auch performance-mäßig spannender ist. Man muss nicht zweimal parsen, immer gut.

00:56:25.475 --> 00:56:27.655
Aber dann hat man halt auch kein App-Excess.

00:56:29.375 --> 00:56:36.635
Und das ist auch was, wovor ich jetzt. Wie ist das mit dem Szenario des Wechselns zwischen den Welten?

00:56:36.875 --> 00:56:44.315
Also man kann ja SVG und MathML und sowas einbetten in HTML.

00:56:44.315 --> 00:56:49.395
Und im Grunde ist es ja so, dass beim Parsen auf einen anderen Parser dann umgeschaltet

00:56:49.395 --> 00:56:51.875
wird, wenn man in diesen Bereichen unterwegs ist.

00:56:52.095 --> 00:56:55.135
Und da gibt es ja auch wiederum dann andere Regeln.

00:56:55.235 --> 00:57:00.035
Ich nehme mal an, ich weiß nicht, kann man inner-HTML bei SVG-Elementen machen?

00:57:00.135 --> 00:57:01.475
Ich sage mal einfach wahrscheinlich schon.

00:57:01.915 --> 00:57:04.335
Und dann kann man das eben genauso ... Ich glaube schon.

00:57:05.789 --> 00:57:12.849
Da ihr quasi den Browser-Parser nutzt, kann den wahrscheinlich auch einfach

00:57:12.849 --> 00:57:15.549
entsprechend umschalten und das Richtige tun.

00:57:16.209 --> 00:57:20.189
Ja, auch übrigens einer der Gründe, warum wir nach fünf Jahren nochmal über

00:57:20.189 --> 00:57:21.429
die Sanitizer-API sprechen.

00:57:21.869 --> 00:57:25.849
Etwas, wo ich gehofft hatte zu sagen, wir machen nur HTML und lassen den Rest

00:57:25.849 --> 00:57:27.329
weg oder verbieten den oder so.

00:57:27.549 --> 00:57:31.809
Und da gab es relativ klares Feedback von Leuten, die tiefer in Webstandards

00:57:31.809 --> 00:57:35.969
sitzen und am HTML-Spec mitschreiben oder mitarbeiten.

00:57:37.129 --> 00:57:40.929
Nee, das gehört alles schon dazu und das muss auch unterstützt werden,

00:57:41.149 --> 00:57:43.569
sonst funktioniert es, sonst ist es nicht part of the web.

00:57:44.509 --> 00:57:47.449
Dementsprechend tun wir das alles auch. Das hat uns schon noch ein bisschen

00:57:47.449 --> 00:57:49.529
Gehirnschmalz und ein bisschen Nerven und ein bisschen...

00:57:50.719 --> 00:57:56.919
Ärger bereitet. Aber genau, die Sanitizer API versteht, was SVG ist,

00:57:57.079 --> 00:58:01.799
was MathML ist und was da teilweise unterschiedlich ist und ein bisschen komischer

00:58:01.799 --> 00:58:05.139
und vielleicht ein bisschen XML-ischer,

00:58:05.579 --> 00:58:10.999
kann das aber alles und man kann auch ganz spezifisch Elemente für ein Namespace

00:58:10.999 --> 00:58:12.199
erlauben oder verbieten.

00:58:12.199 --> 00:58:15.099
Das heißt, wenn man eine Sanitar-Config schreibt, dann kann man auch sagen,

00:58:15.199 --> 00:58:19.919
ich möchte SVG und dann übergibt man halt SVG Element-Name und dem Namespace

00:58:19.919 --> 00:58:24.639
und dann ist es klar, es ist das SVG-Element gemeint und nicht das Element gemeint.

00:58:24.679 --> 00:58:27.679
Da gibt es ja teilweise auch ähnliche Namen mit anderen Semantiken.

00:58:27.979 --> 00:58:28.719
Das ist dann ja auch wichtig.

00:58:29.499 --> 00:58:31.119
Das ist dann die Gefahr so ein bisschen.

00:58:32.499 --> 00:58:37.719
Genau. Und da gibt es ja auch dieses Document-Create-Element-NS. Also quasi,

00:58:38.599 --> 00:58:43.679
dann die Namespace-Variante, wo man dann sagen kann, ich möchte jetzt aber für

00:58:43.679 --> 00:58:47.579
SVG ein Element erzeugen und nicht für HTML, was der Default ist.

00:58:48.059 --> 00:58:51.659
So ähnlich haben wir es in unserem Konfigurationsobjekt auch abgedeckt,

00:58:51.759 --> 00:58:55.799
indem man Elementname als String übergeben kann und sagen kann, ich meine das Element.

00:58:56.339 --> 00:59:00.539
Und dann meint man im Zweifelsfall das HTML-Element, was es gibt unter diesem Namen.

00:59:01.079 --> 00:59:03.779
Wenn man aber was anderes meint, dann kann man halt ein Dictionary übergeben

00:59:03.779 --> 00:59:06.759
und sagen, ich meine das Element mit dem Namen und dem Namespace.

00:59:07.499 --> 00:59:11.559
Und dann ist ganz klar, was gemeint ist, dass man da auch beliebig spezifisch

00:59:11.559 --> 00:59:17.539
sein möchte, wie es die Webplattform manchmal verlangt, aber auch es sich einfacher machen kann.

00:59:19.922 --> 00:59:25.442
Ja, hört sich doch alles gut an. Und du hast gesagt, das shippt alles demnächst.

00:59:25.922 --> 00:59:31.242
Also genau, ich glaube, wie ist das momentan? Ist noch kein Browser am Start, oder?

00:59:31.742 --> 00:59:35.062
Es ist in Firefox Beta. Ah ja, genau.

00:59:35.802 --> 00:59:41.782
Und bei Chrome bin ich mir nicht sicher, ob das schon in einer Beta-Version

00:59:41.782 --> 00:59:44.302
ist oder ob das noch die Canary-Branch ist.

00:59:44.402 --> 00:59:48.002
Auf Chrome Canary gibt es auch. Chrome Beta weiß ich nicht.

00:59:49.922 --> 00:59:55.322
Und ja, im Februar 2026 wird das alles schippen. Dann kann man Elementor ZDH

00:59:55.322 --> 00:59:56.562
machen und dann ist es sicher.

00:59:57.543 --> 01:00:04.443
Cool. Das ist ja fast so ein bisschen konzertiert wie diese hier Interop-Geschichten,

01:00:04.683 --> 01:00:09.343
aber ist wahrscheinlich gar nicht Teil von Interop, oder? weil dafür ist es

01:00:09.343 --> 01:00:12.063
zu frisch. Dafür ist es zu frisch.

01:00:13.683 --> 01:00:18.103
Genau. Bei Interop geht es ja meistens darum, alle Browser unterstützen es einigermaßen.

01:00:18.643 --> 01:00:22.143
Wir wollen uns jetzt sicher sein, dass es nicht nur einigermaßen ist,

01:00:22.263 --> 01:00:23.023
sondern dass wir uns einigen.

01:00:23.123 --> 01:00:28.603
Das sind all die Test Cases, das sind all die Corner Cases, all die Randbedingungen,

01:00:28.703 --> 01:00:31.063
all die Dinge, die alle so ein bisschen subtil anders sind, aber die meisten

01:00:31.063 --> 01:00:32.643
Entwickler benutzen das hoffentlicherweise nie.

01:00:33.143 --> 01:00:35.823
Und dann wird es halt schnell, klar, okay, alle Browser können das,

01:00:35.823 --> 01:00:37.803
Aber alle Browser machen das dann doch ganz schön anders.

01:00:38.103 --> 01:00:43.143
Und da geht es bei Interop ganz klar darum, hey, entweder haben wir viele Web-Plattform-Tests

01:00:43.143 --> 01:00:47.183
oder wir schreiben noch ganz viele Tests und sagen, jetzt sorgen wir dafür,

01:00:47.263 --> 01:00:49.003
dass es wirklich, wirklich gleich ist.

01:00:50.623 --> 01:00:55.543
Und das funktioniert erstaunlich gut und nehmen auch alle Browser sehr ernst.

01:00:55.763 --> 01:00:58.903
Bei der Überlegung, wollen wir das in Interop machen?

01:00:59.503 --> 01:01:03.243
Was spricht dafür, was spricht dagegen? Aber dann auch, wenn man sich geeinigt

01:01:03.243 --> 01:01:06.663
hat, als Gruppe, okay, das qualifiziert für Interop.

01:01:06.923 --> 01:01:10.223
Die Entwickler wollen das und wir sehen, da gibt es ordentliche Divergenzen.

01:01:11.583 --> 01:01:14.563
Ja, und es muss viele Tests geben. Das ist ja auch immer voraussetzung,

01:01:14.823 --> 01:01:16.383
glaube ich. Es muss viele Tests geben.

01:01:16.583 --> 01:01:19.403
Und was dann aber auch dazugehört ist, es dürfen die Tests dann nicht mehr verändert

01:01:19.403 --> 01:01:23.223
werden. Wenn man sagt, das sind die Tests, denen wir alle hinterherrennen.

01:01:23.703 --> 01:01:29.363
Wenn dann jemand merkt, da gibt es noch keinen Test, dann müssen sich alle drei einig sein.

01:01:29.503 --> 01:01:33.223
Oh, diesen Corner Case, das wollen wir schon auch lösen und nicht einer prescht

01:01:33.223 --> 01:01:34.843
vor und dann sind alle irgendwie verwundert.

01:01:35.596 --> 01:01:39.376
Aber das wird so ernst genommen, dass diese Ziele, die da gesetzt werden und

01:01:39.376 --> 01:01:44.916
im Endeffekt ist das Ziel, glaube ich, Prozentzahl von Tests, die gepasst werden,

01:01:45.256 --> 01:01:49.556
dass die am Ende des Jahres, zumindest in den Pre-Release-Versionen wie Safari

01:01:49.556 --> 01:01:51.936
Technology Preview, 5 Oxenightly, Chrome Canary,

01:01:52.416 --> 01:01:56.296
dass die alle bei irgendwie 98, 99, 100 Prozent liegen.

01:01:57.296 --> 01:02:01.616
Das funktioniert. An der Stelle dann ein bisschen auf Topic vielleicht für diese Sendung.

01:02:02.076 --> 01:02:06.956
Wenn ihr was habt, wo ihr denkt, das brauchen alle, das benutzen alle,

01:02:07.076 --> 01:02:09.576
aber das ist trotzdem total absurd, dass jeder Browser das anders macht und

01:02:09.576 --> 01:02:11.656
zwar schon viel zu lange, dann

01:02:11.656 --> 01:02:14.516
schreibt ein Interproposal. Die Zeit ist witzigerweise schon abgelaufen.

01:02:14.896 --> 01:02:17.376
Dementsprechend müsst ihr euch das November diesen Jahres merken.

01:02:18.176 --> 01:02:19.376
Die Zeit geht ja schon rum.

01:02:20.436 --> 01:02:23.756
Ja, die geht schon rum. Wir sind bereits dabei zu entscheiden,

01:02:25.036 --> 01:02:27.676
was 2026 Interop Ziel wird.

01:02:29.096 --> 01:02:32.236
Und das ist halt für Dinge, die schon abgehangen sind, wo die Leute wissen,

01:02:32.356 --> 01:02:33.896
das ist aber komisch und unterschiedlich.

01:02:34.936 --> 01:02:39.916
Trust Types könnte Teil von Interop 2026 werden. Da gibt es ein Proposal und

01:02:39.916 --> 01:02:41.456
das ist implementiert in Firefox.

01:02:41.916 --> 01:02:45.256
Das kommt übrigens auch im Februar in Chrome und Safari.

01:02:45.976 --> 01:02:51.236
Da gibt es definitiv das Ziel, klarer zu sein und dass alle Browser da,

01:02:51.896 --> 01:02:56.596
Ich dachte, dass Trust Types vielleicht dann auch sozusagen in Tarteinheit mit

01:02:56.596 --> 01:03:02.996
der Sanitizer API ausgerollt werden, weil sie ja einfach gut zusammenspielen.

01:03:04.616 --> 01:03:09.036
Das hat definitiv bei uns was damit zu tun. Es gibt auch ein paar Änderungen

01:03:09.036 --> 01:03:13.536
an Trusted Types, die aber jetzt nicht spannend genug sind, dass ich das groß erzählen würde.

01:03:13.636 --> 01:03:19.776
Aber Chrome hat, nachdem wir Trusted Types implementiert haben und wir diverse.

01:03:21.714 --> 01:03:24.994
Ecken und Kanten in der Spezifikation gefunden haben, die irgendwie nicht Sinn

01:03:24.994 --> 01:03:29.554
gemacht haben oder nicht gefallen haben oder vielleicht in dem Standard anders

01:03:29.554 --> 01:03:32.294
sind als in existierenden Implementierungen und wir dann gemerkt haben,

01:03:32.374 --> 01:03:35.154
wenn wir das implementieren wie aufgeschrieben, dann ist es nicht wie in einer Browsern,

01:03:35.814 --> 01:03:37.974
sodass es da auch noch ein paar Änderungen gab und die landen,

01:03:38.074 --> 01:03:39.514
glaube ich, jetzt auch im Februar.

01:03:39.514 --> 01:03:43.434
Also wenn man ab Februar Trusted Types einsetzt, dann funktioniert es nicht

01:03:43.434 --> 01:03:46.794
nur in Safari, Firefox und Chrome, sondern dann funktioniert es auch ziemlich

01:03:46.794 --> 01:03:48.314
ähnlich in Safari, Firefox und Chrome.

01:03:48.514 --> 01:03:54.054
Und on top wollen wir zumindest gerne, dass das Teil von Interop sein kann.

01:03:54.594 --> 01:03:57.374
Dann ist es bis Ende des Jahres sowieso noch mal viel, viel glatter und runder.

01:03:58.734 --> 01:04:02.354
Ja, cool. Genau. Genau, und abschließend vielleicht noch mal die Frage,

01:04:02.834 --> 01:04:05.294
du hast es auch schon so ein bisschen beantwortet, oder wir haben es beantwortet

01:04:05.294 --> 01:04:12.234
schon so ein bisschen, die Sanitizer-API, die ist im Grunde nicht relevant für

01:04:12.234 --> 01:04:17.354
Leute, die Frameworks benutzen, also die klassischen SPA-Frameworks.

01:04:18.454 --> 01:04:25.514
Da hat man ja auch einfach wenig Einfluss darauf, wie die das ganze DOM zusammenstecken.

01:04:27.954 --> 01:04:32.954
Man benutzt es ja nie in der HTML, sondern es ist eigentlich eher für Leute,

01:04:33.154 --> 01:04:37.214
die entweder selber ein Framework implementieren, an einem Framework mitarbeiten,

01:04:37.434 --> 01:04:39.694
das in HTML und Konsorten nutzt.

01:04:41.134 --> 01:04:46.754
Oder eben die Dinge zu Fuß machen, weil sie einfach das nicht einsehen,

01:04:46.974 --> 01:04:49.034
für ein paar Kleinigkeiten ein Framework zu nutzen.

01:04:49.474 --> 01:04:54.634
Genau. Wenn man irgendwie ein kleines Hobbyprojekt schreibt mit wenigen 100-Zeilen-Code,

01:04:55.314 --> 01:04:57.394
dann bietet sich das auf jeden Fall an.

01:04:57.854 --> 01:05:01.334
Ansonsten nimmt einem im Regelfall das Framework relativ viel Arbeit ab.

01:05:01.734 --> 01:05:05.834
Falls jemand zuhört und an einem Framework arbeitet und interessiert ist,

01:05:05.974 --> 01:05:09.974
bin ich gerne bereit zu eins sprechen und rauszufinden, funktioniert es für euch?

01:05:10.174 --> 01:05:12.494
Wenn nicht, kann ich euch helfen, dass es für euch funktioniert?

01:05:13.351 --> 01:05:16.351
Das ist auch so ein bisschen, was ich mir überlegt habe, was jetzt der nächste

01:05:16.351 --> 01:05:17.851
Schritt ist, nachdem das jetzt geschippt ist.

01:05:18.391 --> 01:05:23.131
Wie kann man es Leuten in die Hand geben, wenn ja im Regelfall irgendwie eine

01:05:23.131 --> 01:05:27.691
Abstraktion und ein Framework dazwischen steckt, damit es auch wirklich ankommt

01:05:27.691 --> 01:05:31.651
und dieses Ziel erfüllt, was ich eingangs gesagt habe.

01:05:31.651 --> 01:05:35.731
Aber es ist einfach die häufigste Schwachstelle oder am meisten veröffentlichte

01:05:35.731 --> 01:05:37.091
Schwachstelle zumindest in Software.

01:05:37.691 --> 01:05:41.871
Wir wollen es loswerden. Wir haben jetzt einen Baustein. Es ist bestimmt nicht

01:05:41.871 --> 01:05:43.891
die perfekte Lösung, ganz bestimmt nicht.

01:05:44.151 --> 01:05:47.271
Aber es ist, glaube ich, ein weiterer sehr, sehr nützlicher Baustein und der

01:05:47.271 --> 01:05:49.771
muss halt bei den Leuten ankommen. Und wenn die Leute Frameworks benutzen,

01:05:50.271 --> 01:05:51.631
dann reden wir gleich mit den Frameworks.

01:05:52.331 --> 01:05:56.631
Genau. Ja, ich bin gespannt. Also ich werde es dann ja auch einsetzen.

01:05:57.011 --> 01:06:00.851
Und wenn mir etwas auffällt, dann melde ich mich aber unbedingt.

01:06:01.963 --> 01:06:04.963
Ihr habt das ja scheinbar schon echt super durchdacht und ich meine,

01:06:05.023 --> 01:06:06.343
es ist ja auch lang genug in der Mache.

01:06:08.363 --> 01:06:11.523
Dass wir bestimmt gut werden. Ja, vielen Dank dafür.

01:06:11.763 --> 01:06:16.503
Vielen Dank auch für einfach die ganze Arbeit, die du und auch alle anderen

01:06:16.503 --> 01:06:20.123
da reingesteckt habt in den letzten fünf Jahren.

01:06:20.763 --> 01:06:23.883
Ja, danke, dass ich immer wieder hierüber erzählen kann.

01:06:24.483 --> 01:06:29.223
Genau, jetzt musst du dir wahrscheinlich was Neues ausdenken für eine neue API

01:06:29.223 --> 01:06:32.163
für deinen nächsten Besuch hier bei uns.

01:06:32.383 --> 01:06:38.063
Aber Security ist ja auch immer ein Thema und immer spannend und da tut sich ja auch was.

01:06:38.183 --> 01:06:42.603
Also genau, wenn du mal irgendwie noch ein Thema hast, musst du wenige Leute kennen.

01:06:43.423 --> 01:06:46.583
Ja, wenn die Hürde ist nicht, dass ich eine neue API spezifizieren muss,

01:06:46.663 --> 01:06:48.983
dann finde ich es leichter hierher.

01:06:50.123 --> 01:06:55.323
Naja, wir haben ja auch diese eine Folge über diese ganzen Security-HTTP-Header gemacht.

01:06:55.623 --> 01:07:01.163
Die war jetzt ja auch nicht so ganz, also die war auch vielleicht so ein bisschen

01:07:01.163 --> 01:07:05.303
trockener und anstrengender, aber ich fand die super.

01:07:05.543 --> 01:07:10.563
Also danach hat das alles für mich viel mehr Sinn ergeben und ich konnte die

01:07:10.563 --> 01:07:12.263
auch gut auseinanderhalten.

01:07:12.903 --> 01:07:15.563
Also die muss ich mir vielleicht einfach nochmal anhören jetzt.

01:07:15.563 --> 01:07:19.023
Vielleicht ist das auch noch mal ein schöner...

01:07:20.409 --> 01:07:25.169
Schöner Hinweis an die Zuhörer, wenn es was gibt, was im Kopf keinen Sinn ergibt

01:07:25.169 --> 01:07:27.629
und im weitesten Sinne, was mit Security zu tun hat.

01:07:28.269 --> 01:07:33.529
Du suchst ja auch mal Talk, Vortragsideen. Ich bin offen für Vortragsideen.

01:07:33.909 --> 01:07:37.329
Dieses Jahr ist, glaube ich, primär meine Vortragsidee. Ich erzähle allen noch

01:07:37.329 --> 01:07:40.289
mehr über die Sanitizer API, bis es aus den Ohren rauskommt und keiner mehr

01:07:40.289 --> 01:07:41.409
vergessen hat. Das macht Sinn.

01:07:42.589 --> 01:07:45.709
Aber ja, natürlich erkläre ich auch gerne andere Security-Sachen.

01:07:45.809 --> 01:07:48.609
Das müssen nie meine eigenen APIs sein. Ich finde das Web großartig,

01:07:48.669 --> 01:07:52.649
wie es ist und freue mich über alle, die sich um Security kümmern oder darüber

01:07:52.649 --> 01:07:56.149
nachdenken oder inspiriert oder angestupst werden wollen.

01:07:56.309 --> 01:08:00.829
Und dann rede ich da gerne drüber. Letztes Jahr habe ich zum Beispiel viel über

01:08:00.829 --> 01:08:06.249
HTTPS geschrieben und wie sich das entwickelt hat, unsere Perspektive.

01:08:06.369 --> 01:08:09.169
Da hatten wir ein kleines wissenschaftliches Paper zugeschrieben.

01:08:10.369 --> 01:08:15.049
Oder ich hatte auch einen Vortrag letztes Jahr, warum Security immer irgendwie

01:08:15.049 --> 01:08:20.149
Opt-in ist. warum man Security nicht immer bei Default machen kann.

01:08:20.269 --> 01:08:23.529
Und die Antwort ist im Endeffekt, wie wir es schon ein bisschen besprochen haben,

01:08:23.609 --> 01:08:24.629
Backwards-Compatibility.

01:08:26.309 --> 01:08:29.729
Und dementsprechend vielleicht auch nochmal ein Appell, wenn man sich um Security

01:08:29.729 --> 01:08:33.749
kümmern möchte, dann muss man leider tätig werden. Dann kriegt man das nicht immer geschenkt.

01:08:34.209 --> 01:08:40.469
Ja, so ist es. Ja, super. Vielen, vielen Dank, Freddy, dass du...

01:08:40.469 --> 01:08:41.629
Ja, danke für die Einladung.

01:08:42.369 --> 01:08:46.409
Gerne, genau. Und wir wiederholen das. Wir wissen noch nicht wann und zu welchem

01:08:46.409 --> 01:08:48.829
Thema, aber wir wissen, es wird passieren.

01:08:49.909 --> 01:08:54.669
Gerne. Solange viele liebe Grüße nach Berlin. Ja. Auch an die Mozilla-Mannschaft.

01:08:55.649 --> 01:08:59.749
Danke. Richtig aus. Grüße nach Düsseldorf und an deine Mannschaft.

01:09:00.189 --> 01:09:03.129
Ja, danke. Und auch an die Zuhörer. Danke fürs Zuhören.

01:09:04.449 --> 01:09:09.609
Dann bis nächste Woche, würde ich sagen. Danke fürs Zuhören. Macht's gut. Tschüss.

