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 v3.1 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
