TL;DR
Die OWASP Top 10 sind der globale Standard für kritische Web-Applikations-Schwachstellen und werden von PCI DSS, BSI IT-Grundschutz und ISO 27001 referenziert. Die zehn Kategorien umfassen Broken Access Control, Cryptographic Failures, Injection, Insecure Design, Security Misconfiguration, Vulnerable Components, Authentication Failures, Integrity Failures, Logging Gaps und Server-Side Request Forgery. Zu jeder Kategorie werden reale Vorfälle, fehlerhafte Code-Muster und konkrete Fixes für Entwickler beschrieben.
Diese Zusammenfassung wurde KI-gestützt erstellt (EU AI Act Art. 50).
Inhaltsverzeichnis (11 Abschnitte)
Die OWASP Top 10 sind das bekannteste Sicherheitsdokument der Welt für Web-Applikationen. Das Open Web Application Security Project (OWASP) veröffentlicht alle 3-4 Jahre eine aktualisierte Liste der kritischsten Schwachstellenkategorien - basierend auf echten Daten aus Tausenden Web-Applikations-Pentests.
Jede seriöse Compliance-Anforderung die Web-Sicherheit adressiert - PCI DSS, BSI IT-Grundschutz, ISO 27001 - referenziert OWASP. Wenn Sie wissen wollen ob Ihre Web-Applikation sicher ist, sind die OWASP Top 10 der Startpunkt.
A01: Broken Access Control - Häufigste Schwachstelle
Was es ist: Nutzer können auf Ressourcen oder Funktionen zugreifen, für die sie keine Berechtigung haben.
Real-World-Beispiel: Facebook, 2018 - Access Control Fehler erlaubte jedem Nutzer Fotos anderer Nutzer herunterzuladen, auch wenn diese privat eingestellt waren. 6,8 Millionen Nutzer betroffen.
Typischer Code-Fehler:
// GET /api/documents/:id - kein Check ob Dokument dem User gehört
app.get("/api/documents/:id", authenticate, async (req, res) => {
const doc = await Document.findById(req.params.id);
res.json(doc); // Jeder angemeldete User kann JEDES Dokument lesen!
});
Sichere Variante:
app.get("/api/documents/:id", authenticate, async (req, res) => {
const doc = await Document.findOne({
_id: req.params.id,
owner: req.user.id, // Eigentümercheck!
});
if (!doc) return res.status(403).json({ error: "Not found or unauthorized" });
res.json(doc);
});
Praxis-Tipp: Jeden API-Endpunkt mit der Frage testen: "Was passiert wenn ein anderer eingeloggter User die ID eines anderen Users ändert?"
A02: Cryptographic Failures - Daten unzureichend geschützt
Was es ist: Sensitive Daten werden nicht oder zu schwach verschlüsselt.
Real-World-Beispiel: LinkedIn 2012 - 117 Millionen Passwort-Hashes gestohlen. Ohne Salt mit SHA-1 gehasht → 90% in Stunden geknackt.
SHA-1 ohne Salt lässt sich mit Rainbow Tables in Sekunden knacken. Die OWASP-empfohlene Alternative sind speziell gehärtete Passwort-Hashing-Algorithmen:
import bcrypt
# bcrypt mit automatischem Salt, Work Factor 12
password_hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(rounds=12))
# Alternativ (OWASP empfohlen): Argon2id
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=4)
hash = ph.hash(password)
Weitere Maßnahmen:
- TLS 1.3 für alle Verbindungen (kein TLS 1.0/1.1)
- Festplattenverschlüsselung für Datenbankserver
- Keine sensitiven Daten in Logs, URLs oder Browser-History
A03: Injection - Angreifer injizieren Code
Was es ist: User-Input wird ohne ausreichende Validierung in Interpreter-Befehle eingebettet.
SQL Injection ist der Klassiker: Ein Request wie GET /user?id=1' OR '1'='1 kann die Query SELECT * FROM users WHERE id = '1' OR '1'='1' erzeugen und damit alle Nutzer zurückgeben. Das Grundprinzip gilt genauso für NoSQL, LDAP und andere Interpreter.
NoSQL Injection (MongoDB) funktioniert über manipulierte JSON-Objekte: Wenn password nicht als String validiert wird, kann ein Angreifer { "$ne": null } senden und ohne Passwort einloggen. Schema-Validierung mit Joi oder ähnlichen Bibliotheken verhindert dies.
Immer Parameterized Queries verwenden:
# SQLite - IMMER so:
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
# NIEMALS:
cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")
A04: Insecure Design - Sicherheit in der Architektur
Was es ist: Grundlegende Designentscheidungen die Sicherheit unmöglich machen.
Beispiel: Rate Limiting fehlt auf Login-Endpoint → Brute Force mit 10.000 Versuchen/Sekunde möglich.
Threat Modeling (STRIDE) sollte bereits beim Design stattfinden. Für jedes neue Feature sind sechs Fragen zu stellen:
- S - Spoofing: Kann jemand sich als anderer User ausgeben?
- T - Tampering: Können Daten manipuliert werden?
- R - Repudiation: Können Aktionen abgestritten werden?
- I - Information Disclosure: Können Daten gelesen werden?
- D - Denial of Service: Kann der Dienst gestört werden?
- E - Elevation of Privilege: Können Rechte eskaliert werden?
A05: Security Misconfiguration - Falsche Standardeinstellungen
Was es ist: Default-Konfigurationen die unsicher sind.
# FALSCH (nginx):
server_tokens on; # Zeigt nginx-Version - gibt Angreifern Infos
# RICHTIG:
server_tokens off;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
Häufige weitere Fehler: Debug-Modus in Produktion (DEBUG = True in Django, NODE_ENV = 'development' in Node.js), offene Administrations-Interfaces und Standard-Credentials. Alle sensitiven Features müssen in Produktion explizit deaktiviert werden.
A06: Vulnerable and Outdated Components - Log4Shell lässt grüßen
Was es ist: Third-Party-Libraries mit bekannten CVEs.
Log4Shell (CVE-2021-44228) war vermeidbar, wenn Software Composition Analysis (SCA) in der Pipeline aktiv gewesen wäre - die CVE-Datenbank hatte die Schwachstelle am Tag der Veröffentlichung. Wöchentliche Dependency-Checks in CI/CD sind der Minimalstandard:
npm audit --audit-level=high # Node.js
pip-audit # Python
./gradlew dependencyCheckAnalyze # Java
Automatische PRs für Dependency-Updates lassen sich mit GitHub Dependabot oder Renovate Bot konfigurieren.
A07: Identification and Authentication Failures
Was es ist: Schwachstellen in Authentifizierung und Session Management.
JWT Sicherheitsfalle: Wird beim Verify-Aufruf kein Algorithmus explizit angegeben, könnte ein manipuliertes Token mit dem Algorithmus "none" akzeptiert werden:
// GEFÄHRLICH: Algorithmus nicht explizit angegeben
jwt.verify(token, secret);
// SICHER:
jwt.verify(token, secret, { algorithms: ["HS256"] });
Session-Cookies müssen mit den richtigen Flags gesetzt werden:
res.cookie("session", token, {
httpOnly: true, // Kein JavaScript-Zugriff (XSS-Schutz)
secure: true, // Nur HTTPS
sameSite: "Strict", // CSRF-Schutz
maxAge: 3600000, // 1 Stunde (kein "niemals ablaufen")
});
A08: Software and Data Integrity Failures - Supply Chain
Was es ist: Keine Integritätsprüfung von Software-Updates und CI/CD-Pipelines.
Subresource Integrity (SRI) schützt vor kompromittierten CDNs: Ein eingebundenes Script ohne SRI-Hash kann durch einen kompromittierten CDN-Knoten durch beliebigen Code ersetzt werden. Mit SRI wird beim Laden des Scripts der Hash geprüft und eine Manipulation erkannt:
<script
src="https://cdn.example.com/jquery.min.js"
integrity="sha384-hash..."
crossorigin="anonymous"
></script>
Für Git-Repositories empfehlen sich signierte Commits (git config --global commit.gpgsign true), damit Manipulationen an der Commit-Historie erkennbar werden.
A09: Security Logging and Monitoring Failures
Was es ist: Angriffe werden nicht erkannt weil Logging fehlt.
# Erfolgreiche und fehlgeschlagene Logins
logger.info("LOGIN_SUCCESS", extra={"user_id": user.id, "ip": request.remote_addr})
logger.warning("LOGIN_FAILURE", extra={"username": username, "ip": request.remote_addr})
# Admin-Aktionen (Wer hat Was verändert?)
logger.info("ADMIN_ACTION", extra={
"actor": current_user.id,
"action": "USER_DELETED",
"target_user": user_id,
"timestamp": datetime.utcnow().isoformat()
})
# NIEMALS loggen:
# - Passwörter (auch nicht gehashte)
# - Session-Tokens
# - Vollständige Kreditkartennummern
A10: Server-Side Request Forgery (SSRF)
Was es ist: Server wird als Proxy missbraucht um auf interne Ressourcen zuzugreifen.
Gefährlichstes Target: Cloud Metadata Service. Ein Angreifer, der eine SSRF-Schwachstelle ausnutzt, kann einen Request wie POST /api/fetch mit der URL http://169.254.169.254/latest/meta-data/iam/security-credentials/ absetzen und erhält darüber die IAM Credentials des Servers zurück.
Schutz durch Allowlist und IP-Filterung:
import ipaddress
from urllib.parse import urlparse
ALLOWED_DOMAINS = {"api.approved-partner.com", "cdn.company.de"}
def validate_url(url: str) -> bool:
parsed = urlparse(url)
if parsed.scheme not in ("http", "https"):
return False
# Cloud-Metadata-Adressen blockieren
blocked_ips = [
ipaddress.ip_network("169.254.169.254/32"), # AWS/Azure/GCP Metadata
ipaddress.ip_network("10.0.0.0/8"), # Private IPs
ipaddress.ip_network("192.168.0.0/16"),
]
# Allowlist nutzen statt Blocklist
return parsed.hostname in ALLOWED_DOMAINS
OWASP Top 10 im Pentest-Kontext
Bei jedem AWARE7-Web-Applikations-Penetrationstest werden alle OWASP Top 10-Kategorien systematisch geprüft - nach dem OWASP Web Security Testing Guide (WSTG). Das Ergebnis ist ein Bericht mit:
- CVSS v4.0 Score für jede Schwachstelle
- Proof-of-Concept der ausnutzbaren Schwachstellen
- Reproduzierbare Schritte für Ihre Entwickler
- Priorisierte Handlungsempfehlungen
- Option auf Re-Test nach Behebung
PCI DSS 6.4 und BSI CON.10 fordern explizit OWASP-basierte Tests für Web-Applikationen.
Sie möchten wissen ob Ihre Web-Applikation die OWASP Top 10 besteht? In einem Web-Applikations-Penetrationstest prüfen wir systematisch alle Kategorien und liefern einen klaren Bericht mit priorisierten Maßnahmen.
Nächster Schritt
Unsere zertifizierten Sicherheitsexperten beraten Sie zu den Themen aus diesem Artikel, unverbindlich und kostenlos.
Kostenlos · 30 Minuten · Unverbindlich