Dass eine interne Webanwendung seit Jahren ohne Vorfall läuft, sagt nichts über ihre Sicherheit aus – nur, dass bisher niemand gezielt danach gesucht hat. Code, der nie mehr angefasst wird, verändert sich zwar nicht selbst, aber sein Umfeld schon: Was beim Bau eine übliche Vorgehensweise war, gilt heute oft als eine der am häufigsten ausgenutzten Schwachstellen im Web.
Warum «es lief ja immer» nichts über Sicherheit aussagt
Eine ruhige Anwendung ist nicht dasselbe wie eine geprüfte Anwendung. Die meisten Angriffe auf kleine, unauffällige interne Tools sind keine gezielten Attacken durch jemanden, der die Firma kennt, sondern automatisierte Scans, die routinemässig nach bekannten Mustern suchen – einem Login-Formular, einer veralteten PHP-Version, einer offen erreichbaren Konfigurationsdatei. Ob so ein Scan je stattgefunden hat, lässt sich von aussen kaum beurteilen, und wenn niemand die Logs auswertet, hinterlässt selbst ein erfolgreicher Zugriff oft keine Spur, die auffällt.
Hinzu kommt: Viele dieser Anwendungen sind über die Jahre gewachsen, ohne dass es einen Zeitpunkt gab, an dem «die Sicherheit» bewusst geprüft wurde. Ein Formular kam dazu, eine Schnittstelle zu einem Lieferanten, ein Upload-Feld für Belege – jede Erweiterung ein sinnvoller Schritt für sich, aber niemand hat die Summe je aus der Perspektive eines Angreifers betrachtet.
Was bei zwei ungewarteten KMU-Anwendungen tatsächlich gefunden wurde
Bei zwei unabhängigen internen Anwendungen von Schweizer Betrieben – beide seit über zehn Jahren im Einsatz, beide ohne laufende Wartung – zeigte eine Sicherheitsüberprüfung ein sehr ähnliches Bild. Keine der beiden Firmen hatte einen Vorfall gemeldet oder auch nur vermutet; in beiden Fällen bestätigte die Analyse dieselbe Grundaussage aus dem vorigen Abschnitt.
| Befund | Was das konkret bedeutete |
|---|---|
| Login-Formular anfällig für SQL-Injection | Ein Angreifer hätte sich ohne Kenntnis eines Passworts als beliebiger Benutzer anmelden können – mit einem gewöhnlichen Browser, ohne Spezialwerkzeug |
| Zugangsdaten im Programmcode | Datenbank-, E-Mail- und Schnittstellen-Passwörter standen als lesbarer Text im Code – sichtbar für jeden mit Code-Zugriff |
| Fehlender Formularschutz (CSRF) | Eine präparierte fremde Webseite hätte im Namen eines angemeldeten Mitarbeiters Aktionen auslösen können, etwa Einträge löschen |
| Ungeprüfte Ausgaben (XSS) | Werte aus der Datenbank wurden ungefiltert angezeigt – ein Einstiegspunkt, um Schadcode im Browser anderer Nutzer auszuführen |
| Veraltete Serverkomponenten | Die Anwendungen liefen auf PHP-Versionen und Funktionen, die seit Jahren keine Sicherheitsupdates mehr erhalten |
Nach der Behebung war der praktische Unterschied für die tägliche Arbeit gleich null – die Anwendungen sehen aus und verhalten sich wie vorher. Der Unterschied liegt ausschliesslich darin, was ein Angreifer damit anfangen könnte.
Eine Webanwendung wird nicht sicherer, weil sie ruhig ist – nur unauffälliger.
Warum genau diese Lücken entstehen, wenn niemand mehr hinschaut
Keiner dieser Befunde entsteht durch Nachlässigkeit einer einzelnen Person. Sie entstehen, weil sich der Massstab dafür, was «normal programmiert» bedeutet, seit dem Bau der Anwendung verschoben hat. Vor zehn, fünfzehn Jahren war es üblich, Benutzereingaben direkt in eine Datenbankabfrage einzusetzen oder ein Passwort als Konstante im Code zu hinterlegen – Konzepte wie CSRF-Schutz oder systematisches Output-Encoding waren in vielen Entwicklungsumgebungen schlicht noch kein Standard. Der Code hat sich seither nicht verändert; die Bedrohungslage und der Stand der Technik aber schon.
Ohne laufende Pflege gibt es auch keinen Moment, an dem diese Verschiebung nachgeholt wird. Jede neue Funktion wird nach dem Muster der bestehenden gebaut, und das Muster stammt aus einer Zeit, in der es noch als unbedenklich galt.
Wie Sie eine ungewartete Anwendung technisch prüfen
Ein belastbares Urteil braucht eine Analyse. Fünf Schritte führen aber schon ohne fremde Hilfe zu einem brauchbaren Lagebild:
- Erreichbarkeit von aussen feststellen. Rufen Sie die Anwendung aus einem fremden Netz auf – Mobilfunk statt Firmen-WLAN, ohne VPN. Erscheint das Login, ist sie öffentlich. Fragen Sie zusätzlich die Certificate-Transparency-Protokolle für Ihre Domain ab (etwa über
crt.sh): Dort stehen auch die Hostnamen, an die im Haus niemand mehr denkt. - Laufzeit-Versionen erheben und gegen das Support-Ende abgleichen. Welche PHP-Version läuft, welches Framework, welche Bibliotheken? Alles, was keine Sicherheitsupdates mehr bekommt, ist eine offene Rechnung – unabhängig davon, ob eine konkrete Lücke bekannt ist.
- Zugangsdaten im Code suchen. Eine Textsuche über das Repository nach
password,passwd,secret,api_keyfördert erstaunlich viel zutage. Wichtig: auch die Versionsgeschichte durchsuchen. Ein Passwort, das vor Jahren aus dem aktuellen Stand entfernt wurde, steht im Git-Verlauf weiterhin – und ist dort genauso lesbar. - Die Logs auf frühere Scans durchsuchen. Suchen Sie im Access-Log nach den typischen Mustern:
' OR 1=1,UNION SELECT,../../, Aufrufe von/wp-login.phpoder/phpmyadminauf einer Anwendung, die beides gar nicht hat. Das zeigt, ob und wie oft die Anwendung bereits abgeklopft wurde. - Eingabestellen inventarisieren. Jedes Formular, jedes Upload-Feld, jede Schnittstelle ist ein Ort, an dem Fremdeingaben verarbeitet werden. Eine simple Liste dieser Stellen ist die Landkarte für jede weitere Prüfung.
Zwei Fallstricke, die das Ergebnis wertlos machen:
- «Nichts im Log» heisst meistens «kein Log». Viele Hostings rotieren die Zugriffsprotokolle nach wenigen Tagen oder schreiben sie gar nicht erst. Die Abwesenheit von Spuren ist dann kein Befund, sondern eine Lücke in der Beobachtung. Prüfen Sie zuerst, wie weit Ihre Logs überhaupt zurückreichen – erst dann sagt ihr Inhalt etwas aus.
- Ein Test gegen die laufende Anwendung verändert Daten. Wer Formulare durchprobiert, verschickt echte Mails, legt echte Einträge an und löscht im schlechtesten Fall welche. Solche Prüfungen gehören auf eine Kopie – die dann ihrerseits nicht offen im Internet stehen darf.
Wie Sie einschätzen, ob ein eigenes Tool betroffen sein könnte
Für ein erstes Gefühl reicht auch ohne technische Prüfung eine Handvoll Fragen:
- Ist die Anwendung ohne VPN oder IP-Einschränkung aus dem offenen Internet erreichbar?
- Verarbeitet sie Kunden- oder Personendaten, Rechnungen oder Zugangsdaten zu weiteren Systemen?
- Weiss noch jemand im Betrieb, wann der Code zuletzt inhaltlich – nicht nur im Server-Update – angefasst wurde?
- Gab es je eine gezielte Sicherheitsprüfung, oder lief die Anwendung einfach, weil sie funktionierte?
Zwei oder mehr «Ja» bei den ersten drei Fragen sind kein Beweis für eine Schwachstelle, aber ein guter Grund, das genauer anzuschauen, statt sich auf die störungsfreie Historie zu verlassen.
Dass nichts passiert ist, heisst nur: Es hat niemand nachgesehen
In fast jedem Betrieb läuft irgendein selbstgebautes Werkzeug: eine Anwendung für die Zeiterfassung, für Offerten, für die Auftragsverwaltung. Sie wurde vor Jahren programmiert, sie tut, was sie soll, und niemand fasst sie mehr an. Genau deshalb gilt sie als unbedenklich – es ist ja nie etwas passiert.
Der Trugschluss steckt in diesem Satz. «Es ist nichts passiert» ist keine Aussage über die Sicherheit Ihrer Anwendung, sondern über Ihre Beobachtung. Wenn niemand die Zugriffsprotokolle anschaut, sieht man auch dann nichts, wenn etwas geschehen ist.
Bei zwei Schweizer Betrieben, deren interne Anwendungen ich prüfen liess, war das Ergebnis nahezu deckungsgleich: In beiden Fällen hätte sich ein Fremder ohne Passwort anmelden können – mit einem gewöhnlichen Browser, ohne Spezialwerkzeug. Beide Firmen hatten nie einen Vorfall bemerkt. Nach der Behebung sahen die Anwendungen aus wie vorher und verhielten sich wie vorher. Für die tägliche Arbeit änderte sich nichts. Geändert hat sich nur, was ein Fremder damit hätte anfangen können.
Was die Prüfer meinen, wenn sie von Lücken sprechen
Die Anmeldung lässt sich umschreiben
Der Fachausdruck dafür lautet SQL-Injection. SQL steht für «Structured Query Language» – das ist die Sprache, in der eine Anwendung mit ihrer Datenbank redet. Tippt jemand seinen Benutzernamen ein, baut die Anwendung daraus eine Frage an die Datenbank: «Gibt es einen Benutzer mit diesem Namen und diesem Passwort?» Prüft sie die Eingabe nicht, kann ein Besucher statt eines Namens ein Stück dieser Sprache eintippen – und damit die Frage selbst umschreiben. Aus «Gibt es diesen Benutzer?» wird «Lass mich rein, egal wer ich bin.»
Passwörter stehen im Programmtext
Damit die Anwendung an die Datenbank kommt, braucht sie ein Passwort. Steht es direkt im Programmtext statt an einem geschützten Ort, kann es jeder lesen, der an den Programmtext kommt – der externe Entwickler von damals, der Praktikant, jeder mit Zugriff auf die Datensicherung.
Eine fremde Seite handelt in Ihrem Namen
Der Fachausdruck lautet CSRF, ausgeschrieben «Cross-Site Request Forgery», sinngemäss: das Fälschen einer Anfrage von einer fremden Seite aus. Solange Sie in Ihrer Anwendung angemeldet sind, vertraut diese Ihrem Browser. Öffnen Sie im selben Browser eine präparierte fremde Seite, kann diese im Hintergrund einen Befehl an Ihre Anwendung schicken – und die führt ihn aus, weil er ja von Ihrem angemeldeten Browser kommt. Sie sehen davon nichts.
Warum ich zuerst frage, ob je jemand hingeschaut hat
Wenn mir jemand sagt, seine Anwendung laufe seit zwölf Jahren ohne Probleme, höre ich zwei verschiedene Sätze. Der eine ist: «Sie ist sicher.» Der andere ist: «Wir haben nie nachgesehen.» Nur der zweite ist belegt.
Technisch sind diese Lücken keine Kunstfehler. Sie entstehen, weil sich der Massstab verschoben hat: Was vor fünfzehn Jahren gängige Programmierpraxis war, gilt heute als leichtfertig. Der Code hat sich nicht verändert – die Welt um ihn herum schon. Deshalb rede ich ungern von Schuld und lieber von Wartung.
Wirtschaftlich ist der Punkt, den ich am häufigsten machen muss, ein anderer: Diese Anwendungen sind selten unwichtig. Sie enthalten Kundendaten, Offerten, manchmal Zugangsdaten zu anderen Systemen. Sie werden nur deshalb stiefmütterlich behandelt, weil sie unauffällig sind – und unauffällig ist genau das, was sie so lange ungeprüft bleiben liess. Der Aufwand, die gefundenen Lücken zu schliessen, war in beiden Fällen ein Bruchteil dessen, was eine Neuentwicklung gekostet hätte.
Was ich Ihnen nicht verspreche: dass eine Prüfung alles findet. Sie findet, wonach gesucht wird. Aber sie ersetzt eine Vermutung durch einen Befund – und das ist der ganze Unterschied zwischen «wird schon gut sein» und «wir wissen, wo wir stehen».
Häufige Fragen
Reicht ein Server-Update, oder muss der Programmcode selbst geprüft werden?
Ein Server-Update schliesst nur Lücken in der zugrunde liegenden Software (PHP, Webserver, Bibliotheken). Fehler im eigenen Programmcode – etwa eine unsichere Datenbankabfrage oder ein fehlender Formularschutz – bleiben davon unberührt und brauchen eine eigene Prüfung des Codes.
Ist eine Anwendung ohne Internetzugang automatisch sicher?
Nein, aber das Risiko sinkt deutlich. Ein System, das nur im internen Netz oder per VPN erreichbar ist, kann kaum von aussen automatisiert abgesucht werden. Bleibt es dennoch offen im Internet erreichbar, zählt es zum gleichen Risiko wie jede öffentliche Website – unabhängig davon, wie wenige Personen die Adresse kennen.
Muss man ein altes internes Tool gleich neu programmieren?
In der Regel nicht. Die in diesem Beitrag beschriebenen Lücken lassen sich meist gezielt im bestehenden Code schliessen, ohne die Anwendung neu zu bauen. Eine Neuentwicklung lohnt sich erst, wenn der technische Unterhalt insgesamt teurer wird als eine Ablösung.
Woran erkennt man solche Lücken, ohne selbst Programmierkenntnisse zu haben?
Als Entscheider muss man den Code nicht lesen können – die Fragen im Abschnitt «Wie Sie einschätzen, ob ein eigenes Tool betroffen sein könnte» reichen, um zu beurteilen, ob eine nähere Prüfung sinnvoll ist. Die eigentliche Analyse gehört dann in fachkundige Hände.