Warum Default-Passwörter ein Übel sind

Posted by christopher on Thursday, August 13, 2015

Ein spannender Fall aus dem Support, der hervorragend vorführt wieso Default-Passwörter ein Übel sind, so früh wie möglich geändert werden sollten und warum es besser ist Software von vornherein so zu schreiben, dasss sie ohne auskommt:

Ein User hatte sich nach der in unserem Wiki verlinkten Anleitung eines anderen Users OpenProject eingerichtet. Als ich mir die Sache später anschaute, sah es zunächst so aus als habe er einen wichtigen Punkt aus der Anleitung übersprungen:

“Find a free port for your OpenProject installation. I use the port 61621 - you need to replace that number with your port in the following files. This is the port your OpenProject server will listen to. The uberspace-apache will redirect all requests to that port.”

Wie sich später herausstellte, hatte er das nicht übersprungen, denn er hat die Anleitung gar nicht benutzt sondern ein Skript das die Schritte aus der Anleitung abarbeitet und an der Stelle in der Version die der User verwendet hat einen Bug hatte.

(Zu diesem Zeitpunkt standen mir bereits die Haare zu Berge. Installationen die im wesentlichen so ablaufen: curl https://example.com/mystery_script | bash (wahlweise auch mit wget) sind einer der gruseligsten Trends der letzten Jahre. Mit Fremden ohne Kondom unterwegs auf der Shell. Was könnte dabei wohl schief gehen? Am besten gleich noch ohne HTTPS, wo wir schonmal dabei sind, das macht den Kohl dann auch nicht mehr fett.)

Das allein war aber noch kein Problem. Leider hat der User aber nachdem OpenProject bei ihm lief die Default-Zugangsdaten nicht geändert. Diese werden in der Anleitung erwähnt, allerdings ohne einen Hinweis, dass diese unverzüglich geändert werden sollten. (Ein nachvollziehbarer Fehler. Ich finde auch, dass soetwas selbstverständlich ist, jahrelange Erfahrung mit dem Schreiben von Anleitungen und den Supportanfragen die dann trotzdem kommen haben mich aber eines besseren belehrt. Sicherheitsrelevante Hinweise dürfen nie fehlen und müssen immer möglichst groß, fett, rot und am besten noch blinkend dargestellt werden, damit sie etwas seltener ignoriert werden. Zumindest solange Computer noch keine Funktion haben das Befolgen solcher Hinweise mit leichten Stromschlägen durchzusetzen.)

Die OpenProject-Instanz lief aber erstmal und funktionierte.

Nun kam ein anderer User und hat sich zufällig auf dem selben Host ebenfalls nach dieser Anleitung OpenProject eingerichtet und ebenfalls den Hinweis mit den Ports ignoriert, bzw. das selbe Skript bareback ausgeführt. Wenig später sah er in seinem Browser nichtsahnend unter seiner User-Subdomain die Login-Seite von OpenProject und bekam mit dem Usernamen “admin” und dem Passwort “admin” sofort Zugang dazu, auch wie erwartet mit Vollzugriff. Die bereits vorhandenen Daten hielt er zunächst für Beispieldaten, wobei ihm das aber schnell suspekt erschien, denn für Beispieldaten wirkten sie bemerkenswert realistisch und aktuell. Als plötzlich neue Beispieldaten auftauchten, wandte er sich irritiert an uns und wenig später auch an den User in dessen OpenProject-Instanz er gelandet war.

Was der zweite User nicht mitbekommen hatte war, dass seine OpenProject-Instanz nie gestartet war, da sie sich nicht an Port 61621 aus der Anleitung binden konnte, denn dieser war bereits durch die Instanz des ersten Users belegt.

Dass nun bei einer Applikation die auf einem hohen Port hinter dem Webserver als Proxy läuft prinzipiell jeder User auf diese Applikation zugreifen kann wenn er den Webserver ebenfalls mit einer Proxy-Regel für diesen Port konfiguriert, ist an sich noch kein großes Problem, auch wenn es natürlich unschön ist. (Vermeiden ließe sich das nur mit Unix Domain Sockets, welche als Dateien im Dateisystem erscheinen und mit entsprechenden Zugriffsrechten und ACLs versehen werden können. Leider sind Socket-Dateien bei Entwicklern offenbar nicht populär, vielleicht weil es sie nur auf Unix-verwandten Systemen gibt und nicht unter Windows. – Wir arbeiten daran diesem Problem auf anderer Weise Herr zu werden, nämlich indem wir den Zugriff auf Ports per SELinux regulieren, das ist aber noch nicht spruchreif.) Fatal war in diesem Fall aber das nicht geänderte Default-Passwort.

Und die Moral von der Geschicht?

  • Wie schon beim jüngsten Schreck um MongoDB zeigt sich einmal mehr, das es eine schlechte Idee ist Dienste ohne Zugriffsschutz oder in diesem Fall mit dank Default-Passwort wirkungslosem Zugriffsschutz zu betreiben.
  • Ändert Default-Passwörter immer sofort bei der ersten sich bietenden Gelegenheit.
  • Bei Software mit Default-Passwörtern packt während des Setups am besten noch einen weiteren Zugriffsschutz dazu bis das Default-Passwort geändert ist.
  • Führt niemals Befehle wie curl http://example.com/mystery_script | bash aus, auch nicht mit wget, auch nicht mit HTTPS, auch nicht mit einer anderen Shell. Oder wenn dann ladet sie vorher wenigstens runter und schaut sie Euch sehr genau an und führt danach die Version aus die ihr Euch runtergeladen habt und ladet das nicht nochmal neu (mit möglicherweise überraschenden Ergebnissen).
  • Wenn Anleitungen sagen, ihr sollt Euch einen anderen Port suchen, dann sucht Euch gleich einen anderen Port und nicht erst später. Geht in der Anleitung nicht zum nächsten Schritt über, bevor ihr Euch einen anderen Port gesucht habt. Fahrt erst in der Anleitung fort nachdem ihr Euch einen anderen Port gesucht habt. Der übernächste Schritt in der Anleitung kommt gar nicht erst in Frage bevor ihr Euch einen anderen Port gesucht habt und den nächsten Schritt in der Anleitung gemacht habt.
  • Unix Domain Sockets sind super, benutzt sie wenn Eure Software das kann. (Ich sag das gerne und wie ihr merkt bei jeder Gelegenheit.) Mit einer Proxy-Regel im Apache geht das bei uns nicht, aber über unser HTTP(S)-Frontend Pound geht es, schreibt uns wenn ihr sowas ausprobieren wollt.

Und für alle Entwickler: Bitte schreibt Software so, dass es erst gar keine Default-Passwörter gibt, auch nicht in der Beta-Version. Generiert ein sicheres Passwort oder erzwingt dass ein solches gesetzt wird, indem Eure Software sich weigert ohne eines zu starten.