12
Nov 22

Notizen zur Content Security Policy (CSP)

Vor einer Weile stolperte ich über Webbkoll, ein Tool der schwedischen NGO Dataskydd.net, mit dem man die Performance einer Webseite bzgl. Datenschutz und Datensicherheit prüfen kann1. Kann ja nicht schaden, dachte ich mir so - prüfte und stellte fest, das ich noch einiges verbessern konnte.

Wie man es halt gerne so macht, habe ich recht unbedarft sinnvoll klingende Content Security Policy Regeln in den Header und die .htaccess-Datei meines Blogs eingeführt. Danach war alles einigermaßen okay bewertet und ich war happy.

<Spongebob>Several months later</Spongebob>

Und dann stellte ich fest, dass es etwas zu sicher ist und ich die anderen Domains, die auf den Blog leiten vom Laden diverser Inhalte ausgeschlossen habe2.

Nun also auf in den Kampf. Oberflächlich betrachtet schien eine Freischaltung für die Domains geholfen zu haben. Ein Blick in die Developer-Konsole offenbart allerdings: da wird noch eine ganze Menge blockiert. Allerdings helfen die Fehlermeldungen in der Firefox-Konsole nicht wirklich weiter. Hier bietet Chrome ein paar mehr Infos:

Refused to apply inline style because it violates the following Content Security Policy directive

Die Verursacher sind gefunden: Inline-CSS bzw. -Scripte.

Und folgende Lösungen helfen gegen das Problem:

  • Aufweichen der Content Security Policy, und Hinzufügen von 'unsafe-inline' für script-src / style-src;
  • Hinzufügen von hash-Werten für jede Datei, die Inline-CSS oder JS ausführen darf;
  • Hinzufügen einem erlaubten Attributs ('nonce-'), welches in allen Inline-Elementen eingefügt wird;
  • oder alle Inline-Elemente auslagern in separate Dateien.

Da die CSP für frame-ancestors nicht über <meta> übermittelt werden kann, überlasse ich die CSP jetzt komplett der PHP-header()-Funktion:

header("Content-Security-Policy: default-src 'none'; [...] )

Aber so richtig klappt das nicht. Vllt. muss ich doch auf ein Plugin-Ausweichen, dass WordPress mit einer funktionierenden, besseren CSP ausstattet - und Multi-Domain-kompatibel ist.

  1. Googles CSP Evaluator ist auch ganz nützlich in dem Kontext []
  2. In gewisser weiße ironisch, dass netzgeschaedigt.de nur eine kaputte Version des Blogs anzeigte. []

12
Apr 20

Virtueller Spieleabend mit ZOOM-Annotations

Es gibt diverse Möglichkeiten miteinander einen Online-Spieleabend zu verbringen: Multiplayer-Spiele in all ihren Ausprägungen von Fortnite über World of Warcraft bis Quizduell, digitale Brettspiel-Communities1, oder den Tabletop Simulator.

Bild 1: Geteilter Bildschirm mit Qwixx-Zetteln aller Mitspieler*innen und Zweitmonitor mit Videos und Annotationsleiste

Eine Alternative ist es, im Rahmen einer Videokonferenz mit ZOOM das Annotationsfeature einzusetzen.

Aktivierung des Annotationsfeatures in ZOOM

Die Person, die den virtuellen Spieleabend hostet benötigt einen ZOOM-Account2. Alle anderen Teilnehmer können dann in das virtuelle Spielzimmer eingeladen werden3.

Um die Annotationsfunktion zu nutzen, muss diese erst in den ZOOM-Einstellungen im Bereich "In Meeting (Grundlagen)" aktiviert werden (Bild 2, lilafarbener Pfeil). Ebenfalls benötigt wird eine aktivierte Bildschirmübertragung.

Bild 2: Annotationsfunktion in den ZOOM-Einstellungen aktivieren

Das Whiteboard kann ebenfalls verwendet werden. Wir haben es bei unserem Spieleabend letztendlich gar nicht eingesetzt und direkt auf dem Desktop gezeichnet.

Wenn man das erste Mal in den Einstellung ist, sollte man die Gelegenheit nutzen um sich die Optionen einmal in Ruhe anzusehen und ggf. Funktionen deaktivieren, die man nicht verwenden möchte.

Wer mehr Hilfe bei der Verwendung von ZOOM benötigt, sollte sich auf jeden Fall einmal bei den umfangreichen Anleitungen der Firma vorbeischauen.

Welche Geräte benötigt man?

Für den besten Spielegenuss sollten alle Teilnehmer*innen an einem PC-/Laptop mit möglichst großem Monitor - noch besser an einem Rechner mit zwei Monitoren4 - sitzen. Bei kleineren Monitoren muss man, um die Spielfelder gut zu sehen u.U. die Videos aller Mitspieler*innen ausblenden, womit ein wenig der Gemeinschaft verloren geht.

Das Malen auf dem Desktop macht natürlich auf Geräten mit Eingabestiften am meisten Spaß, geht aber auch mit der Maus gut.

Spiele für virtuelle Spieleabende

Bisher habe ich drei Spiele virtuell ausprobiert - und es hat besser geklappt als ich mir dies vorgestellt habe:

Concept

Wir spielen eine vereinfachte, abgewandelte Version von Concept, in welcher wir nacheinander Begriffe mit Hilfe des Boards erklären, ohne dass wir großartig Punkte zählen. Für die digitale Variante muss der/die Besitzer*in des Spiels ein Foto des Spielebrettts schießen, die Legende erhält man bei Asmodee. Begriffe kann man sich entweder selbst ausdenken oder auf ein anderes Spiel zurückgreifen, was sich - zumindest in meiner Generation - in fast jedem Haushalt befindet: Tabu.

Die Person mit dem Foto des Spielbretts teilt seinen Bildschirm oder für mehr Privatsphäre nur das Programmfenster mit dem geöffneten Bild. Alle Mitspieler*innen starten dann die "Kommentier"-Funktion in der ZOOM-Meetingleiste (Bild 3).

Bild 3: Kommentieren in der ZOOM-Meeting-Leiste aktivieren

Dann kann die Person, die an der Reihe ist einen Begriff zu erklären, mit dem Zeichnen- (verschiedenen Farben) oder Stempeln-Tool (verschiedene Symbole) Haupt- und Nebenkonzepte markieren. Es gibt dabei eine kleine Zeitverzögerung und manchmal mussten wir die Aktualisierung durch eine eigene Annotation triggern. Wurde ein Begriff erraten kann der/die Spieleleiter*in (der Host) über "Löschen" alle Kommentare auf einmal entfernen.

Bild 4: Kommentierleiste nutzen

Stört die Annotations-Leiste, kann man sie verschieben, in dem man die Leiste am linken Rand (Bild 4, lilafarbener Pfeil) mit der Maus "greift" und dann bewegt.

Tipp: Bei diesem Spiel lohnt es sich, die Legende auf einem zweiten Monitor, z.B. einem Smartphone oder Tablet, zu öffnen. Dann muss man nicht ständig zwischen den Fenstern wechseln.

Qwixx

Um Qwixx spielen zu können, benötigen alle teilnehmenden Haushalte ein Qwixx-Würfelset (d.h. jeweils einen Würfel in blau, gelb, rot und grün und zwei neutrale Würfel), außerdem muss eine Person die Punktezettel digitalisiert haben. Im geteilten Bildschirm wird der Punktezettel nun so häufig geöffnet, wie Teilnehmer*innen am Abend versammelt sind (Bild 1)5.

Mit dem Annotations-Werkzeug wird dann an jedem Zettel der Name des Spielenden vermerkt, dem der Zettel gehört. Dann würfelt jeder reihum und teilt die Community-Würfelzahl der neutralen Würfel mit. Über das Annotationstool kann jeder dann eigenständig die Felder im eigenen Zettel markieren. Die Mitteilung aller Würfel haben wir recht schnell aufgegeben und den jeweiligen Würfelnden vertraut.

Kaleidos

Kaleidos ist noch einfacher zu spielen. Neben den digitalisierten Versionen der Suchbilder benötigt man nur einen Timer und pro Spieler*in Stift und Papier.

Die Person, die die Suchbilder besitzt teilt den Bildschirm und startet zusätzlich dazu eine Timer-App. Unter Windows standardmäßig an Board: Alarm & Uhr. Im Zeitgeber die gewünschte Zeitspanne einstellen, die pro Runde für die Suche nach Begriffen verfügbar sein soll.

Bild 5: Zeitgeber in der Windows Alarm & Uhr App

Tipp: Schneller Zugriff auf den Zeitgeber erhält man, wenn man ihn "an Start anheftet" (Bild , lilafarbener Pfeil)

Den Anfangsbuchstaben für die Begriffe zieht entweder der/die Besitzer*in des Spieles aus den im Spiel beiligenden Buchstabenkarten oder noch einfacher, man verwendet die Stadt-Land-Fluss-Methode.

Alle Mitspieler*innen vermerken, sobald die Zeit läuft, gefundene Objekte mit dem passenden Buchstaben auf ihrem Zettel. Alles läuft so, wie wenn man an einem Tisch säße - gegen die Schummelgefahrt kann man sich ja ab und zu die Zettel in der Kamera zeigen lassen ^.~

Andere Spiele

Bisher noch nicht getestet, aber bestimmt genauso einfach umsetzbar - mit dem Vertrauen, dass die anderen nicht schummeln - sind z.B. Tabu6, Kniffel, Die Montagsmaler oder Stadt-Land-Fluss. Für Tabu muss in allen teilnehmenden Haushalten eine Version des Spieles vorhanden sein - und für Kniffel benötigt jeder ein Set Würfel sowie die digitalisierte Version des Kniffelblocks.

Fallen euch noch Spiele ein, die ebenfalls gut mit den Boardmitteln von gängigen Videokonferenzwerkzeugen in den virtuellen Raum hebbar sind?

An dieser Stelle ist mein Blogeintrag eigentlich abgeschlossen, aber ich komme nicht umhin, noch ein paar Worte zum Elefanten im Raum zu schreiben. Wen also meine Meingun dazu interessiert, ob man ZOOM überhaupt verwenden sollte, darf gerne auf Seite 2 weiterlesen.

  1. siehe auch "6 Great Sites to Play Online Board Games with Friends" oder die Ravensburger Digitale Puzzelwelt []
  2. die kostenlose Version erlaubt 40-minütige Sessions für bis zu 100 Teilnehmer []
  3. theoretisch geht dies sogar ohne die Installation der Software, wobei ich bisher nicht getestet habe, ob dann sämtliche Funktionen, insbesondere die Annotationsfunktion, zur Verfügung stehen []
  4. oder, da man ja bis zu 100 freie Teilnehmenden-Slots hat, schaltet man einfach noch ein zweites Gerät für die Videos hinzu ^-^ []
  5. ich verwende dafür die kostenlose Software IrfanView []
  6. an Stelle einer Team-Variante kann man hier ebenfalls die vereinfachte Version "eine*r beschreibt, alle raten" spielen []

05
Okt 19

Navigation im Archiv: Alte Webserversicherungen zu Leben erwecken - Teil 3

Die Verzeichnis-Indexierung ist auf dem Webserver deaktiviert. Das könnte ich ändern und hätte damit meine Möglichkeit, die Verzeichnisse zu durchbrowsen. Reizvoller war es für mich, mir selbst ein kleines Script zu erstellen, dass die Inhalte auflistet. Insbesondere da in meinem Kopf die Idee herumschwirrt, die Liste später mit Screenshots anzureichern.

Unter Zuhilfenahme der Lösung der StackOverflow-Frage "How to list directories, sub-directories and all files in php" (Lösung von Tomás Aresak Malcánek1, 17.10.2015) schnell etwas zusammengezimmert und "schöner" gemacht. Hier nur der relevante PHP-Code.

function list_folder_content($path) {
  $items = scandir($path);
  $folder = explode("/", getcwd());
  echo "<h1>" . $folder[array_key_last($folder)] . "</h1>";
  echo "<ul>";
  foreach($items as $item) {
    if ($item != ".") {  // ignore "."
      // list files
      if (is_file($path . $item)) {
        echo "<li class=\"file\"><a href=\"" . $item . "\">" . $item . "</a></li>";
      } 
      // list folders
      else { 
        echo "<li ";
        if ($item == "..") echo " class=\"up\""; // special class for "directory up"
        echo "><a href=\"" . $item . "/\">" . $item . "</a></li>";
      } 
    }
  }
  echo "</ul>";
}
 
list_folder_content("./");

Praktischerweise funktioniert Pawel Kazakows portables Programm pkColorPicker auch nach 9 Jahren wie ich es gewohnt bin und ermöglicht mir die einfache Farbauswahl.

Mit dem Web-Generator ICONSVG von Gaddafi Rusli habe ich an mein Farbkonzept angepasste Icons für die Ordnerliste erstellt.

Problem: Das Script muss in allen Ordner liegen, in denen das Verzeichnis gelistet werden soll. Da ich nicht ständig neu kopieren möchte, dachte ich zuerst an einen symbolischen Link. Ad hoc ließ sich dies mit der existierenden Berechtigungsstruktur nicht einstellen, da für den Administrator das Netzlaufwerk nicht eingebunden ist.

Lösung: In den Ordnern, die ebenfalls den Script anzeigen sollen, liegt eine index.php, welche das eigentliche Script includiert:

$index = "#absoluter/Pfad/zum/Script#";
if (file_exists($index)) {
  include ($index);
}

Damit die Einbindung auf diversen Ebenen funktioniert, muss der Pfad absolut angegeben werden. Sicherlich gibt es da elegantere Lösungen... aber elegant ist im Moment nicht mein Ziel. Mit dieser kleinen Lösung muss ich das Script nur an einer Stelle warten.

Offene Punkte

  • Blog-Font updaten, damit alle Zeichen angezeigt werden
  • Bildvorschau für Ordner
  • Administrator-Shell: Zugriff auf Netzlaufwerke
  1. Es tut mir Leid, die aktuell verwendete Schriftart scheint die benötigten Zeichen nicht zu unterstützen - deswegen die Vereinfachung der Schreibweise []

03
Okt 19

Das Problem mit den dynamischen Inhalten: Alte Webserversicherungen zum Leben erwecken - Teil 2

Die Wahl haben zwischen Neuschreiben von altem Code oder doch Container anlegen, die mit alten PHP/MySQL-Versionen laufen. Es gibt noch eine dritte Möglichkeit, die jedoch voraussetzt, dass die Sicherungen auf den alten portablen Webservern unter WinXP noch einwandfrei funktionieren (was sie nur bedingt tun): Eine statische Sicherung der PHP-Ausgaben.

Alle drei Mölichkeiten sind mehr oder weniger - sehr - zeitaufwändig. Reverse Engineering hat das Problem, dass ich sowohl vor 10+ Jahren als auch jetzt ein absoluter Noob bin, was das Schreiben ordentlichen Codes angeht. Damals, weil es neu war - und heute, weil ich zuletzt vor etwa 10 Jahren wirklich aktiv gecoded habe. Seitdem ist viel passiert.

Mit einer steigenden Komplexität des Codes - Frameworks, Bibliotheken wird die Entwicklung einfacher/strukturierter - niemand muss das Rad mehr neu erfinden - doch die Komplexität dahinter steigt: viele Abhängigkeiten. Wird alles noch gewartet? Die Wetten, wie es in einem Jahr aussieht sind klar.

Trotz allem Aufwand wollte ich eines der Projekte wieder zum Leben erwecken. Was hat sich im letzten Jahrzehnt in PHP verändert? Wie funktionieren neue Funktionen? Es hat etwas befriedigendes, wenn dann nach und nach die PHP-Fehler verschwinden und die eigentlichen Inhalte ausgegeben werden. Und doch auch die traurige Gewissheit, dass es nicht sinnvoll ist, sämtlichen schlechten Code von damals in einer vermutlich ebenso schlechten Version wieder zum Leben zu erwecken. Bleiben die Optionen 2 und 3.


03
Okt 19

In die Kaninchenhöhle gefallen: alte Webserversicherungen zum Leben erwecken - Teil 1

Wenn nach langem Wunsch endlich ein Server zu Hause steht und die Idee aufkeimt, die Historie der eigenen Webseiten aus den Backups und portablen Webserver-Sicherungen an einer Stelle zusammenzuführen ... und wieder zum Laufen zu bringen. Schließlich gibt es nichts schöneres, als sich über die Sünden der Vergangenheit zu amüsieren ^-^ - Augenkrebs und so (Hier am Beispiel der Crazylounge anno 2001).

Problem: Portable Webserver laufen nicht mehr. Genauer gesagt, die MySQL-Datenbank funktioniert unter Windows 10 nicht.

Versuch 1: Glücklicherweise funktioniert die Windows XP VM, welche ich bis vor gar nicht all zu langer Zeit noch zur Nutzung des Scanners einsetzte, nach wie vor einwandfrei. Der Webserver startet dort, inklusive Zugriff auf die MySQL-Datenbanken & phpMyAdmin. Dumm nur, dass in dem funktionerenden Webserver die betroffenen Datenbanken doch nicht drin waren.

Versuch 2: Internet-Suche bringt mich zur Anleitung "Recovering MySQL Files and Database Tables" von Hetman Software. Mit Hilfe von MySQL Workbench können auch Datenbanken exportiert werden, deren Ordner aus dem ursprünglichen mysql-Verzeichnis in den mysql-Ordner einer bestehenden Datenbank hineinkopiert werden.

Nächster Schritt: Eine bestehende Datenbank muss her, also Docker-Container aufsetzen. Dieses Mal nicht in der Konsole sondern aus Bequemlichkeit direkt im Synology-Docker-Interface. Nicht vergessen die Variable MYSQL_ROOT_PASSWORD zu setzen.

Einrichten einer neuen Verbindung in MySQL Workbench: Hostname entspricht dem hostnamen des Servers, Port kann über docker ps herausgefunden werden. Klappt. Jetzt müsste ich die Ordner in den data-Ordner der Datenbank hineinkopieren ...

Problem: Upload von Dateien in den MySQL-Docker-Container ist gerade etwas umständlich für mich.

Alternative: Eine MySQL-DB, die in Windows läuft und auf deren Verzeichnisse ich aus Windows heraus zugreifen kann, wäre doch etwas angenehmer. Glücklicherweise habe ich den Bitnami-WAMP-Stack noch nicht ins Nirvana geschickt, nachdem die darauf laufenden Services auf den Webserver umgezogen sind. Zugriff darauf klappt genauso wie das Hinzufügen der Ordner aus alten mysql-Ordnern.

Wie in der oben erwähnten Anleitung den Data Export für einen der alten Ordner anstoßen. Ich exportiere zu einer Self-Contained File inklusive Dump- und Schema-Instruktionen. Die Warnung, dass die MySQL-Version nicht übereinstimmt ignoriere ich. Mehr als schiefgehen kann es nicht, immerhin liegt mehr als ein Jahrzehnt zwischen den Versionen.

Anschließend nutze ich die Exportdatei um die Datenbank in der Docker-Datenbank zu importieren. Es werden Tabellen angelegt, in den Tabellen ist Inhalt der so aussieht, als sei er komplett. Zugegebenermaßen - inbesondere die frühen Datenbanken sind so basic, dass ich weniger Probleme erwarte.

Als nächster Schritt bleibt nun die große Aufgabe, den PHP-Teil der Webseiten wieder mit dem Datenbankteil zu verbinden. Denn natürlich möchte ich nicht mit einer PHP-anno-tubac-Version auf dem Server arbeiten. Dies ist ein größeres Projekt - oder ich finde eine Bibliothek, die mysql_* in mysqli_* transformiert. Aber nicht mehr heute.