Zum Inhalt springen
Michael Blaess
IT-Consulting
Michael Blaess
EN

"Wir sind nicht nur verantwortlich für das, was wir tun, sondern auch für das, was wir nicht tun"

EthikOpen SourceCrawlerPython
Porträt Voltaires von Nicolas de Largillière, um 1724
Der Satz wird Voltaire zugeschrieben. Porträt von Nicolas de Largillière, um 1724/25. Quelle: Wikimedia Commons, gemeinfrei (Scan: Manfred Heyde).

Wer Software veröffentlicht, verteilt Handlungsfähigkeit an Fremde. Das ist der Sinn der Sache. Es ist zugleich der Grund, warum es nicht folgenlos bleibt.

Einige meiner Werkzeuge machen das sehr konkret. sitemap-tracker baut eine vollständige Sitemap für Seiten, die keine brauchbare haben, und spürt tote Links auf. c2pa-scanner prüft Bilder auf Herkunftsdaten, damit man die eigene Website nach dem EU AI Act kennzeichnen kann. console-error-scanner findet JavaScript-Fehler und HTTP-Fehler auf Webseiten.

Ob das Terminal-Tools, WebApps oder Desktop-Anwendungen sind, spielt dabei keine Rolle. Es sind hilfreiche Werkzeuge, die Fehler finden sollen und Webseitenbetreiber und Administratoren unterstützen. Um das zu leisten, müssen sie Server analysieren, und dabei erzeugen sie Traffic.

Genau da hört die gute Absicht auf, nur technisch relevant zu sein. Und genau da muss auch der Entwickler aufhören, nur aus technischer Perspektive zu denken, für den Patterns und Code-Eleganz den Maßstab bilden. Er muss weiter denken und sich bewusst machen, dass sein Werkzeug nicht ausschließlich in vernünftige Hände gerät.

Was sich nicht verhindern lässt

Ein Crawler unterscheidet nicht zwischen sinnvoller Fehlersuche und gefährlichem Abgrasen. Er sieht eine URL und holt sie. Ob dahinter jemand seine eigene Website aufräumt oder die eines Wettbewerbers durchleuchtet, steht in keinem Request-Header.

Das ist die nüchterne Ausgangslage: Missbrauch lässt sich nicht verhindern. Wer ein Werkzeug veröffentlicht, gibt es aus der Hand. Keine Lizenz, kein README und kein gut gemeinter Absatz “Wofür es gedacht ist” ändert daran etwas. Missbrauch liegt niemals in meinem Sinne, aber “nicht in meinem Sinne” ist eine Meinung und keine Schutzmaßnahme.

Das ist auch keine Besonderheit meiner Werkzeuge. Das bekannteste Beispiel liegt auf fast jedem Entwicklerrechner: curl. Ein winziges, seit Jahrzehnten gepflegtes Programm, verbaut in unzähligen Skripten, Build-Pipelines und Geräten, und aus dem Alltag nicht mehr wegzudenken. In einer Schleife und mit genug Parallelität ist dasselbe Programm ein Hammer, der einen kleinen Server umlegt. Trotzdem käme niemand auf die Idee, curl sei ein schlechtes Werkzeug.

Der Unterschied liegt in der Abstraktionsebene. curl ist ein Basiswerkzeug. Es macht genau einen Request und überlässt jede weitere Entscheidung dem Aufrufer. Wer bremsen will, setzt --limit-rate, wer robots.txt respektieren will, baut das selbst. Das ist völlig in Ordnung, weil der Nutzer eines Basiswerkzeugs die Kontrolle bewusst übernimmt. Bei einer fertigen Anwendung mit Startknopf verschiebt sich das: je fertiger das Werkzeug, desto mehr Entscheidungen trifft der Entwickler an Stelle des Nutzers.

Interessant wird die Frage eine Ebene darunter. Nicht: Was macht der schlimmste Nutzer aus meinem Werkzeug? Sondern: Was macht mein Werkzeug, wenn niemand etwas Böses vorhat und einfach auf Start drückt? Diese zweite Frage liegt vollständig in meiner Hand.

Vier Praktiken, mit denen ich versuche (!), sie zu beantworten.

1. Eine sinnvoll durchdachte Bremse gehört in die Voreinstellung

Ein Werkzeug, das fremde Server anfasst, braucht ein Rate-Limit ab Werk. Nicht als Option für den vorsichtigen Nutzer, sondern als Standard, den der Ungeduldige aktiv abschalten muss.

Die häufigste Verwechslung dabei: Gleichzeitigkeit ist keine Rate. Eine Semaphore begrenzt, wie viele Requests parallel laufen, nicht wie viele pro Sekunde. Antwortet das Ziel schnell, feuert das Tool entsprechend schnell nach. Der gut ausgebaute Server wird also am härtesten getroffen. Beim Crawlen kommt dazu, dass die Seitenzahl vorher nicht feststeht, weil der Crawler Links bis zur eingestellten Tiefe folgt.

Ein echter Limiter verteilt deshalb alle Abrufe gleichmäßig über die Zeit und greift auch bei Wiederholungsversuchen. In meinen Tools stehen jetzt 60 Requests pro Minute als Vorgabe, änderbar über einen Regler oder --rate-limit, mit 0 abschaltbar. Die Herangehensweise ist der entscheidende Punkt: abschaltbar, nicht anschaltbar. Wer schneller crawlen will, trifft damit eine bewusste Entscheidung, und dann ist es seine.

2. robots.txt richtig oder gar nicht

robots.txt gehört respektiert. Aber ein Häkchen “robots.txt beachten”, das in der Praxis nichts beachtet, ist schlechter als gar keins, weil es beruhigt.

Die Regeln nach RFC 9309 kennen * und $. Wer nur naiv auf Präfixe vergleicht, greift bei realen Einträgen nie. Ein Beispiel aus der Praxis:

Disallow: /*CR-Dokumentation.pdf$

Ein Präfix-Vergleich prüft, ob der Pfad buchstäblich mit /*CR-Dokumentation.pdf beginnt. Kein Pfad tut das. Die Regel wäre vorhanden und würde nie greifen. Dazu gehört die Konfliktauflösung: bei mehreren Treffern gewinnt die längste Regel, bei gleicher Länge Allow.

Und wenn eine Lücke bleibt, gehört sie dokumentiert. Beim c2pa-scanner werden die Seiten aus der Sitemap geprüft, die Bilder nicht, weil sie oft auf einer CDN-Domain mit eigener robots.txt liegen. Das steht so im README. Eine bekannte Grenze ist kein Makel, eine verschwiegene schon.

3. Der Hinweis, der bestätigt werden muss

In meinen Tools blockiert ein Haftungshinweis den Start, bis er bestätigt wurde. Die Zustimmung wird zusammen mit der Textfassung gespeichert, sodass nur bei einer Änderung erneut gefragt wird. Für Skripte und headless CI gibt es --accept-disclaimer.

Zur Einordnung, damit keine falsche Erwartung entsteht: Der Disclaimer ist nicht die Schutzmaßnahme. Er verhindert keinen einzigen Missbrauch. Er sorgt dafür, dass jeder Nutzer einmal bewusst gelesen hat, was das Werkzeug tut, wofür es gedacht ist und wofür ausdrücklich nicht.

Die Wirkung steckt in den Voreinstellungen, die Klarheit im Hinweis. Der Hinweis ohne vernünftige Defaults ist Kosmetik. Gute Defaults ohne Hinweis überlassen dem Nutzer das Nachdenken. Erst beides zusammen ergibt ein Werkzeug, das man guten Gewissens veröffentlicht.

4. Rechtstexte in der Sprache des Lesers

Ein Punkt, der in Tools aus dem deutschsprachigen Raum gern durchrutscht: die Sprache. Ein Haftungshinweis, den der Leser nicht versteht, ist kein Haftungshinweis. Ihn trotzdem bestätigen zu lassen, ist eine Formalie ohne Inhalt.

In meinen Tools und Anwendungen richtet sich die Sprache beim Erststart deshalb nach der Systemumgebung, und zwar bewusst asymmetrisch: Deutsch nur bei nachweislich deutschsprachiger Umgebung. Unbekannte Sprache, leere Umgebung oder ein Fehler beim Auslesen -> Englisch, die Sprache der Projektdokumentation. Im Zweifel bekommt der Nutzer die Sprache, die er mit höherer Wahrscheinlichkeit lesen kann.

Die Frage vor dem Release

Ob Open Source, Kundenprojekt oder internes Werkzeug macht dabei keinen Unterschied. Die Verantwortung hängt nicht am Lizenzmodell, sondern daran, dass fremde Menschen und fremde Systeme mit dem Ergebnis in Berührung kommen.

Ich habe mir deshalb eine Frage angewöhnt, die vor jedem Release drankommt:

Was ist der schlimmste vernünftige Einsatz meines Werkzeugs - und was ist mein Default dagegen?

Nicht der schlimmste denkbare. Gegen Vorsatz kommt niemand an. Der schlimmste vernünftige: der Nutzer, der nichts Böses will, einfach startet und die Voreinstellungen übernimmt. Der trifft genau die Defaults an, die ich gesetzt habe. Oder die, über die niemand nachgedacht hat.

Voltaire hat für Verantwortung im Handeln keine Ausrede gelten lassen, und für die im Unterlassen erst recht nicht. Daran sollten wir uns orientieren. Bei jedem Werkzeug, das wir entwickeln, gehört die Frage mitgedacht, wie es am Ende eingesetzt werden kann.

Links: sitemap-tracker · c2pa-scanner · console-error-scanner · RFC 9309 (robots.txt)

“It works on my machine. Then we'll ship your machine.”

- Unbekannt