Stranger Than Usual

Only in Florida

Nur in Florida: Dort sollen jetzt Maskenmandate an Schulen verboten werden. Um „Rechte der Eltern zu schützen“.

Dass damit die ganzen vernünftigeren Eltern ihres Rechts auf körperliche Unversehrtheit beraubt werden, ganz zu schweigen von den Kindern? Egal.

Ist natürlich politisch. Weil es vernünftige, wissenschaftlich belegte Gründe gibt, etwas zu tun, dann sind die Republikaner ja schon einmal prinzipiell dagegen. Und wenn man damit die Demokraten ärgern kann, um so besser.

Auf der Suche nach Weithalsflaschen

Ich will Weithalsflaschen online kaufen. Man kann gut losen Tee darin aufbewahren und sie sehen schlicht und elegant aus.

„Mache ich eine Sammelbestellung mit Freunden und Familie“, habe ich mir Gedacht. Da gibt es ja noch ein paar, von denen ich weiß, dass sie auch noch welche haben wollen.

Also Mails herumgeschickt insgesamt vier Personen (inkl. mir selbst), wir bekommen sogar ein bisschen Mengenrabatt. Außerdem gibt es noch zwei Sonderwünsche: ein 1l-Becherglas (idealerweise die hohe Form) und ein Deckel ohne Glas, als Ersatz.

Auch einen Online-Laden gefunden, der alles hat. Vom Becherglas leider nur die niedrige Variante, aber was soll man machen. Alles in den Warenkorb, Bestellung absch…

Bitte geben Sie eine gültige E-Mail-Adresse an.

Fuck you. Die E-Mail-Adresse ist richtig geschrieben. Eine kurze Meldung an den Support (dort wird meine E-Mail-Adresse klaglos akzeptiert), aber bis so etwas gefixt ist können Wochen vergehen. Monate. Jahre. Äonen. Wenn es überhaupt gefixt wird.

Also schon mal zum nächsten Shop. Shop #2 hat keine Deckel ohne Flaschen. Shop #3 ist der gleiche Shop wie Shop #2, gleiche Software, gleiche Firma dahinter, nur ein anderer Name und ein anderes Logo.

Shop #4 ist teurer als die anderen Shops.

Shop #5 und #6 haben keine Weithalsflaschen aus Glas.

Shop #7 hat zwar als bisher einziger die hohe Form der 1l-Bechergläser, aber auch keine losen Deckel.

So ein Scheiß passiert mir ständig, wenn ich online einkaufen will. Seien es Bahntickets oder Raspberry-PI-Zubehör. Oder Online-Buchungen von Hotels.

Und meine Therapeutin fragt mich immer, warum ich so ungerne online einkaufe. Der Grund ist, weil ich stundenlang daran sitze, zu versuchen, etwas zu kaufen, nur um dann um 23:00 Uhr wütende Blogposts darüber zu schreiben, dass es nicht ging.

Den Boten erschießen

Man hört es ja ständig. Es gab wieder „Cyber-Angriffe“. Die meisten dieser sogenannten Angriffe sind einfach nur Malwarebefall. Manche sind auch gezielter Malwarebefall. Auf jeden Fall ist dann mal hier ein Krankenhaus ausgefallen, da ein Gericht, dann ein großer Zeitungsverlag… Warum ist das so? Warum ist so viel Software unsicher?

Nun, ein Grund ist, dass wir nicht besonders sensibel mit den Leuten umgehen, die sich auf IT-Sicherheit spezialisiert haben. Wie zum Beispiel einer Hackerin, die in Wahlkampfapps von CDU und CSU im März schwerwiegende Sicherheitslücken entdeckt hatte, und die auch ordentlich gemeldet, so dass sie behoben werden konnten. Und jetzt hat diese Hackerin einen Strafantrag am Hals.

Um es einmal zu betonen: Diese Frau hat der CDU geholfen. Unentgeltlich. Sie hat mit der Sicherheitslücke keinen Mist gebaut. Sie hat sie gemeldet und damit geholfen, die Software besser zu machen. Und dafür soll sie jetzt verklagt werden. Aber was soll man schon erwarten von einem Staat, der Sicherheitslücke lieber kaufen, geheimhalten und Nutzen will, um unter dem Begriff „Hackback“ zurückhacken zu können, wenn mal wieder ein Krankenhaus von Malware befallen wird.

Wen man da zurückhacken soll ist ungeklärt, und ignoriert wird auch, dass man vielleicht gar keinen Malwarebefall hätte, wenn man Lücken beheben würde anstatt sie geheimzuhalten. Aber ich schweife ab.

Es gibt auch einen riesigen Haufen Softwareentwickler, die sich nicht wie kleine Kinder verhalten, wenn man sie auf Sicherheitslücken hinweist. Trotzdem gibt es überall Lücken. Warum?

Meine Hypothese ist: Es ist uns, als Gesellschaft nicht wichtig genug. Es ist denen, die die Entscheidungen dazu treffen, nicht wichtig genug. Wenn es uns wichtig genug wäre, würden wir mehr für die Sicherheit tun. Und das heißt auch, Geld in die Hand nehmen.

Kurzfristig kostet es weniger Geld, unsichere Software zu entwickeln. Kurzfristig kostet es Geld, Software rigoros zu testen. Software ohne oder mit wenig Gedanken an Sicherheit zu bauen ist schneller. Weniger Sicherheitsvorkehrungen bedeutet, dass die Software bequemer zu benutzen ist (wer hat nicht schon einmal davon geträumt, sich nicht ständig um Passwörter kümmern zu müssen?).

Wenn ein Entscheidungsträger die Wahl hat, eine Million Euro mehr zu bezahlen, um die Software sicherer zu machen, oder Hunderttausend Euro für eine Marketingkampagne auszugeben, wie wichtig ihnen Sicherheit sei, und das bei ihnen Datenschutz an erster Stelle stünde, dann ist die Entscheidung klar.

Das Schema ist: Der Entscheidungsträger hat nur wenig unter dieser Entscheidung zu leiden. Das Produkt wird gekauft, und bis herauskommt, wie unsicher ist, ist schon das Nachfolgeprodukt auf dem Markt. Enttäuschte Kunden kann man ja mit ein bisschen Marketing und Bequemlichkeit davon überzeugen, bei der eigenen Marke zu bleiben. Und manchmal ist der Kunde ja auch gar nicht geschädigt, oder kriegt es nicht mit. Was schert es den, wenn das Dutzend Internet-of-Things-Geräte heimlich DoS-Angriffe fährt, Spam verschickt, oder Bitcoins schürft? Den erhöhten Stromverbrauch kriegt der doch garnicht mit. Tragedy of the commons.

Also kein Grund, etwas anders zu machen. Das ist wie bei anderen großen Problemen: Es kümmert die Entscheidungsträger einfach nicht. Der Abgeordnete, der über ALG-II-Sätze abstimmt, muss ja nicht selber davon leben. Den Flug von München nach Berlin? Bequemer als die Bahn, das bisschen Klimawandel mehr oder weniger macht den Braten auch nicht fett.

Wenn du ein Krankenhaus betreibst, möchtest du nicht großartig in IT-Sicherheit investieren. Das hat ja im Alltag keinen erkennbaren Nutzen. Meistens geht es gut. Absicherung gegen Hochwasser? Meistens ist kein Hochwasser, aber man kann das Feld viel einfacher bestellen und viel einfacher auf dem Fluss fahren, wenn der Fluss gerade ist. There is no glory in prevention. So lange nichts passiert, sind Investitionen in Sicherheit herausgeworfenes Geld, also spart man hier.

Und dann geht was schief. Aber dann ist es zu spät. Dann ist das Krankenhaus für Tage außer Betrieb. Dann wird dein Haus weggespült.

Was kann man machen? Vielleicht sollte man es so richtig teuer machen, unsichere Software auszuliefern. Indem man zum Beispiel Hersteller für Sicherheitslücken haftbar macht. Wenn das Krankenhaus zum Beispiel tagelang ausfällt, musst der Ausfall halt bezahlt werden. Was meint ihr, wie viel Geld man dann in saubere Entwicklung und Sicherheitstests stecken würde? Wenn der von dir vermarktete smarte Fön Spam verschickt, musst du halt Pro Spam-Mail eine Strafe zahlen. Wenn dein smarter Vibrator intime Kundenfotos offen ins Netz stellt, musst du halt eine deftige Entschädigung zahlen. Und den Kaufpreis erstatten.

Bei anderer Technik gibt es ja auch Entschädigungszahlen oder Strafen, wenn sie durch vermeidbare Fehler Menschen schaden. Warum nicht auch bei Sicherheitslücken?

Ich werde es euch sagen: Es ist uns nicht wichtig genug.

Quantenkryptographie auf tagesschau.de

Vor ein paar Tagen habe ich diesen Artikel auf tagesschau.de gelesen. Da geht es darum, dass die erste „quantengesicherte“ Videokonferenz vor Kurzem in Bonn getestet wurde.

Dabei wird ein Quantenschlüsselaustausch-Verfahren verwendet. Nun versteht mich bitte nicht falsch, ich halte Quantenkryptografie für eine coole Sache, auch wenn der Artikel zugibt, dass die Technik noch nicht praxisreis ist. Aber einige Aussagen in diesem Artikel sind schlichtweg falsch.

Da ist zum einen die Aussage „Nicht einmal das Kanzlerinnen-Handy ist abhörsicher“. Das mag stimmen, aber wenn das so ist, dann liegt das nicht daran, dass wir keine sicheren Verschlüsselungsverfahren haben. Richtig eingesetzt kann z.B. der symmetrische Advanced Encryption Standard (AES) nicht geknackt werden. Nicht mit aller Rechenleistung, die die Menschheit jetzt oder in absehbarer Zukunft aufbringen kann.

Außerdem wird über bisherige Verschlüsselungssysteme gesagt, dass die „von großen Rechnern allerdings bald geknackt werden können“. Ich vermute mal, das ist eine Anspielung an Quantencomputer. Herkömmliche Computer sind sehr lange davon entfernt, heute gängige symmetrische oder asymmetrische Verschlüsselunsverfahren zu knacken. Ich bin kein Experte, was Quantencomputer angeht, aber so wie ich das verstanden habe, könnten gängige asymmetrische Verschlüsselungsverfahren geknackt werden, deswegen wird auch schon an Verfahren gearbeitet, die von einem Quantencomputer nicht geknackt werden können.

Oh, und der Quantenschlüsselaustausch braucht auch einen „authentifizierten Kanal“. Was bedeutet das in der Praxis? Klassische asymmetrische Kryptografie.

Die falschen Probleme lösen

Wenn das Kanzlerinnen-Handy also nicht abhörsicher ist, wie behauptet, so liegt das nicht an den eingesetzten Verschlüsselungsverfahren. Richtig eingesetzt sind die nämlich sicher. Das Problem liegt darin, wie sie angewandt werden und was sonst noch auf dem System zu finden ist. Das Problem sind unsichere Implementierungen.

Warum wollen Geheimdienste, Polizei und Politiker den Staatstrojaner? Warum werden Hintertüren zu verschlüsselter Kommunikation gefordert? Warum will der Staat bisher unbekannte Sicherheitslücken kaufen, um sie statt sie zu beheben als Waffe auszubewahren?

Die Antwort ist einfach: Weil man die Verschlüsselung selbst nicht angreifen kann, die ist sicher. Und wenn wir den Kern der Verschlüsselung auf Quantenkryptografie umstellen, so ändert sich nichts daran, dass die Umgebung, in der die Quantenkryptografie läuft, unsicher ist, und somit angegriffen werden kann.

Ich hatte ja vor Kurzem einen Rant geschrieben, warum wir keine gute IT-Sicherheit haben. Meine Antwort war: Es ist uns nicht wichtig genug. Das ist ein gesellschaftliches Problem. Quantenkryptografie auf dieses Problem zu werfen ist der Versuch, ein gesellschaftliches Problem mit technischen Mitteln zu lösen. Das funktioniert erfahrungsgemäß nicht.

Ich will nicht sagen, dass dieser Quantenschlüsselaustausch keine coole Idee ist, ich kenne mich nicht gut genug damit aus (oder mit Quantencomputern, oder mit Verschlüsselung im Allgemeinen). Ich kann mir schon vorstellen, dass einige Probleme damit gelöst werden können. Aber das Kernproblem ist nicht die Verschlüsselung, sondern der Kram drumherum. Solange der nicht sicher ist, bringt uns auch Quantenschlüsselaustausch nichts.

Snowden mag rust

Ein lesenswerter Artikel, den ich schon vor Wochen hier verlinken wollte, ist dieser Artikel von Edward Snowden über den Einsatz von NSOs Spyware Pegasus, dem Pegasus Project nach dem die Spyware dazu benutzt wird, um Journalisten und politische Gegner zu überwachen.

Nun, das ist nichts Neues, und andere haben schon viel dazu geschrieben. Dass Firmen in demokratischen Ländern ihre Spyware an Unterdrückerstaaten verkaufen, die damit unliebsame Presse und politische Gegner unterdrücken, ist bekannt. Ich…

Ich könnte stundenlang ranten und es würde nichts bringen. Wir haben selber ja jetzt Staatstrojaner, und ich prophezeie, dass es irgendwann in den nächsten zehn Jahren einen Skandal geben wird, weil die gegen Journalisten, Aktivisten oder Anwälte unter Schweigepflicht eingesetzt wurden. Dann geht das ein paar Wochen durch die Presse, es heißt, dass hier etwas geändert werden muss, und nachher geht alles so weiter wie vorher.

Also komme ich zu meinem eigentlichen Punkt: Snowden schreibt folgendes:

The vast majority of vulnerabilities that are later discovered and exploited by the Insecurity Industry are introduced, for technical reasons related to how a computer keeps track of what it’s supposed to be doing, at the exact time the code is written, which makes choosing a safer language a crucial protection... and yet it’s one that few ever undertake.

Der Link ist so im Original. Also Snowden benutzt nie das Wort „rust“. Aber er verlinkt auf die Sprache als das Beispiel für eine sichere Sprache.

Unicode code point vs. scalar value

Mit kommt in letzter Zeit immer wieder der Begriff „unicode scalar value“ unter. Zum Beispiel in der rust-Dokumentation zum Typ char:

The char type represents a single character. More specifically, since ‘character’ isn’t a well-defined concept in Unicode, char is a Unicode scalar value’, which is similar to, but not the same as, a ‘Unicode code point’.

Hmm… aber was ist denn da nun der Unterschied? Zum code point steht, wenn man dem Link folgt:

Any value in the Unicode codespace; that is, the range of integers from 0 to 10FFFF. […]

Ok, das deckt sich soweit mit meinen Erwartungen. Und zu scalar value?

Any Unicode code point except high-surrogate and low-surrogate code points. In other words, the ranges of integers 0 to D7FF and E000 to 10FFFF inclusive.

Das ist schon weniger klar. Was sind denn diese high-surrogate und low-surrogate code points? Fehlt einem irgendwas, wenn man einen char-Typ hat, der die nicht enthält? Kann rust vielleicht mit seinem char nicht alles darstellen, was unicode zu bieten hat? (Strings sollten kein Problem sein, oder? schließlich sind Strings in rust immer UTF-8-codiert, und UTF-8 kann ja alle code points darstellen, richtig?)

Why bother?

Warum ist mir das jetzt wichtig? Weil ich in Kürze einen kleinen Vortrag u.a. über gotchas im Zusammenhang mit unicode halten will. Aber wie soll mir das gelingen, wenn ich nicht einmal den Unterschied zwischen einem code point und einem scalar value kenne?

Surrogates

Ok, also was hat es mit diesen oben erwähnten surrogates auf sich? Im Unicode-Glossar steht direkt unter „Code Point“ „Code Point Type“:

Any of the seven fundamental classes of code points in the standard: Graphic, Format, Control, Private-Use, Surrogate, Noncharacter, Reserved. (See definition D10a in Section 3.4, Characters and Encoding.)

Aha! Also sind Surrogate Code Points eine spezielle Unterart der Code Points? Folgen wir mal dem Link. clicKscroll scroll scroll … da ist es:

High-surrogate code point: A Unicode code point in the range U+D800 to U+DBFF.

High-surrogate code unit: A 16-bit code unit in the range D800 to DBFF, used in UTF-16 as the leading code unit of a surrogate pair.

Low-surrogate code point: A Unicode code point in the range U+DC00 to U+DFFF.

Low-surrogate code unit: A 16-bit code unit in the range DC00 to DFFF, used in UTF-16 as the trailing code unit of a surrogate pair.

  • High-surrogate and low-surrogate code points are designated only for that use.
  • High-surrogate and low-surrogate code units are used only in the context of the UTF-16 character encoding form.

Nun weiß ja jedes Kind, dass UTF-16 aus 16-Bit-Einheiten („code units“) besteht. Was viele allerdings gerne ignorieren (hier kommt wieder mein unicode-gotcha-Vortrag ins Spiel) ist, dass ein code point in UTF-16 aus einem oder zwei dieser code units bestehen kann. Man muss also irgendwie erkennen, dass es nach der ersten code unit noch weitergeht.

Nun hätte ich ja erwartet, dass sie das hier so ähnlich wie bei UTF-8 machen (das erkläre ich jetzt nicht, aber auf Wikipedia ist es recht gut dargestellt). Machen sie aber nicht. Vermutlich aus historischen Gründen.

Bei code points, die durch zwei 16-bit code units dargestellt werden, beginnt der höherwertige (also „High-Surrogate“) immer mit dem Binärstring 110110 und der niederwertige mit dem Binärstring 110111. Code points, die durch nur eine 16-bit code unit dargestellt werden, beginnen nie mit einem dieser Bitsrings. Man kann also (ebenso wie bei UTF-8 immer unterscheiden ob man eine Codeeinheit hat, die für sich alleine steht, oder ob sie Teil eines code points ist, der in mehreren Einheiten encodiert wird. Man kann sogar erkennen, ob man sich am Anfang eines code points befindet oder nicht. Praktisch.

Aber warum die code points?

So, das ist geklärt. Aber warum gibt es eigene code points für diese Surrogates? Die Surrogates sind doch etwas encoding-spezifisches! Bei UTF-8 braucht man so etwas doch auch nicht. Scrollt man im Unicode-Standard noch ein bisschen weiter nach unten, steht da auch, dass die drei unicode encodings UTF-8, UTF-16 und UTF-32 alle nur die unicode scalar values codieren, nie die surrogate code points.

Also warum der Kram? Welchen Grund hat es, den Standard so zu bauen? man könnte das UTF-16 encoding doch genau so gut ohne diese Surrogate-Code-Points bauen, man kann die surrogate-code-points ja sogar theoretisch in UTF-16 codieren (wobei das, wie gesagt, nicht gültig wäre, weil ja nur scalar values encodiert werden).

Einige Kommentare an verschiedenen Stellen haben mich auf UCS-2. Davon hatte ich vorher schon einmal gehört, das war so etwas wieder unicode-Vorgänger, als man glaubte, 2¹⁶ code points würden locker ausreichen. Im Gegensatz zu UTF-16 hat in UCS-2 jeder code point exact 16 bit Länge.

In dem Wikipedia-Artikel steht:

Der UCS wird entwickelt von ISO/IEC/JTC1/SC2/WG2. Die Gruppe arbeitet sehr eng mit dem Unicode-Konsortium zusammen, das die Standards ständig in neuen Versionen synchronisiert. Aufgrund dessen sind alle Kodierungen aus Gründen der Interoperabilität beschränkt auf die bei Unicode erlaubten 1.112.064 Zeichen (= 220+216, abzüglich 211 = 2048 Surrogate von UTF-16), nämlich von U+00000 bis U+0D7FF sowie von U+0E000 bis U+10FFFF.

Es ist also irgendein Rückwärtskompatibilitätskrams, damit man UTF-16 nicht mit UCS-2 verwechseln kann.

TL;DR

  • für beliebige Unicode-Texte braucht man nicht alle code points, sondern nur die Unicode scalar values
  • die übrigen Werte sehen so aus wie die Werte, die die code units in UTF-16 surrogate pairs annehmen können
  • das ist vermutlich aus Rückwärtskompatibilitätsgründen drin.

Habe ich schon einmal erwähnt, dass ich UTF-8 für das bessere Encoding halte? Und siehe da, das hat eine Rückwärtskompatibilität mit ASCII und man muss überhaupt keine code points für das Encoding reservieren und braucht auch nicht auf byte order zu achten.

Nicht angetroffen

Ich habe langsam keinen Bock mehr.

Dieses Jahr habe ich deutlich mehr Pakete und Päckchen bestellt bzw. geschickt bekommen als sonst. Und früher habe ich die mir immer ins Büro liefern lassen und sie von da aus nach Hause genommen, weil ich ja sowieso zu Hause nicht anzutreffen war.

Nun bin ich aber jeden Tag praktisch immer da. Und trotzdem kommt kaum ein Paket an mich direkt bei mir an. Irgendwie war ich nie anzutreffen, obwohl ich fucking zu Hause war. Und ich weiß, dass meine Klingel funktioniert, weil Pakete für Nachbarn sehr gut bei mir abgegeben werden können.

Die nicht abgegebenen Pakete kommen entweder zu Nachbarn, manchmal auch zu einer Abholstelle. Manchmal kriege ich dafür Zettelin den Briefkasten, manchmal nicht. Wenn ich ein Paket erwarte, erfahre ich normalerweise nur auf Anfrage, dass es angekommen ist. Bzw. bei Nachbarn abgegeben. Es wird aber seltsamerweise nie erwähnt, bei welcher Nachbarwohnung, ich muss also an mehreren Türen klingeln.

Zwei besonders dämliche Fälle: meine Firma hat mir ein Osterpaket geschickt. Mit Schokohasen und so. Ohne es anzukündigen, sollte eine Überraschung sein. Und da sie wussten, das ich zu Ostern im Urlaub war, haben sie es extra später abgeschickt.

Der Paketbote hat nicht einmal einen Zettel hinterlassen und das Paket zur Abholstation gebracht. Wo ich es natürlich nicht abgeholt habe, weil ich ja nicht wusste, dass es das Paket überhaupt gibt. Irgendwann bekam ich dann eine Anfrage vom Office, warum denn das Paket zurückgekommen sei. Beim zweiten Zustellungsversuch hat es dann geklappt.

Der zweite dämliche Fall: Das Paket (in diesem Fall wirklich ein Paket und nicht nur ein Päckchen) wurde angekündigt. Ich war natürlich da, wie immer. Es klingelt. Ich betätige den Türöffner. Horche auf den Flur. Nichts. Gehe die Treppen runter. Niemand da. Ich gehe wieder nach oben. Schaue aus dem Fenster. Gelber DHL-Wagen gegenüber, kein Paketbote weit und breit.

Zehn Minuten, nachdem ich dem Paketboten die fucking Tür geöffnet habe, kriege ich eine E-Mail, dass ich nicht dagewesen sei und ich das Paket am nächsten Tag abholen könne.

Das hat dann das Fass zum Überlaufen gebracht und ich habe eine Anfrage an den DHL-Kundendienst gestellt, was das denn solle. Ausschnitt aus der Antwort:

Es tut uns sehr leid, dass Sie mit unserer Zustellung nicht zufrieden sind. Natürlich nehmen wir Ihr Feedback sehr ernst und haben deshalb die Kollegen vor Ort darüber informiert. Wir hoffen, Sie in Zukunft wieder von unserer Qualität und Zuverlässigkeit überzeugen zu können.

Unser Tipp:
Um Ihnen künftig den Weg in die Filiale zu ersparen, können wir Ihre Sendungen gerne an einem von Ihnen gewählten, sicheren Ort ablegen. Bestimmen Sie dafür einfach einen Ablageort kostenfrei unter dhl.de/ablageort . Sollten Sie keinen geeigneten Ablageort zu Hause haben, können Sie Ihre Pakete alternativ auch an eine unserer vielen Packstationen in Ihrer Nähe senden und somit Ihre Pakete rund um die Uhr abholen.

Also diesen Tipp können die sich mal sonstwohin schieben. Ich bin ja da. Ich brauche keinen Ablageort. Hatte ich denen in der Mail ja auch erklärt. Von mir aus können die Paketboten ja auch gerne einen Infektionssicherheitsabstand halten wenn sie das Paket liefern. Aber einen Ablageort, der nicht in jedermanns Blickfeld liegt, kann ich an meinem Wohnort nicht finden.

Was die Zusicherung angeht, dass sie mein Feedback ernst nehmen, wollte ich ihnen eine Chance geben. Aber drei Mal dürft ihr raten, was ich heute für einen gelben Zettel aus dem Briefkasten fischen durfte. Naja, immerhin gab es einen gelben Zettel, und er war in meinem Briefkasten. Zu Hause war ich trotzdem, als ich angeblich nicht anzutreffen war.

Update

Ach ja, falls jemand das Supportformular nicht findet, weil DHL das wirklich gut versteckt hat: hier ist das Supportformular.

Die dümmste Ausrede des Jahres

Ein kurzer rant. Es geht um die App Scoolio. Wohl so eine App, die sich an Schüler richtet, um den Schulalltag zu erleichtern. Kostenlos, was heißt, dass die Schüler das Produkt sind.

Diese App hat sich zerforschung jetzt angeschaut. Mit von der Partie war auch die Hackerin, die vor ein paar Monaten die Sicherheitslücke in der CDU/CSU-Wahlapp gefunden hat.

Ergebnis, kurz zusammengefasst: Es werden zuhauf Daten über die Schüler abgegriffen und es gibt ein paar gravierende Sicherheitslücken, über die man Daten über alle möglichen Schüler abgreifen oder teilweise sogar verändern kann.

Den Vogel abgeschossen hat für mich aber das hier:

Scoolio gibt es jetzt seit über fünf Jahren. Als wir den Geschäftsführer der Sicherheitslücke wegen vor einigen Wochen angerufen haben, sagte er, dass scoolio als Startup nicht die Möglichkeiten hätte, sichere Software zu bauen.

Das ist erstens nicht richtig, zweitens falsch und drittens ethisch fragwürdig.

Ist es für ein Startup zu schwierig, sichere Software zu bauen? Nein. Zumindest die Grundlagen sollte jedes Startup beherrschen. Man kann vielleicht keine Entwickler von Weltrang in sein Projekt ziehen, aber grundlegende Sicherheitsmaßnahmen wie das Verhindern unberechtigter Zugriffe ist innerhalb der Möglichkeiten jedes Softwareentwicklers. Man muss es nur wollen.

Aber angenommen, sie könnten es tatsächlich nicht. Dann haben sie meiner Meinung nach kein Recht, diese Software groß zu vermarkten. Ein Vergleich: Ein fünf Jahre altes Bauunternehmen baut ein Haus. Beim Bau wird geschlampt, und ein Jahr nach dem Bau stürzt das Haus ein und alle Bewohner sterben.

Würde sich da jetzt der Geschäftsführer des Bauunternehmens hinstellen und sagen, dass man als Startup nicht die Möglichkeit hat, stabile Häuser zu bauen? Und wenn ja, wie sollte man darauf reagieren?

Ich würde so jemanden nie wieder ein Haus bauen lassen.

Advent of Code steht vor der Tür

Wir schon in den vorherigen Jahren wird es auch dieses Jahr wieder einen Advent of Code geben, der, wie es sich für einen Adventskalender gehört, am 1. Dezember anfängt.

Ich vermute mal, dass wie immer die ersten Aufgaben simpel sind, dann aber sehr schnell interessanter werden. Ich mache wieder mit, natürlich in rust, habe mir aber wieder vorgenommen, aufzuhören, wenn es mir zu stressig wird. Weil das in den letzten Jahren ja so gut geklappt hat.

Dieses Mal habe ich weniger Urlaub, deswegen auch eine höhere Chance, dass ich einfach notgedrungen irgendwann aufgeben muss, jeden Tag mitzukommen.

Ich kann angehenden aber auch erfahrenen Programmierern nur empfehlen, teilzunehmen. Es gibt immer eine schräge Hintergrundgeschichte, viele interessante Puzzle und es ist meist ein befriedigendes Gefühl, eines der Puzzle gelöst zu haben.

Und wem alles zu einfach ist, der kann sich auch gerne kleine Herausforderungen setzen. Wie z.B. alles in einer Programmiersprache zu lösen, die man parallel lernt. Oder in einer esoterischen Programmiersprache. Oder in MS Excel. Oder man kann, wenn es zum Puzzle passt, schöne Animationen dazu bauen.

Versucht nur nicht an einem Tag unter die ersten 100 erfolgreichen Lösungen zu kommen. Das ist fast unmöglich und den Ärger nicht wert.

Submarine of Code

Wie schon angekündigt hat der Advent of Code wieder begonnen.

Dieses Jahr hat irgendein dusseliger Elf die Schlüssel zu Santas Schlitten ins Meer fallen lassen, und jetzt ist man mit einem U-Boot unterwegs, sie wiederzufinden.

Natürlich gibt es Hindernisse. Verwirrende Sonarausgaben, fehlende Bedienungsanleitungen für die Steuerung, Lebenserhaltungssysteme, Bingospielende Riesenkalmare, Raucher (nein, nicht Personen, sondern die Unterwasservulkane, Laternenfische in großer Anzahl und Pottwale machen einem das Leben schwer.

Meine Lösungen kann man hier finden. Sie sind, wie bisher auch, in Rust geschrieben. Die Qualität ist gemischt. Gestern habe ich schnell eine saubere Lösung hingekriegt, die ich (mit einem kleinen Update von u32 auf u64) auch für den zweiten Teil verwenden konnte.

Meine heutige Lösung ist nicht so schön sondern brute-forced die Lösung, was aber aufgrund der Problemgröße auch in Sekundenbruchteilen fertig ist. Ich mache mir selten die Mühe, eine funktionierende Lösung noch einmal zu überarbeiten, wenn mir danach etwas besseres einfällt.

Meine Lösungen zu 2019 und zu 2020 sind da auch zu finden. Ich habe auch endlich Zeit gefunden, die Lösungen von 2018 zu mergen. Die hatte ich nämlich in ein Repo pro Tag gesteckt, und dementsprechend nicht hochgeladen. Ein Repo für das ganze Event ist deutlich handhabbarer.

Vollständig sind nur meine Lösungen zu 2020, bei denen davor habe ich irgendwann aus Zeitgründen aufgehört.

Unbedingt erwähnen möchte ich noch den Twitteraccount von Gary Grady. Der macht immer nette Comics zu jedem Tag.

Synchronisierung in zellulären Automaten

Heute, Tag 11 des Advent of Code 2021, ging es um Dumbo-Oktopusse, die in regelmäßigen Abständen aufleuchten. Ob es tatsächlich solche Oktopusse gibt, weiß ich nicht, aber das Puzzle bezog sich auf einen zellulären Automaten, der simuliert, wann die Oktopusse leuchten.

Dabei beeinflusst jeder Oktopus, der aufleuchtet, andere Oktopusse in der Nachbarschaft. In Teil zwei stellt sich heraus, dass das dazu führt, dass die Oktopusse irgendwann alle synchron aufleuchten.

Lustigerweise ist das etwas, was auch in der Natur vorkommt, auf viele verschiedene Arten und Weisen. Wichtig ist nur, dass etwas periodisch passiert und Individuen einen (wenn auch nur leichten) Einfluss auf die anderen Individuen haben.

Das synchrone Aufleuchten zum Beispiel kann bei Glühwürmchen beobachtet werden. Es gibt dazu ein schönes Video auf Youtube, dass dieses Verhalten erklärt und einige schöne Beispiele darstellt.

log4j-Sicherheitslücke

Vorgestern kam ja diese Sicherheitslücke auf, die gestern überall die Runde machte. Kurz zusammengefasst: Wenn man bestimmte strings mit log4j logged, dann wird code von einer (potentiell vom Angreifer kontrollierten) website geladen und ausgeführt.

Das ist natürlich ein totaler WTF-Bug: Warum sollte ein Logging-Framework überhaupt den Inhalt der Logtexte parsen, anstatt einfach nur zu prüfen, ob das gültiges encoding ist? Und warum sollte es willkürliche URLs aufrufen und den Code dort ausführen?

Meine Vermutung: Featuritis. „Was können wir noch für tolle Features einbauen? Vielleicht JNDI-support? Braucht zwar niemand, aber damit haben wir ein Feature, das sonst niemand hat! What could possibly go wrong?

Jedenfalls ist log4j das logging-Framework in Java. Wenn du einen Java-basierten Webservice betreibst, benutzt du vermutlich log4j. In einem meiner alten Projekte haben wir auch log4j verwendet, auch wenn wir zum eigentlichen loggen eine andere Bibliothek nutzten, die log4j nur als Backend verwendet.

Kurz: log4j ist überall. Zum Beispiel irgendwo im tech-stack unserer beliebten Ingenuity-Helikopterdrohne auf dem Mars. Und der Exploit ist nicht einmal schwierig durchzuführen.

Selbst minecraft ist betroffen. Als mir das klar wurde, habe ich erst einmal meinen Server heruntergefahren und darf den jetzt fixen. Glücklicherweise wurde gestern auch direkt ein Fix bereitgestellt.

Jetzt muss ich natürlich den Server ein bisschen im Auge behalten. Der Minecraftserver lief natürlich mit begrenzten Rechten, trotzdem: Wer einen Spamversandt oder einen bitcoin-Miner auf meinem Server installieren will, dem reicht das.

Also: fleißig Updates installieren (am besten gestern).

Advent of Code 2021 Rückblick

SPOILER ALERT: Wer sich zur Story oder zu den Lösungen des Advent of Code 2021 nicht spoilern möchte, sollte nicht weiterlesen.

Der Advent of Code 2021 ist vorbei, und zum zweiten Mal habe ich es geschafft, alle Puzzle zu lösen. Am Ende wurden die Puzzle wieder interessanter, also hier einige meiner Highlights der letzten Tage:

Tag 15 oder: Ich habe noch nie Dijkstra produktiv implementiert.

Tag 15 war eine relativ direkte kürzeste-Pfade-Suche mit positiven Kantenlängen. Teil zwei war einfach nur eine größere Variante von Teil 1, was bedeutete, dass man wirklich auf seinen Algorithmus und seine Datenstrukturen aufpassen sollte, weil das Ding sonst ewig rechnet.

Ich habe den Dijkstra-Algorithmus verwendet, den ich tatsächlich noch mehr oder weniger auswendig herunterschreiben konnte (die „weniger auswendig“-Teile konnte ich mir rekonstruieren aus dem was ich noch wusste.

Dieser Algorithmus ist einer, den ich an der Uni in mindestens drei verschiedenen Vorlesungen gelernt habe, aber bisher noch nie in Produktivcode anwenden musst. Also mal ganz nett, ihn wenigstens für ein Puzzle verwenden zu können.

Tag 16: Krumme Bit-Werte

Tag 16 bestand darin, irgendein Kommunikationsprotokoll, dass die Weihnachtselfen entwickelt haben, zu implementieren. Es war ein bisschen nervig zu implementieren, weil viele Blöcke vorkamen, die nicht nicht an 8-bit aligned waren. Wenn man das Parsen erst einmal hatte, war es aber ganz einfach. Dementsprechend bestand Aufgabe 1 praktisch nur aus dem Parsen und Aufgabe 1 darin, etwas mit den geparseten Daten zu machen.

Tag 17: Kurvendiskussionen

In Tag 17 musste man Bahnen berechnen, in denen man eine Sonde abschießt, damit sie in einem Tiefseegraben landet.

Die Gemeinheit: Die Sonde bewegt sich in diskreten Schritten, schießt also gerne auch mal über das Ziel hinaus.

Dieses war das einzige Puzzle, dass ich nicht am Tag der Veröffentlichung durchgekriegt habe, was aber auch daran lag, dass ich den ganzen Tag zu tun hatte (inkl. einer Rollenspielrunde am Abend).

An sich ist die Simulation recht einfach, aber ich brauchte eine Weile um eine geeignete Obergrenze für die Startgeschwindigkeit festzulegen (Tipp: Die Flugkurve ist symmetrisch). In Teil zwei hatte ich dann einen dummen Bug, den ich um 1 Uhr nachts nicht mehr beheben konnte, deswegen war ich erst am nächsten Morgen fertig.

Tag 18: Mathehausaufgaben

An Tag 18 musste man die Hausaufgaben von ein paar Scheibenbäuchen erledigen.

Die haben ein, gelinde gesagt, außergewöhnliches Zahlensystem. Ich hätte zur Umsetzung eine andere Datenstruktur wählen sollen. Ich kriege ja immer kribbeln wenn ich sehe, wie Leute in ihren Lösungen direkt auf Strings arbeiten, aber in diesem Fall wäre das vermutlich eine einfachere Lösung gewesen.

Trotzdem, ich habe es hingekriegt, rekursive, verändernde Aufrufe auf derselben Datenstruktur in rust zu implementieren (mit einer Menge &mut, ohne, dass mir der Compiler das komplett um die Ohren gehauen hat.

Tag 19: Rotation und Translation

An Tag 19 musste man Sonden, die ihre eigene Position und Ausrichtung nicht kannten, mit Hilfe von Baken in dasselbe Koordinatensystem bringen. Es gab eine Menge Rotationen und Koordinatensystemverschiebungen, ich musste mir ein Koordinatensystem aus Lego bauen, weil meine rechte Hand irgendwann nicht mehr flexibel genug war um mir das Koordinatensystem zu veranschaulichen.

Ein Koordinatensystem aus LEGO Technik, mit farblich codierten Achsen

Ein doofer Fehler, den ich gemacht habe: Ich habe irgendwie aus der Beschreibung herausgelesen, dass das Koordinatensystem auch gespiegelt werden kann. Kann es nicht. Nur Rotationen (um jede Achse, aber nur in 90°-Schritten).

Das ganze Herumgehampel hat mich irgendwie an meine Masterarbeit erinnert, wo ich auch verschiedene Koordinatensysteme (eines Roboterarms) ineinander umrechnen musste.

Tag 20: Die Tiefsee: Unendliche Weiten

In Tag 20 musste man eine Bildaufnahme verbessern. Im Prinzip war das hier wieder ein zellulärer Automat. Mit einem Trick: Das Bild ist unendlich groß, und auch der Bereich, der nicht vom initialen Zustand beeinflusst wurde, verändert sich. Das muss man berücksichtigen.

Lustigerweise hatte ich daran schon gedacht, aber während ich noch einen anderen Bug in meinem Code behoben habe, hatte ich das wieder vergessen. Irgendwann ist es mir wieder eingefallen, und dann hatte ich auch die korrekte Lösung.

Tag 21: Würfelspiele

Teil 1 von Tag 21 war ziemlich straighforward. Teil 2 war interessanter. Im Prinzip musste man die Anzahl von Wegen berechnen, in denen jeweils einer von zwei Spielern gewinnt, wenn man mit dreiseitigen Würfeln würfelt. Die Zahlen werden recht schnell ziemlich hoch, der Trick hier ist: Der nächste Schritt im Spiel hängt nur vom aktuellen Zustand ab, nicht von allen vorherigen Zuständen. So kann man alle Wege, die zu einem speziellen Zustand führen, zusammenfassen und spart dem Computer eine Menge Arbeit und Speicherauslastung.

Doof nur, wenn man aus Versehen zwei Mal für Spieler 2 spielt, anstatt für jeden Spieler einmal (doofer Tippfehler). Trotzdem habe ich das Puzzle während einer Zugfahrt fertig gekriegt.

Tag 22: Quaderspiele

Bei Tag 22 musste man zählen, wie viele Zellen in einer 3D-Matrix „an“ sind, wenn man verschiedene Quader von Zellen (die sich überschneiden können) nacheinander an- oder ausschaltet.

Ich habe direkt die Lösung gebaut, bei der man die Überschneidungen zwischen den Quadern berücksichtigt, so dass man nicht jede Zelle einzeln zählen muss und mich dabei wie schon an Tag 20 in meiner nur mäßig ausgeprägten räumlichen Vorstellungskraft für eine Weile verheddert.

Dann habe ich festgestellt, dass der Suchraum für Teil 1 so klein ist, dass ich da auch jede Zelle einzeln betrachten könnte. Weil meine Lösung da aber schon fast fertig war, habe ich die fertig gemacht.

Teil zwei hatte dann wie zu erwarten einen Suchraum mit mehreren hunder Milliarden Zellen, was für mich kein Problem war, weil meine Lösung mit Quader-Überschneidungen hier tatsächlich auch gut funktionierte.

Tag 23: Amphipoden-Wohnungen

Tag 23 war wieder ein kürzeste-Pfade-Problem, für das ich wieder den Algorithmus von Dijkstra verwenden konnte. Dieses Mal war es nicht sofort offensichtlich, dass man das als kürzester-Pfad-Problem modellieren kann, aber es hat sehr gut funktioniert.

Teil zwei wäre eigentlich kein Problem gewesen, aber ich hatte dummerweise meine Datenstrukturen für die Knoten und Kanten des Graphen so gewählt, dass ich alles hätte noch einmal schreiben müssen.

Stattdessen habe ich dann erst einmal den Code von Teil 1 in mühevoller Kleinarbeit refaktorisiert (dabei bin ich ein bisschen mit rust generics amok gelaufen) und konnte dann Teil 2 recht schnell lösen.

Tag 24: Bitte Seriennummer eingeben

In Tag 24 musste man eine ALU implementieren. Oder auch nicht. Eigentlich musste man nur den größten akzeptierten Eingangswert einer Berechnung herausfinden.

Es war Heiligabend, und ich habe es nicht auf die Reihe gekriegt. Codeanalyse (des input-Programms) hat mich nur mäßig weit gebracht. Am Ende habe ich dann, mit ein paar Vereinfachungen aus der Codeanalyse, einen brute-force-Ansatz gewählt. Der hat knapp eine Minute gearbeitet (mit optimiertem rust-code), eine Menge Speicher verbraten aber am Ende das korrekte Ergebnis herausgegeben.

Teil zwei war wie Teil 1, nur mit der niedrigsten akzeptierten Eingabe. Selber Ansatz, selbe Laufzeit.

User-Agent von Chrome 100

Neulich habe ich diesen Artikel hier gelesen.

Darin geht es darum, dass Es wohl einige Websitebaukästen und ähnliches gibt, die mit Chrome 100 ernsthafte Probleme bekommen könnten, weil sie beim Parsen des User-Agent-Headers nicht beachten, dass die Browserversion dreistellig sein kann.

Dazu kann ich nur sagen: Kein Mitleid von mir. User-Agents sind notorisch unstandardisiert, praktisch jeder Browser behauptet, von Mozilla zu sein. Sich für irgendetwas auf den User-Agent zu verlassen, ist etwas wovon abgeraten wird

It's worth re-iterating: it's very rarely a good idea to use user agent sniffing. You can almost always find a better, more broadly compatible way to solve your problem!

Und wenn man es doch macht so sollte verdammt noch mal keine wichtige Funktion davon abhängen, dass der User-Agent korrekt geparsed wird. Das ist einfach nicht zuverlässig genug. Im Zweifelsfall einfach die Standardversion der Website ausliefern. Oder noch besser immer, für alle Browser die gleiche Version ausliefern. Danke.