🌐 Dieser Artikel ist auch verfügbar auf: English

OWASP Top 10:2025, alle Kategorien mit Beispielen erklärt

OWASP Top 10:2025, leicht erklärt mit Beispielen

Die OWASP Top 10 sind der wichtigste Wegweiser durch die Sicherheit von Webanwendungen. Sie fassen die zehn kritischsten Risiken zusammen, die Entwickler, Betreiber und Sicherheitsteams kennen müssen, bevor Angreifer sie ausnutzen. Seit Anfang 2026 gilt eine neue Ausgabe: die OWASP Top 10:2025. Sie ist final veröffentlicht, die vorherige Ausgabe 2021 wird von OWASP als überholt geführt.

Dieser Artikel bringt Sie auf den aktuellen Stand. Wir erklären alle zehn Kategorien der Edition 2025 mit einer Erläuterung, einem konkreten Code-Beispiel und einer Gegenmaßnahme, editionsscharf und mit den offiziellen Kennzahlen von owasp.org. Zusätzlich zeigen wir in einem eigenen Abschnitt genau, was sich von 2021 auf 2025 geändert hat: welche Kategorie umbenannt, verschoben, zusammengelegt oder neu aufgenommen wurde.

Wenn Sie tiefer in eine einzelne Schwachstelle einsteigen möchten, verlinken wir aus jeder Kategorie auf einen weiterführenden Fachartikel. So dient dieser Beitrag zugleich als Übersicht und als Einstiegspunkt für die Praxis. Geben Sie Angreifern nicht die niedrig hängenden Früchte.

Was ist die OWASP Top 10?

Die OWASP Top 10 ist ein Standarddokument des Open Web Application Security Project (OWASP), einer gemeinnützigen Community, die frei verfügbare Sicherheitsressourcen pflegt. Die Liste benennt die zehn kritischsten Sicherheitsrisiken für Webanwendungen und wird etwa alle vier Jahre auf Basis realer Daten aktualisiert. Sie ist kein vollständiger Sicherheitskatalog, sondern ein Sensibilisierungsdokument: Sie soll Teams auf die häufigsten und gefährlichsten Schwachstellen aufmerksam machen und bewährte Gegenmaßnahmen an die Hand geben.

Für die Ausgabe 2025 wertete OWASP nach eigenen Angaben rund 175.000 Datensätze aus über 2,8 Millionen Anwendungen aus und analysierte 589 verschiedene Schwachstellenklassen (CWEs), von denen 248 in die zehn Kategorien einsortiert wurden. Das Auswahlverfahren ist laut OWASP "datenbasiert, aber nicht blind datengetrieben": Acht der zehn Kategorien ergeben sich direkt aus den Daten, zwei weitere werden über eine Community-Umfrage aufgenommen, um aufkommende Risiken früh sichtbar zu machen.

Wichtig für das Verständnis der Zahlen: Jede Kennzahl gehört untrennbar zu ihrer Edition und ihrer Metrik-Definition. Eine Häufigkeit (Incidence) von 3,74 Prozent aus der Edition 2025 lässt sich nicht mit einer Zahl aus 2021 verrechnen, weil sich Datensatz, Methodik und Kategorienzuschnitt geändert haben. Wir kennzeichnen deshalb jede Zahl mit ihrer Edition.

Editions-Status: 2025 ist final, 2021 ist überholt

Die OWASP Top 10:2025 ist die achte Ausgabe der Liste und offiziell final. Das belegt das offizielle GitHub-Repository von OWASP, dessen README die Ausgabe als "RELEASED" und "Final" markiert und die Ausgabe 2021 als "SUPERSEDED" (überholt) führt. Auch die Projektseite auf owasp.org nennt die Edition 2025 als aktuellste veröffentlichte Version und 2021 als Vorgängerversion.

Ein tagesgenaues Erstveröffentlichungsdatum dokumentiert OWASP auf der eigenen Website nicht. Laut Sekundärquellen wurde ein Release Candidate am 6. November 2025 auf der Global AppSec Conference vorgestellt und die finale Fassung Anfang 2026 veröffentlicht. Diese Datumsangaben stammen nicht von OWASP selbst, sondern aus Drittquellen, weshalb wir sie ausdrücklich als "laut Sekundärquelle" kennzeichnen. Gesichert ist: Zum jetzigen Zeitpunkt ist 2025 die maßgebliche, aktuelle Edition.

Ein praktischer Hinweis: Für die Edition 2025 gibt es bislang keine offizielle deutsche OWASP-Übersetzung, nur Englisch und Japanisch. Die englischen Kategorienamen sind daher der verbindliche Anker. Wir nennen sie im Original und ergänzen eine deutsche Erklärung, damit Sie beide Fassungen zuordnen können.

Was sich von 2021 zu 2025 geändert hat

Netto bringt die Edition 2025 laut OWASP zwei neue Kategorien und eine Zusammenlegung. Neu sind Software Supply Chain Failures und Mishandling of Exceptional Conditions. Zusammengelegt wurde Server-Side Request Forgery (SSRF), die frühere eigenständige Kategorie A10:2021, die jetzt in Broken Access Control aufgeht. Die folgende Tabelle zeigt für jede Position, welcher Name 2025 dort steht und was sich gegenüber 2021 verändert hat.

Platz20212025Änderung
A01Broken Access ControlBroken Access Controlunverändert Platz 1, absorbiert jetzt SSRF (vormals A10:2021)
A02Cryptographic FailuresSecurity MisconfigurationSecurity Misconfiguration steigt von Platz 5 auf Platz 2
A03InjectionSoftware Supply Chain Failuresneue Kategorie, Erweiterung von "Vulnerable and Outdated Components" (A06:2021)
A04Insecure DesignCryptographic FailuresCryptographic Failures fällt von Platz 2 auf Platz 4
A05Security MisconfigurationInjectionInjection fällt von Platz 3 auf Platz 5
A06Vulnerable and Outdated ComponentsInsecure DesignInsecure Design fällt von Platz 4 auf Platz 6
A07Identification and Authentication FailuresAuthentication Failuresgleiche Position, umbenannt (kürzer gefasst)
A08Software and Data Integrity FailuresSoftware or Data Integrity Failuresgleiche Position, minimale Namensänderung ("and" zu "or")
A09Security Logging and Monitoring FailuresSecurity Logging and Alerting Failuresgleiche Position, umbenannt ("Monitoring" zu "Alerting")
A10Server-Side Request Forgery (SSRF)Mishandling of Exceptional ConditionsSSRF entfällt als eigene Kategorie und geht in A01 auf, A10:2025 ist komplett neu

So lesen Sie die Tabelle richtig: Die Zeilen sind keine direkten Nachfolger. Nur bei A01, A07, A08 und A09 steht 2025 dieselbe Kategorie an derselben Position wie 2021. Die übrigen Zeilen zeigen lediglich, welcher Kategoriename an welcher Positionsnummer steht. So rückte etwa Security Misconfiguration von Platz 5 auf Platz 2 vor, während Cryptographic Failures und Injection nach unten rutschten.

Die wichtigsten inhaltlichen Punkte im Klartext:

  • Neu, A03:2025 Software Supply Chain Failures: OWASP hat die frühere Kategorie "Vulnerable and Outdated Components" deutlich erweitert. Es geht nicht mehr nur um bekannte Schwachstellen in Bibliotheken, sondern um die gesamte Lieferkette: Abhängigkeiten, Build-Systeme und Verteilinfrastruktur. In der Community-Umfrage setzten 50 Prozent der Befragten dieses Risiko auf Platz 1.
  • Neu, A10:2025 Mishandling of Exceptional Conditions: eine komplett neue Kategorie mit 24 CWEs. Sie bündelt fehlerhafte Fehlerbehandlung, logische Fehler und das "Failing Open", also das unsichere Öffnen bei Ausnahmezuständen.
  • Zusammengelegt, SSRF: Bereits 2021 hatte OWASP prognostiziert, dass die kleine SSRF-Kategorie später in eine größere aufgehen könnte. Genau das ist 2025 geschehen: SSRF ist jetzt Teil von Broken Access Control.

Im Folgenden gehen wir alle zehn Kategorien der Edition 2025 der Reihe nach durch.

A01:2025 Broken Access Control

Erläuterung

Eine unzureichende Zugriffskontrolle liegt vor, wenn eine Anwendung nicht korrekt durchsetzt, welche Aktionen ein Benutzer ausführen darf. Dann können unbefugte Personen auf Ressourcen zugreifen oder diese verändern, obwohl ihnen das eigentlich verwehrt sein sollte. Die Folgen reichen von Datendiebstahl über unerlaubte Aktionen bis zur Preisgabe vertraulicher Informationen. Typische Ursachen sind fehlende serverseitige Berechtigungsprüfungen, Vertrauen auf clientseitige Kontrollen oder Funktionen, die direkt über manipulierbare URLs erreichbar sind.

Broken Access Control steht in der Edition 2025 unverändert auf Platz 1, mit 40 zugeordneten CWEs (der maximal zulässigen Zahl) und einer durchschnittlichen Häufigkeit von 3,74 Prozent im 2025er Datensatz. Laut OWASP wurde in mindestens einer getesteten Anwendung in dieser Kategorie eine hundertprozentige Testabdeckung erreicht. Neu ist, dass Server-Side Request Forgery (SSRF, vormals A10:2021) jetzt hier aufgeht. Zu den prägenden Schwachstellenklassen zählen CWE-200 (Preisgabe sensibler Informationen), CWE-352 (Cross-Site Request Forgery) und CWE-918 (SSRF).

Beispiel

Stellen Sie sich eine Anwendung vor, in der Nutzer ihr Profil unter /user/profile/123 abrufen. Prüft die Anwendung nicht, ob der anfragende Nutzer auch Eigentümer des Profils ist, kann ein Angreifer die URL einfach auf /user/profile/124 ändern und fremde Daten einsehen. Das ist eine Insecure Direct Object Reference (IDOR), einer der häufigsten Fälle von Broken Access Control.

# Flask-Beispiel ohne Zugriffskontrolle
@app.route('/user/profile/<int:user_id>')
def user_profile(user_id):
    user = users.get(user_id)
    if user:
        return jsonify(user)
    return "User not found", 404

In diesem verwundbaren Beispiel wird nicht geprüft, ob der anfragende Nutzer die angeforderten Daten überhaupt sehen darf. Wie IDOR-Angriffe im Detail funktionieren und wie Sie sie systematisch testen, lesen Sie in unserem Beitrag zu Broken Access Control und IDOR.

Maßnahme

# Flask-Beispiel mit Zugriffskontrolle
@app.route('/user/profile/<int:user_id>')
def user_profile(user_id):
    logged_in_user_id = session.get('user_id')
    if logged_in_user_id != user_id:
        return "Forbidden", 403
    user = users.get(user_id)
    if user:
        return jsonify(user)
    return "User not found", 404

Die sichere Variante prüft serverseitig, ob die ID des angemeldeten Nutzers mit der angeforderten Profil-ID übereinstimmt, und verweigert andernfalls den Zugriff. Grundregel: Verweigern Sie standardmäßig (deny by default) und erzwingen Sie jede Berechtigungsprüfung auf dem Server, niemals nur im Browser.

Weil SSRF nun Teil dieser Kategorie ist, gehört auch die folgende Situation hierher: Eine Anwendung ruft eine vom Nutzer angegebene URL ab, etwa um ein Bild zu laden. Ohne Einschränkung kann ein Angreifer eine interne Adresse angeben und so auf nicht öffentliche Dienste zugreifen.

# Sichere URL-Prüfung gegen SSRF (Positivliste)
import requests
from urllib.parse import urlparse

ALLOWED_DOMAINS = ['example.com']

def is_allowed_url(url):
    parsed_url = urlparse(url)
    return parsed_url.hostname in ALLOWED_DOMAINS

def fetch_image(url):
    if not is_allowed_url(url):
        raise ValueError("URL is not allowed")
    response = requests.get(url)
    if response.status_code == 200:
        with open('image.jpg', 'wb') as f:
            f.write(response.content)

Eine Positivliste (Allowlist) zulässiger Ziele ist gegenüber Sperrlisten klar im Vorteil, denn Angreifer verfügen über umfangreiche Umgehungslisten für Deny-Regeln.

In API-Umgebungen tragen dieselben Autorisierungsfehler eigene Namen: Broken Object Level Authorization (BOLA) steht für fehlende Objektprüfungen und Broken Function Level Authorization (BFLA) für fehlende Funktionsprüfungen an einzelnen Endpunkten. Wie Sie diese API-Autorisierungsmuster gezielt absichern, zeigt unser Beitrag zur API-Sicherheit nach den OWASP Top 10.

Realer Fall: Beim Datenabfluss bei Capital One (2019) nutzte die Täterin eine Server-Side Request Forgery, um über eine fehlkonfigurierte Web Application Firewall den Metadatendienst der AWS-Cloud zu erreichen und temporäre Zugangsschlüssel abzugreifen. Damit wurden laut Anklage des US-Justizministeriums Daten von rund 106 Millionen Kunden in den USA und Kanada ausgelesen. Der Fall zeigt, warum SSRF in der Edition 2025 als Zugriffskontrollproblem in A01 aufgeht. Auch großflächiges Scraping wie bei Facebook (2021, laut Medienberichten rund 533 Millionen Datensätze) verdeutlicht, wie fehlende Zugriffs- und Ratengrenzen massenhaft Daten preisgeben.

A02:2025 Security Misconfiguration

Erläuterung

Eine Sicherheitsfehlkonfiguration entsteht, wenn eine Anwendung oder ihre Umgebung nicht sicher eingerichtet ist: Standardpasswörter bleiben aktiv, unnötige Dienste sind offen, Fehlermeldungen verraten interne Details oder Härtungsmaßnahmen fehlen. Solche Fehler sind weit verbreitet und oft leicht auszunutzen, weil sie keine ausgefeilten Angriffstechniken erfordern.

In der Edition 2025 ist Security Misconfiguration von Platz 5 (2021) auf Platz 2 vorgerückt, weil Fehlkonfigurationen in den aktuellen Daten häufiger auftreten. Die Kategorie umfasst 16 CWEs bei einer durchschnittlichen Häufigkeit von 3,00 Prozent im 2025er Datensatz. Prägend sind CWE-16 (Konfiguration) und CWE-611 (XML External Entities, XXE).

Beispiel

Ein klassisches Beispiel ist ein Webserver, der das Auflisten von Verzeichnissen erlaubt. Sind dort sensible Dateien abgelegt, werden sie so für jeden sichtbar. In einer Apache-Konfiguration sieht die riskante Einstellung so aus:

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

Durch Options Indexes kann der Inhalt jedes Verzeichnisses unterhalb von /var/www/html aufgelistet werden.

Maßnahme

<Directory "/var/www/html">
    Options -Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

Die Direktive Options -Indexes deaktiviert das Verzeichnislisting. Ergänzend gehören zu einer soliden Härtung: Standard-Anmeldedaten ändern, nicht benötigte Funktionen und Ports abschalten, aussagekräftige aber nicht verräterische Fehlermeldungen, sowie ein wiederholbarer, dokumentierter Härtungsprozess für alle Umgebungen.

A03:2025 Software Supply Chain Failures

Erläuterung

Software Supply Chain Failures ist eine der beiden neuen Kategorien der Edition 2025. Sie erweitert die frühere Kategorie "Vulnerable and Outdated Components" (A06:2021) erheblich. Es geht nicht mehr nur um bekannte Schwachstellen in eingebundenen Bibliotheken, sondern um die gesamte Software-Lieferkette: Abhängigkeiten, Build-Systeme, Paketregister und Verteilinfrastruktur. Ein manipuliertes Paket, ein kompromittierter Build-Server oder ein gekapertes Entwicklerkonto kann so bösartigen Code in tausende nachgelagerte Anwendungen tragen.

OWASP verankert die Kategorie historisch: Sie tauchte bereits 2013 als "Using Components with Known Vulnerabilities" auf und ist seither in ihrem Umfang gewachsen. In der Community-Umfrage zur Edition 2025 setzten 50 Prozent der Befragten dieses Risiko auf Platz 1. Datenseitig umfasst die Kategorie 6 CWEs, nur 11 zugeordnete CVEs, aber mit 5,72 Prozent die höchste durchschnittliche Häufigkeit aller Kategorien im 2025er Datensatz (der OWASP-Intro-Fließtext nennt abweichend 5,19 Prozent; 5,72 Prozent ist der Wert aus der Score-Tabelle).

Beispiel

Ein häufiges Problem ist das ungenaue Einbinden von Abhängigkeiten ohne feste Version und ohne Integritätsprüfung. Wenn eine Anwendung Pakete zur Laufzeit in beliebigen kompatiblen Versionen zieht, kann eine kompromittierte oder untergeschobene Version unbemerkt einfließen:

{
  "dependencies": {
    "left-pad": "*",
    "some-utils": "^1.0.0"
  }
}

Der Platzhalter * und der Caret-Bereich ^ erlauben, dass beim nächsten Build automatisch eine neue, ungeprüfte Version installiert wird. Fehlt zusätzlich eine Lockfile mit Integritäts-Hashes, gibt es keine Garantie, dass alle Beteiligten exakt denselben, geprüften Stand bauen.

Maßnahme

Pinnen Sie Abhängigkeiten auf feste Versionen und committen Sie eine Lockfile, die kryptografische Integritäts-Hashes je Paket enthält:

{
  "name": "some-utils",
  "version": "1.0.3",
  "resolved": "https://registry.npmjs.org/some-utils/-/some-utils-1.0.3.tgz",
  "integrity": "sha512-0Xa1b2C3..."
}

Ergänzend gehören zu einer robusten Lieferketten-Absicherung: eine Software Bill of Materials (SBOM), automatisiertes Scannen auf bekannte Schwachstellen in der CI/CD-Pipeline, signierte Artefakte und minimal berechtigte Build-Systeme. Wie sich Lockfiles zwischen npm, Yarn und pnpm unterscheiden und warum sie für reproduzierbare Builds zentral sind, erklären wir im Beitrag zu Lockfiles.

Für das systematische Verfolgen bekannter Schwachstellen in eingebundenen Komponenten hilft unser CVE-Leitfaden.

Realer Fall: Beim Equifax-Datenabfluss (2017) drangen Angreifer über eine seit Monaten bekannte, aber ungepatchte Lücke im Web-Framework Apache Struts (CVE-2017-5638) ein. Laut der US-Handelsbehörde FTC waren rund 147 Millionen Menschen betroffen. Der Fall steht exemplarisch für das Kernrisiko von A03: eine verwundbare, veraltete Komponente in der Lieferkette, die nicht rechtzeitig aktualisiert wurde.

A04:2025 Cryptographic Failures

Erläuterung

Kryptografische Fehler treten auf, wenn Anwendungen Verschlüsselung falsch oder unzureichend einsetzen. Sensible Daten wie Passwörter, personenbezogene Informationen oder Finanzdaten müssen sowohl bei der Übertragung als auch bei der Speicherung geschützt sein. Typische Fehler sind veraltete Algorithmen, fehlende Transportverschlüsselung, schlechte Schlüsselverwaltung und selbst gebaute Krypto-Verfahren ohne fachliche Prüfung.

In der Edition 2025 ist Cryptographic Failures von Platz 2 (2021) auf Platz 4 gerutscht. Die Kategorie umfasst 32 CWEs bei einer durchschnittlichen Häufigkeit von 3,80 Prozent im 2025er Datensatz. Prägend sind CWE-327 (unsicherer Krypto-Algorithmus), CWE-331 (unzureichende Entropie) und CWE-338 (kryptografisch schwacher Zufallsgenerator).

Beispiel

Ein häufiger Fehler ist das Speichern von Passwörtern mit einem schwachen Hash-Verfahren wie MD5. Solche Hashes lassen sich mit vorberechneten Tabellen (Rainbow Tables) schnell zurückrechnen.

# Schwaches MD5-Hashing (unsicher)
import hashlib

def hash_password(password):
    return hashlib.md5(password.encode()).hexdigest()

MD5 gilt als unsicher, weil es anfällig für Kollisionen und vorberechnete Angriffe ist und viel zu schnell rechnet.

Maßnahme

# Starkes Hashing mit bcrypt
import bcrypt

def hash_password(password):
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt())

Verwenden Sie für Passwörter dedizierte, langsame Verfahren wie bcrypt, scrypt oder Argon2, die automatisch salzen und sich gegen Brute-Force-Angriffe wehren. Für Daten im Transit ist eine korrekt konfigurierte TLS-Verschlüsselung Pflicht. Die Grundlagen dazu erklären wir im Beitrag zu HTTPS.

A05:2025 Injection

Erläuterung

Injection-Schwachstellen entstehen, wenn eine Anwendung nicht vertrauenswürdige Eingaben ungeprüft in einen Interpreter gibt, etwa in eine SQL-Abfrage, einen HTML-Kontext oder einen Systembefehl. Angreifer können dann eigene Befehle einschleusen und Daten auslesen, verändern oder das System übernehmen. Zur Kategorie gehören unter anderem SQL-Injection (seltener, aber hoher Schaden) und Cross-Site Scripting (sehr häufig, meist geringerer Einzelschaden).

In der Edition 2025 ist Injection von Platz 3 (2021) auf Platz 5 gerutscht, bleibt aber mit 62.445 zugeordneten CVEs die CVE-reichste Kategorie überhaupt. Sie umfasst 37 CWEs bei einer durchschnittlichen Häufigkeit von 3,08 Prozent im 2025er Datensatz. Laut OWASP entfallen auf Cross-Site Scripting mehr als 30.000 CVEs und auf SQL-Injection mehr als 14.000 CVEs.

Beispiel

Baut eine Anwendung ihre SQL-Abfrage per String-Verkettung aus Benutzereingaben, kann ein Angreifer die Abfragelogik verändern:

# SQLite mit direkter Benutzereingabe in der Abfrage (unsicher)
import sqlite3

def search_items(keyword):
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    query = f"SELECT * FROM items WHERE name LIKE '{keyword}'"
    cursor.execute(query)
    return cursor.fetchall()

# Beispielaufruf mit eingeschleuster Bedingung
items = search_items("wert' OR '1'='1")

Mit der Eingabe wert' OR '1'='1 wird die Bedingung immer wahr, sodass die Abfrage sämtliche Datensätze zurückgibt. Wie solche Angriffe im Detail ablaufen, zeigt unser Beitrag zu den SQL-Injection-Grundlagen.

Maßnahme

# SQLite mit parametrisierter Abfrage (sicher)
import sqlite3

def search_items(keyword):
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    query = "SELECT * FROM items WHERE name LIKE ?"
    cursor.execute(query, (f"%{keyword}%",))
    return cursor.fetchall()

Parametrisierte Abfragen trennen Code und Daten sauber: Die Eingabe wird als reiner Wert behandelt und kann die Abfragestruktur nicht mehr verändern. Für andere Injection-Kontexte gelten jeweils eigene Schutzmaßnahmen.

Bei HTML-Ausgaben verhindert kontextabhängiges Escaping Cross-Site Scripting.

Bei Systembefehlen schützt der Verzicht auf Shell-Aufrufe mit Benutzereingaben vor Remote Code Execution.

Bei Dateipfaden verhindert strikte Validierung Local und Remote File Inclusion.

A06:2025 Insecure Design

Erläuterung

Unsicheres Design bezeichnet Sicherheitsmängel, die bereits in der Konzeption einer Anwendung angelegt sind, nicht erst in der Programmierung entstehen. Wenn Bedrohungen nicht durchdacht, Geschäftsregeln nicht serverseitig erzwungen oder Missbrauchsszenarien nicht bedacht werden, hilft auch sauberer Code nichts. Insecure Design lässt sich nicht durch spätere Fehlerkorrekturen beheben, sondern nur durch ein besseres Grundkonzept.

In der Edition 2025 ist Insecure Design von Platz 4 (2021) auf Platz 6 gerutscht, weil Security Misconfiguration und Software Supply Chain Failures daran vorbeigezogen sind. Die Kategorie umfasst 39 CWEs bei einer durchschnittlichen Häufigkeit von 1,86 Prozent im 2025er Datensatz und betont Bedrohungsmodellierung sowie sichere Entwurfsmuster.

Beispiel

Ein typischer Designfehler ist eine kritische Geschäftsfunktion ohne serverseitige Regeldurchsetzung. Nehmen wir eine Überweisungsfunktion, die sich allein auf ein Limit im Browser verlässt:

# Unsicheres Design: keine serverseitige Prüfung der Geschäftsregel
@app.route('/transfer', methods=['POST'])
def transfer():
    amount = float(request.form['amount'])
    # Das Tageslimit wird nur im Frontend geprueft, nicht hier
    execute_transfer(current_user, request.form['to'], amount)
    return "Transfer done"

Da das Limit nur im Frontend geprüft wird, kann ein Angreifer die Anfrage direkt an den Server schicken und beliebige Beträge überweisen. Das Problem liegt nicht in einer einzelnen Codezeile, sondern im Entwurf: Die Sicherheitsregel wurde an der falschen Stelle verankert.

Maßnahme

# Sicheres Design: Geschaeftsregel serverseitig erzwingen
DAILY_LIMIT = 10000

@app.route('/transfer', methods=['POST'])
def transfer():
    amount = float(request.form['amount'])
    if amount <= 0 or spent_today(current_user) + amount > DAILY_LIMIT:
        return "Transfer denied", 403
    execute_transfer(current_user, request.form['to'], amount)
    return "Transfer done"

Sicheres Design bedeutet, Bedrohungen früh zu modellieren, Geschäftsregeln immer serverseitig zu erzwingen und Missbrauch von Anfang an einzuplanen (Rate Limits, Plausibilitätsprüfungen, klare Vertrauensgrenzen). Ein bewährtes Leitprinzip dafür ist die Zero-Trust-Architektur, die niemandem implizit vertraut.

A07:2025 Authentication Failures

Erläuterung

Authentication Failures (2021 noch "Identification and Authentication Failures") umfassen alle Schwächen, mit denen Angreifer die Identitätsprüfung aushebeln: schwache Passwortregeln, unsichere Sitzungsverwaltung, fehlender Schutz gegen automatisiertes Durchprobieren (Credential Stuffing, Brute Force) und unsichere Speicherung von Zugangsdaten. OWASP hat den Namen 2025 gekürzt, um die 36 CWEs der Kategorie treffender abzubilden.

Die Kategorie bleibt auf Platz 7, mit 36 CWEs und einer durchschnittlichen Häufigkeit von 2,92 Prozent im 2025er Datensatz. Prägend sind unter anderem CWE-287 (unsachgemäße Authentifizierung) und CWE-384 (Session Fixation).

Beispiel

Schwache Authentifizierung zeigt sich oft in zwei Fehlern zugleich: unsicheres Passwort-Hashing und vorhersehbare Sitzungskennungen.

# Unsichere Passwortspeicherung und Sitzungsverwaltung
import hashlib
import random
import string

def hash_password(password):
    return hashlib.md5(password.encode()).hexdigest()  # schwaches Hashing

def generate_session_id():
    return ''.join(random.choices(string.ascii_letters + string.digits, k=8))  # vorhersehbar

MD5 ist zu schwach für Passwörter, und eine kurze, mit einem nicht-kryptografischen Zufallsgenerator erzeugte Sitzungs-ID lässt sich erraten oder durchprobieren.

Maßnahme

# Sichere Passwortspeicherung und Sitzungsverwaltung
import bcrypt
import secrets

def hash_password(password):
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt())  # starkes Hashing

def generate_session_id():
    return secrets.token_urlsafe(16)  # kryptografisch sicher

bcrypt schützt die Passwörter, das Modul secrets erzeugt unvorhersehbare Sitzungskennungen. Den stärksten Zugewinn bringt aber ein zweiter Faktor. Wie Sie ihn richtig einsetzen, lesen Sie im Beitrag zur Multi-Faktor-Authentifizierung.

Noch robuster gegen Phishing sind Passkeys nach dem FIDO2-Standard, die ganz ohne wiederverwendbares Passwort auskommen.

A08:2025 Software or Data Integrity Failures

Erläuterung

Integritätsfehler bei Software oder Daten entstehen, wenn Systeme Aktualisierungen, kritische Daten oder Deployment-Vorgänge übernehmen, ohne deren Echtheit und Unversehrtheit zu prüfen. Werden etwa Software-Updates ohne Signaturprüfung installiert oder untrusted Daten deserialisiert, können Angreifer Schadcode einschleusen. Der Name änderte sich 2025 minimal von "and" zu "or", die Kategorie bleibt auf Platz 8.

Sie fokussiert Vertrauensgrenzen auf einer tieferen Ebene als die Lieferketten-Kategorie A03. In der Edition 2025 umfasst sie 14 CWEs bei einer durchschnittlichen Häufigkeit von 2,75 Prozent im 2025er Datensatz. Prägend sind CWE-502 (Deserialisierung nicht vertrauenswürdiger Daten), CWE-494 (Code-Download ohne Integritätsprüfung) und CWE-829 (Einbindung von Funktionalität aus nicht vertrauenswürdiger Quelle).

Beispiel

Eine Anwendung lädt ein Update herunter und führt es aus, ohne die Datei zu prüfen:

# Unsicherer Update-Prozess ohne Integritaetspruefung
import requests

def download_update(url):
    response = requests.get(url)
    with open('update.zip', 'wb') as f:
        f.write(response.content)
    # keine Integritaetspruefung

Wer den Download abfängt oder den Server kompromittiert, kann eine bösartige Version unterschieben.

Maßnahme

# Sicherer Update-Prozess mit Integritaetspruefung
import requests
import hashlib

def verify_file_integrity(file_path, expected_hash):
    sha256_hash = hashlib.sha256()
    with open(file_path, 'rb') as f:
        for chunk in iter(lambda: f.read(4096), b""):
            sha256_hash.update(chunk)
    return sha256_hash.hexdigest() == expected_hash

def download_update(url, expected_hash):
    response = requests.get(url)
    with open('update.zip', 'wb') as f:
        f.write(response.content)
    if not verify_file_integrity('update.zip', expected_hash):
        raise ValueError("File integrity check failed")

Die Anwendung vergleicht den Hash der geladenen Datei mit einem erwarteten SHA-256-Wert und lehnt manipulierte Downloads ab. In der Praxis kommen Signaturen und vertrauenswürdige Verteilkanäle hinzu. Da Integritätsfehler eng mit Abhängigkeiten zusammenhängen, hilft auch hier ein Blick in unseren CVE-Leitfaden.

Ebenso wichtig für nachvollziehbare, unveränderte Abhängigkeitsstände sind reproduzierbare Builds über Lockfiles.

Realer Fall: Bei SolarWinds (2020) schleusten Angreifer über die kompromittierte Build-Pipeline der Orion-Software den Schadcode SUNBURST in ein regulär signiertes Update ein. Laut der US-Behörde CISA luden rund 18.000 Organisationen die manipulierte Version herunter. Weil das Update trotz gültiger Signatur nicht auf die Integrität seiner Herkunft geprüft wurde, ist der Fall ein Musterbeispiel für Software or Data Integrity Failures.

A09:2025 Security Logging and Alerting Failures

Erläuterung

Ohne ausreichende Protokollierung und, das betont die Edition 2025 im neuen Namen, ohne wirksame Alarmierung bleiben Angriffe oft lange unentdeckt. OWASP hat die Kategorie 2025 von "Monitoring" auf "Alerting" umbenannt, um klarzumachen: Protokolle ohne Alarmierung sind für die Erkennung von Vorfällen nur wenig wert. Fehlen Aufzeichnungen zu Anmeldeversuchen, Zugriffen und kritischen Änderungen, lassen sich Angriffe weder erkennen noch forensisch aufarbeiten.

Die Kategorie bleibt auf Platz 9, mit 5 CWEs und einer durchschnittlichen Häufigkeit von 3,91 Prozent im 2025er Datensatz. Sie stammt wie schon 2021 aus der Community-Umfrage.

Beispiel

Eine Authentifizierungsfunktion, die fehlgeschlagene Anmeldeversuche nicht protokolliert, liefert keine Spur für die Erkennung von Brute-Force-Angriffen:

# Ohne Protokollierung fehlgeschlagener Anmeldungen
def authenticate_user(username, password):
    user = get_user_from_database(username)
    if user and user.verify_password(password):
        return "Authentication successful"
    return "Authentication failed"

Maßnahme

# Mit Protokollierung fehlgeschlagener Anmeldungen
import logging

logging.basicConfig(filename='auth.log', level=logging.INFO)

def authenticate_user(username, password):
    user = get_user_from_database(username)
    if user and user.verify_password(password):
        logging.info(f"User {username} authenticated successfully")
        return "Authentication successful"
    logging.warning(f"Failed login attempt for user {username}")
    return "Authentication failed"

Die sichere Variante protokolliert Erfolg und Misserfolg. Entscheidend ist der zweite Schritt: Aus den Protokollen müssen automatische Alarme bei verdächtigen Mustern entstehen, etwa vielen Fehlversuchen in kurzer Zeit. Wie Organisationen Erkennung und Reaktion aufsetzen, ordnet unser Beitrag zu MDR, MSSP, EDR, XDR und NDR ein. Schützen Sie zudem die Protokolle selbst vor Manipulation und Löschung.

A10:2025 Mishandling of Exceptional Conditions

Erläuterung

Mishandling of Exceptional Conditions ist die zweite komplett neue Kategorie der Edition 2025. Sie bündelt Fehler im Umgang mit Ausnahmezuständen: unsauberes Exception-Handling, logische Fehler, verräterische Fehlermeldungen und vor allem das "Failing Open", also das unsichere Öffnen eines Systems, wenn etwas schiefgeht. OWASP hatte diese Schwächen früher unter dem zu allgemeinen Sammelbegriff "schlechte Codequalität" verortet und ihnen 2025 eine eigene, präzisere Kategorie gegeben.

Die Kategorie umfasst 24 CWEs bei einer durchschnittlichen Häufigkeit von 2,95 Prozent im 2025er Datensatz. Prägend sind CWE-209 (Preisgabe von Informationen über Fehlermeldungen), CWE-476 (NULL-Pointer-Dereferenzierung) und CWE-636 (Fehlschlagen ohne sicheren Zustand, "Failing Open").

Beispiel

Der gefährlichste Fall ist eine Zugriffsentscheidung, die bei einem Fehler zugunsten des Nutzers ausfällt. Wirft die Berechtigungsprüfung eine Ausnahme und fängt der Code sie zu großzügig ab, wird der Zugriff womöglich gewährt statt verweigert:

# Failing open: bei einem Fehler wird der Zugriff faelschlich gewaehrt
def is_authorized(user, resource):
    try:
        return check_permissions(user, resource)
    except Exception:
        return True  # falsch: oeffnet bei jedem Fehler

Zusätzlich verraten ungefilterte Fehlermeldungen oft interne Details wie Stack Traces oder Datenbankpfade, die einem Angreifer weiterhelfen.

Maßnahme

# Failing closed: bei einem Fehler wird der Zugriff verweigert
import logging

def is_authorized(user, resource):
    try:
        return check_permissions(user, resource)
    except Exception as e:
        logging.error(f"Permission check failed: {e}")
        return False  # sicher: verweigert im Zweifel

Sichere Systeme scheitern in einen sicheren Zustand hinein (fail closed): Bei einem Fehler wird der Zugriff verweigert, nicht gewährt. Fangen Sie Ausnahmen gezielt ab, protokollieren Sie den Fehler intern und geben Sie nach außen nur generische Meldungen ohne technische Details aus.

Verwandte OWASP-Projekte

Die Top 10 sind nur der Einstieg. OWASP und angrenzende Initiativen bieten weitere Ressourcen, die den Web-Fokus ergänzen:

  • OWASP API Security Top 10: ein eigenes Ranking speziell für API-Risiken, das Themen wie Broken Object Level Authorization vertieft. Details im Beitrag zur API-Sicherheit nach den OWASP Top 10.
  • OWASP Top 10 for LLM Applications: eine separate Liste für Risiken generativer KI, etwa Prompt Injection. Einen Einstieg bietet unser Beitrag zu den Grundlagen der Prompt Injection.
  • OWASP Cheat Sheet Series: kompakte, praxisnahe Umsetzungsleitfäden zu vielen der oben genannten Themen.
  • CWE Top 25 (MITRE): eine verwandte, aber breitere Liste. Während sich die OWASP Top 10 auf Webanwendungen konzentrieren, decken die CWE Top 25 die gefährlichsten Schwachstellenklassen über alle Softwarearten hinweg ab.

Werkzeuge zur Umsetzung der OWASP Top 10

Theorie allein sichert keine Anwendung ab. Erst der Einsatz passender Werkzeuge im Entwicklungsprozess macht die OWASP Top 10 praktisch wirksam. Sinnvoll ist eine Kombination aus statischer Analyse, dynamischen Tests und Abhängigkeitsprüfung:

  • Statische Codeanalyse (SAST): Werkzeuge wie SonarQube, Semgrep, CodeQL oder, für Python, Bandit finden riskante Muster direkt im Quellcode, etwa unsichere Funktionsaufrufe oder fehlende Validierung.
  • Dynamische Tests (DAST): OWASP ZAP (Zed Attack Proxy) prüft die laufende Anwendung auf Schwachstellen wie Cross-Site Scripting oder unsichere Weiterleitungen und lässt sich in CI/CD-Pipelines einbinden.
  • Abhängigkeitsprüfung (SCA): OWASP Dependency-Check und vergleichbare Werkzeuge melden bekannte Schwachstellen in eingebundenen Bibliotheken, wichtig besonders für A03 und A08.
  • Integration in die Pipeline: In Jenkins, GitLab CI oder GitHub Actions lassen sich diese Prüfungen automatisieren, sodass Schwachstellen früh und wiederholbar auffallen.

Häufige Fragen

Was ist die OWASP Top 10?

Die OWASP Top 10 ist ein Standarddokument des Open Web Application Security Project, das die zehn kritischsten Sicherheitsrisiken für Webanwendungen benennt. Sie ist kein vollständiger Sicherheitskatalog, sondern ein Sensibilisierungsdokument, das etwa alle vier Jahre auf Basis realer Daten aktualisiert wird. Maßgeblich ist derzeit die Edition 2025.

Was hat sich in der OWASP Top 10 2025 geändert?

Die Edition 2025 bringt zwei neue Kategorien und eine Zusammenlegung: Neu sind Software Supply Chain Failures (A03) und Mishandling of Exceptional Conditions (A10). Server-Side Request Forgery entfällt als eigene Kategorie und geht in Broken Access Control auf. Zusätzlich rückt Security Misconfiguration von Platz 5 auf Platz 2 vor, und mehrere Kategorien wurden umbenannt.

Ist die OWASP Top 10 2021 noch aktuell?

Nein. OWASP führt die Edition 2021 im offiziellen GitHub-Repository als "SUPERSEDED" (überholt) und die Edition 2025 als "RELEASED" und "Final". Für neue Projekte und Prüfungen sollten Sie sich an der Ausgabe 2025 orientieren.

Was ist die häufigste Schwachstelle laut OWASP?

Auf Platz 1 der Rangliste steht unverändert Broken Access Control, mit einer durchschnittlichen Häufigkeit von 3,74 Prozent im 2025er Datensatz. Die höchste durchschnittliche Häufigkeit aller Kategorien weisen mit 5,72 Prozent jedoch Software Supply Chain Failures auf. Die Platzierung ergibt sich aus mehreren Faktoren, nicht allein aus der Häufigkeit.

Wie setze ich die OWASP Top 10 praktisch um?

Kombinieren Sie statische Codeanalyse (SAST), dynamische Tests (DAST) und Abhängigkeitsprüfung (SCA) und binden Sie diese Prüfungen in Ihre CI/CD-Pipeline ein. Werkzeuge wie OWASP ZAP, OWASP Dependency-Check, Semgrep oder Bandit helfen, die einzelnen Kategorien konkret abzudecken. Ergänzend gehören sicheres Design, geprüfte Abhängigkeiten und regelmäßige Penetrationstests dazu.

Fazit

Die OWASP Top 10 sind eine unverzichtbare Grundlage für sichere Webanwendungen, und mit der finalen Edition 2025 hat sich das Bild spürbar verschoben: Security Misconfiguration rückt nach vorn, Software Supply Chain Failures ist als eigenständiges Großrisiko anerkannt, Mishandling of Exceptional Conditions kommt neu hinzu, und SSRF geht in Broken Access Control auf. Wer diese Verschiebungen kennt, priorisiert seine Schutzmaßnahmen richtig.

Behalten Sie im Blick, dass die Liste nur die häufigsten Risiken abbildet, nicht alle. Absolute Sicherheit gibt es nicht, aber das Risiko lässt sich deutlich senken: durch sicheres Design, geprüfte Abhängigkeiten, saubere Fehlerbehandlung, wirksame Protokollierung mit Alarmierung und regelmäßige Tests wie Penetrationstests oder Bug-Bounty-Programme. Nutzen Sie die verlinkten Vertiefungsartikel, um jede Kategorie in die Praxis zu übersetzen. Nichts zu tun ist keine Option, denn ein erfolgreicher Angriff ist sonst nur eine Frage der Zeit.