Bei falsch positiven Ergebnissen ist hier alles einfach: Sie können die Stellen im Code, an denen Schwachstellen mit dem Verdacht auf falsch positive Ergebnisse gefunden wurden, direkt anzeigen. In der Tat können sich einige von ihnen als falsch positiv herausstellen (obwohl offensichtlich nicht die Hälfte der Gesamtzahl).
Aber darüber, was kritisch ist und was nicht, möchte ich ausführlicher sprechen. Wenn Sie verstehen, warum es nicht mehr möglich ist, SHA-1 zu verwenden, und warum ";" entkommen, wird dieser Artikel Ihnen möglicherweise nichts Neues öffnen. Wenn die Scanergebnisse der gefundenen Sicherheitslücken jedoch zu kurz kommen, begrüßen wir Sie unter dem Strich. Wir werden Ihnen sagen, welche "Löcher" in Mobil- und Webanwendungen am häufigsten zu finden sind, wie sie funktionieren, wie sie behoben werden und vor allem, wie Sie verstehen, was vor Ihnen liegt - ein gefährlicher Fehler oder ein kleiner Fehler im Code.
Implementierung
Nun, sooo häufige Art von Sicherheitslücke. Sie sind überall eingebettet: in SQL-, LDAP-, XML-, XPath-, XSLT-, Xquery-Abfragen ... Alle diese Injektionen zeichnen sich durch die Verwendung nicht vertrauenswürdiger Daten aus, durch die ein Angreifer Zugriff auf Informationen erhält oder das Verhalten der Anwendung ändert. Zum Beispiel mit Benutzereingaben, die nicht ausreichend validiert sind.
Gemäß der internationalen Klassifizierung von Sicherheitslücken OWASP stehen Angriffe mit der Injektionsmethode an erster Stelle in Bezug auf die Kritikalität von Bedrohungen für die Sicherheit von Webanwendungen. Betrachten wir die typischsten Arten von Implementierungen.
SQL-Injection . Nicht vertrauenswürdige Daten gelangen in die SQL-Abfrage zur Datenbank.
Wenn die Abfrage an die Datenbank keine korrekte Authentifizierung der Eingabedaten implementiert, kann ein Angreifer die SQL-Abfrage beschädigen:
- Senden Sie bösartigen Code an ihn.
- Fügen Sie das Symbol "-" oder ";" und beenden Sie den richtigen SQL-Befehl: Alles nach dem "-" wird als Kommentar interpretiert, und das Zeichen ";" markiert das Ende eines Befehls;
- Erraten Sie das Kennwort, indem Sie nacheinander eine Reihe von SQL-Abfragen ausführen.
Wie kann man sich verteidigen? Hier einige Empfehlungen von OWASP :
- Verwenden Sie eine API, die eine parametrisierte Schnittstelle oder ORM-Tools (Object Relational Mapping) bereitstellt.
- Implementieren Sie einen Validierungsmechanismus für vom Benutzer eingegebene Daten. Verwenden Sie eine serverseitige Validierungs-Whitelist.
- Escape-Sonderzeichen (";", "-", "/ *", "* /", "'"; die genaue Liste hängt von der Datenbank ab).
- Verwenden Sie gespeicherte Prozeduren in Verbindung mit einem Filtermechanismus für ihre Parameter, um Benutzereingaben zu validieren.
XML-Injection . Anwendungen verwenden XML zum Speichern oder Austauschen von Daten, sodass sie wertvolle Informationen enthalten können.
Wenn ein Angreifer Daten in ein XML-Dokument schreiben kann, kann er dessen Semantik ändern. In diesem Fall können Sie im harmlosesten Szenario zusätzliche Tags in das Dokument einfügen, wodurch der XML-Parser mit einem Fehler beendet wird. Es kann jedoch zu einem schwerwiegenderen Vorfall kommen: Zum Beispiel durch das Ersetzen von Authentifizierungsdaten in der Kundendatenbank oder des Preises in der Produktdatenbank des Geschäfts. XML-Injection kann auch zu Cross-Site-Scripting (XSS) führen - dem Injection von Schadcode, der beim Öffnen der Seite im Browser des Benutzers ausgeführt wird.
Was können wir raten?
- Erstellen Sie keine Tags und Attribute, deren Namen von Daten einer nicht vertrauenswürdigen Quelle abgeleitet sind (z. B. von einem Benutzer eingegeben).
- Codieren Sie die vom Benutzer eingegebenen Daten, bevor Sie sie in ein XML-Dokument schreiben.
Die XQuery- Injection ist eine Form der klassischen SQL-Injection. In diesem Fall zielt der Angriff jedoch auf die XML-Datenbank ab, und nicht vertrauenswürdige Daten landen im XQuery-Ausdruck.
Im folgenden Beispiel erstellt die Anwendung einen XQuery-Ausdruck basierend auf Parametern
usernameund passwordaus einer HTTP-Anforderung (nicht vertrauenswürdige Quelle) und führt ihn aus:
XQDataSource xqs = new XQDataSource();
XQConnection conn = xqs.getConnection();
String query = "for \$user in doc(users.xml)//user[username='" + request.getParameter("username") + "'and pass='" + request.getParameter("password") + "'] return \$user";
XQPreparedExpression xqpe = conn.prepareExpression(query);
XQResultSequence rs = xqpe.executeQuery();
Wenn die Daten korrekt sind, gibt die Anforderung Informationen über den Benutzer mit dem entsprechenden Namen und Kennwort zurück:
for \$user in doc(users.xml)//user[username='test_user' and pass='pass123'] return \$user
Wenn ein Angreifer eine Zeichenfolge mit Sonderzeichen (z. B.
admin' or 1=1 or ''=') als Parameter angibt, ändert sich die Semantik der Anforderung:
//user[username='admin']
Die empfangene Anfrage gibt Daten über alle Benutzer zurück.
Sichere Option (verwendet
prepared statements):
XQDataSource xqs = new XQDataSource();
XQConnection conn = xqs.getConnection();
String query = "declare variable $username as xs:string external; declare variable $password as xs:string external; for \$user in doc(users.xml)//user[username='$username' and pass='$password'] return \$user";
XQPreparedExpression xqpe = conn.prepareExpression(query);
xqpe.bindString(new QName("username"), request.getParameter("username"), null);
xqpe.bindString(new QName("password"), request.getParameter("password"), null);
XQResultSequence rs = xqpe.executeQuery();
Das Einbetten in XSLT (XML Document Transformation Language) ist möglich, wenn die Anwendung bei der Arbeit mit XSL Daten aus einer nicht vertrauenswürdigen Quelle verwendet.
Anwendungen verwenden XSL, um XML-Dokumente zu transformieren. Dateien im XSL-Stil enthalten Funktionen, die die Transformation beschreiben und bei nicht korrekter Implementierung Schwachstellen enthalten können. Dies erhöht das Risiko von Angriffsszenarien, in denen ein Angreifer die Struktur und den Inhalt der XSL-Datei und damit der entsprechenden XML-Datei ändert. Was können wir am Ausgang bekommen?
Erstens ein XSS-Angriff: Injizieren von schädlichem Code in eine von einem Websystem ausgegebene Seite und Interagieren mit dem Server des Angreifers. Zweitens erhält der Hacker Zugriff auf Systemressourcen. Drittens die Ausführung von beliebigem Code. Und zum Nachtisch - XXE-Angriff (XML eXternal Entity - Injektion einer externen Entität in XML).
Das Einbetten von LDAP (Lightweight Directory Access Protocol ) in Befehle kann zu Datenverlust oder -änderungen führen. In diesem Fall werden nicht vertrauenswürdige Daten in die LDAP-Anforderung übernommen.
Injektion eines böswilligen Interpreter-Befehls.Nicht vertrauenswürdige Daten gelangen in den Interpreter-Befehl. Ein Angreifer kann eine solche Eingabe auswählen, damit der Befehl erfolgreich ausgeführt wird und ihm zusätzliche Berechtigungen in der Anwendung zur Verfügung stehen.
Im folgenden Beispiel führt die Anwendung ein Skript zum Erstellen einer Datenbanksicherung aus. Die Anwendung verwendet den Sicherungstyp als Parameter und führt das Skript mit erhöhten Berechtigungen aus:
String btype = request.getParameter("backuptype");
String cmd = new String("cmd.exe /K
\"c:\\util\\rmanDB.bat "+btype+"&&c:\\utl\\cleanup.bat\"")
System.Runtime.getRuntime().exec(cmd);
Das Problem hierbei ist, dass der Parameter
backuptypenicht validiert wird. Führt Runtime.exec()normalerweise nicht mehrere Befehle aus, aber in diesem Fall wird cmd.exe zuerst gestartet, um mehrere Befehle durch Aufrufen auszuführen Runtime.exec(). Sobald die Befehlszeilen-Shell gestartet ist, kann sie mehrere Befehle ausführen, die durch " &&" Zeichen getrennt sind . Wenn ein Angreifer && del c:\\dbms\\*.*die Zeichenfolge " " als Parameter angibt, löscht die Anwendung das angegebene Verzeichnis.
Entwicklertipps:
- Lassen Sie Benutzer nicht direkt die Kontrolle über die Befehle haben, die die Anwendung ausführt. Wenn das Verhalten der Anwendung von den vom Benutzer eingegebenen Daten abhängen muss, bieten Sie dem Benutzer eine Auswahl aus einer bestimmten Liste zulässiger Befehle an.
- , . , . , .
- , , . . .
Unsicherer Datei-Upload. In diesem Fall stammen nicht nur einzelne Daten aus einer nicht vertrauenswürdigen Quelle, sondern die gesamte Datei. Auf diese Weise kann ein Angreifer schädliche Daten oder Code auf den Zielserver hochladen. Wenn Benutzer in einem Unternehmensnetzwerk beispielsweise Dateien in öffentlich zugängliche Verzeichnisse hochladen dürfen, kann ein Hacker bösartigen Code remote auf dem Server des Unternehmens ausführen.
Unsichere Aufnahme externer Dateien in HTML.Sicherheitslücken beim Einschließen von Dateien treten auf, wenn der Benutzer den Pfad zu einer eingeschlossenen Datei eingibt. Tatsache ist, dass Sie mit modernen Skriptsprachen Code aus Dateien von Drittanbietern dynamisch verknüpfen können, um ihn wiederzuverwenden. Dieser Mechanismus wird für ein einheitliches Erscheinungsbild von Seiten oder zum Aufteilen von Code in kleine Module verwendet. Diese Aufnahme kann jedoch von einem Angreifer ausgenutzt werden, indem er den Pfad ändert und seine Datei verbindet.
Wir empfehlen Experten für Unternehmensinformationssicherheit, eine "weiße Liste" gültiger Dateiverbindungspfade zu erstellen, damit Mitarbeiter Dateien nur über Skripte aus dieser Liste hinzufügen können.
Lesezeichen
Lesezeichen sind Teile, die absichtlich in den Anwendungscode eingefügt werden. Mit deren Hilfe Sie unter bestimmten Bedingungen Aktionen ausführen können, die nicht in der Anwendung enthalten sind. Betrachten wir die häufigsten Arten von Lesezeichen.
Sonderkonten. Wenn die Anwendung den Wert eines Kennworts oder einer Anmeldevariablen mit einem unveränderten Wert vergleicht, ist Folgendes zu beachten: Dieses Konto kann Teil eines Lesezeichens sein. Mal sehen, wie das passiert.
Der Entwickler der Anwendung verwendet beim Debuggen ein spezielles Konto (möglicherweise mit erhöhten Berechtigungen) und belässt die entsprechenden Codeabschnitte in der endgültigen Version, sodass der Zugriff auf die Anwendung erhalten bleibt. Ein Angreifer kann den ursprünglichen Code der Anwendung wiederherstellen, die konstanten Werte des Sonderkontos extrahieren und Zugriff auf die Anwendung erhalten.
Es ist kategorisch unmöglich, Anmeldungen, Kennwörter und Schlüssel im Anwendungsquellcode zu speichern.Versteckte Funktionalität (NDV). Der versteckte Funktionscode wird ausgeführt, wenn ein bestimmter Trigger ausgelöst wird. In Webanwendungen ist der Auslöser häufig ein "unsichtbarer" Abfrageparameter. Manchmal wird zusätzlich geprüft, von welcher IP die Anfrage mit dem Trigger kam, so dass nur der Autor das Lesezeichen aktivieren konnte. Solche Überprüfungen dienen als Signal für mögliche Lesezeichen.
Undokumentierte Netzwerkaktivität. Diese Art von Aktivität umfasst: Herstellen einer Verbindung zu Ressourcen von Drittanbietern im Hintergrund, Abhören von nicht dokumentierten Ports, Übertragen von Informationen über SMTP, HTTP, UDP, ICMP.
Wenn Sie im Code eine verdächtige Verbindung mit einer Adresse finden, die nicht in der Liste der bekannten sicheren Adressen aufgeführt ist, empfehlen wir dringend, diese zu löschen.Ändern Sie die Sicherheitseinstellungen . Die Anwendung enthält Code, der den Wert der Variablen ändert, in der der Erfolg der Authentifizierung gespeichert ist. Ein häufiger Fehler ist die Verwendung von Zuweisung (=) anstelle von Vergleich (==). Bei Authentifizierungsmethoden ist dies besonders gefährlich, da es Teil einer Hintertür sein kann:
if (isAuthenticated = true)
{
someDangerousAction();
}
Zeitauslöser (Zeitbombe). Ein Lesezeichen, das zu einem bestimmten Zeitpunkt ausgelöst wird. Die Anwendung vergleicht das aktuelle Datum mit einem bestimmten Jahr, Monat und Tag: Am 1. Januar 2021 erwartet alle eine Überraschung:
Date now = java.util.Date(); // current time
if ((now.getYear() == 2021) && (now.getMonth() == 1) && (now.getDate() == 1))
{
activateNewYearBackdoor();
}
Oder vielleicht auch nicht ... In der Praxis treten bei der Suche nach temporären Auslösern häufig Fehlalarme auf. Wenn beispielsweise die Zeit-API für den vorgesehenen Zweck verwendet wird: Protokollierung, Berechnung der Ausführungszeit, Zeitstempel für Serverantworten auf HTTP-Anforderungen.
Aber! Wir empfehlen weiterhin, die Augen nicht vor solchen Alarmen zu schließen, da wir echte Beispiele für solche Schwachstellen kennen.
Toter Code. Teile des injizierten Codes, die nichts Nützliches bewirken. Toter Code selbst ist nicht gefährlich, kann jedoch Teil eines Lesezeichens sein, das über mehrere Dateien verteilt wurde. Oder der Lesezeichen-Trigger soll später implementiert werden. In jedem Fall sollte toter Code verdächtig sein.
Fehlende Verschlüsselung und Verwendung schwacher Verschlüsselungsalgorithmen
Die Hauptprobleme bei der Verschlüsselung sind, dass sie entweder überhaupt nicht verwendet wird oder schwache Algorithmen verwendet werden und die Schlüssel und das Salz zu einfach sind oder nicht sicher gespeichert werden. Die Konsequenz all dieser Sicherheitslücken ist dieselbe - es ist einfacher, vertrauliche Daten zu stehlen.
Das Beispiel zeigt die Initialisierung der Verschlüsselung mit dem älteren DES-Algorithmus:
Cipher cipher = Cipher.getInstance("DES");
Beispiele für anfällige Verschlüsselungsalgorithmen: RC2, RC4, DES. Sichere Option:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Gemäß der internationalen OWASP- Klassifizierung stehen Schwachstellen wie „vertrauliche Datenlecks“ in Bezug auf die Schwere der Sicherheitsbedrohungen für Webanwendungen an dritter Stelle.
Unsere Empfehlung an Entwickler: Verwenden Sie die Verschlüsselung aus Sicherheitsgründen.
Die Verwendung des unsicheren HTTP-Protokolls anstelle von HTTPS ist mit einem Mann im mittleren Angriff behaftet.
Das sichere HTTPS-Protokoll basiert auf HTTP, unterstützt jedoch auch die Verschlüsselung über die kryptografischen SSL / TLS-Protokolle. HTTPS verschlüsselt alle darüber übertragenen Daten, insbesondere Anmelde- und Passworteingabeseiten oder Benutzer-Bankkartendaten, und schützt sie so vor unbefugtem Zugriff und Änderungen. Im Gegensatz zu HTTP, das die übertragenen Daten nicht schützt. Infolgedessen kann ein Angreifer eine Informationswebsite über HTTP fälschen und den Benutzer zwingen, Daten auf einer gefälschten Seite einzugeben (Phishing-Angriff).
Der Verschlüsselungsschlüssel wird im Quellcode angegeben . Daher stehen solche Schlüssel jedem Anwendungsentwickler zur Verfügung. Darüber hinaus können Sie nach der Installation der Anwendung den Schlüssel nur durch Aktualisierung aus dem Code entfernen.
Im Allgemeinen können konstante Zeichenfolgen mithilfe eines Quellcode-Wiederherstellungsprogramms (Dekompiler) leicht aus einer ausführbaren Datei extrahiert werden. Daher muss ein Angreifer keinen Zugriff auf den Quellcode haben, um den Wert des verwendeten Schlüssels herauszufinden. In unserer Praxis stoßen wir häufig auf Fälle, in denen Entwickler
nullentweder eine leere Zeichenfolge als Schlüsselwert angeben , was einfach nicht akzeptabel ist.
Unser Rat: Generieren Sie Schlüssel mit kryptografisch starken Pseudozufallszahlengeneratoren (PRNGs) und speichern Sie diese mit speziellen Modulen.
Unsicherer Auffüllalgorithmus für die Verschlüsselung . Wenn der RSA-Verschlüsselungsalgorithmus ohne OAEP-Auffüllung verwendet wird, werden die verschlüsselten Daten anfällig .
Der OAEP-Algorithmus wird benötigt, um Nachrichten zu verarbeiten, bevor RSA verwendet wird. Die Nachricht wird zuerst mit OAEP auf eine feste Länge aufgefüllt und dann mit RSA verschlüsselt. Dieses Verschlüsselungsschema heißt RSA-OAEP und ist Teil des aktuellen Standards .
Dies ist ein Beispiel für die Initialisierung der RSA-Verschlüsselung ohne Auffüllen:
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
Sichere Option:
rsa = javax.crypto.Cipher.getInstance("RSA/ECB/OAEPWithMD5AndMGF1Padding");
Unzureichende Größe des Verschlüsselungsschlüssels . Wenn Sie einen Kurzschlüssel verwenden, ist diese Verschlüsselung anfällig für Brute-Force-Angriffe.
Die Kryptoanalyse steht nicht still, es entstehen ständig neue Angriffsalgorithmen, Computer gewinnen an Leistung. Verschlüsselungseinstellungen, die zuvor als sicher galten, sind veraltet und werden nicht mehr zur Verwendung empfohlen. Daher wurde RSA mit einer Schlüssellänge von 1024 Bit in den Jahren 2010-2015 nicht mehr als sicher angesehen.
Schwacher Hashing-Algorithmus . Aus den im vorherigen Absatz beschriebenen Gründen sind die Hash-Funktionen MD2, MD5, SHA1 unsicher. Es sind keine wesentlichen Ressourcen erforderlich, um Kollisionen für MD2- und MD5-Funktionen zu finden.
Für SHA1 gibt es Beispiele für zwei verschiedene Dateien mit denselben Hashes. Hacking-Algorithmus vorgeschlagenMitarbeiter von Google und dem Zentrum für Mathematik und Informatik in Amsterdam.
Wenn Benutzerkennwörter als Hashes gespeichert werden, aber eine unsichere Hash-Funktion verwenden, kann ein Angreifer leicht auf sie zugreifen, indem er das folgende Szenario implementiert. Wenn Sie den Hash des Kennworts kennen und die Sicherheitsanfälligkeit des Hashing-Algorithmus ausnutzen, können Sie eine Zeichenfolge berechnen, für die der Hash mit dem Kennwort identisch ist. Der Angreifer authentifiziert sich anhand der berechneten Zeichenfolge.
Die Hash-Funktion zum Speichern von Passwörtern muss kollisionssicher und nicht zu schnell sein, damit ein Brute-Force-Angriff nicht implementiert werden kann. Die sicheren Algorithmen PBKDF2, bcrypt, scrypt sollten verwendet werden.
Einige interessante Zahlen: mit PBKDF2Die Geschwindigkeit der Suche nach Schlüsseln wurde für Intel Core2 auf 70 Teile pro Sekunde und für FPGA Virtex-4 FX60 auf etwa 1.000 reduziert. Im Vergleich dazu haben die klassischen LANMAN- Passwort-Hashing-Funktionen eine Suchgeschwindigkeit von etwa Hunderten Millionen Optionen pro Sekunde.
Schwacher Verschlüsselungsalgorithmus . Wie bei Hashing-Algorithmen wird die Sicherheit eines Verschlüsselungsalgorithmus durch die Zeit und die Ressourcen bestimmt, die für die Entschlüsselung aufgewendet werden müssen. RC2, RC4, DES gelten als anfällige Algorithmen. Letzteres kann aufgrund seiner geringen Schlüssellänge (56 Bit) durch rohe Gewalt geknackt werden.
Ein schwacher Pseudozufallszahlengenerator (PRNG) erzeugt vorhersagbare Sequenzen. Ein Hacker kann die Authentifizierung umgehen und die Sitzung eines Benutzers entführen.
Gehen wir etwas tiefer in die Natur der PRNGs ein. Sie generieren Zahlenfolgen basierend auf dem Anfangswert des Parameters
seed. Es gibt zwei Arten von PRNGs - statistische und kryptografische.
Statistische PRNGs erzeugen vorhersagbare Sequenzen, die zufälligen statistisch ähnlich sind. Sie können nicht zu Sicherheitszwecken verwendet werden.
Das Ergebnis des Betriebs von kryptografischen PRNGs kann dagegen nicht vorhergesagt werden, wenn der Parameterwert
seedvon einer Quelle mit hoher Entropie erhalten wird. Der aktuelle Zeitwert hat wenig Entropie und ist auch in der Qualität unsicher seed. In Java, PRNGs von Klassen java.util.Randomund java.lang.Matherzeugen vorhersagbaren Sequenzen und sollte nicht für die Informationssicherheit Zwecke nutzen.
Schwacher Keim eines Pseudozufallszahlengenerators . Es ist nicht
seedsicher, einen Wert aus einer nicht vertrauenswürdigen Quelle zu verwenden, da dadurch eine vorhersagbare Sequenz generiert wird.
Die Arbeit vieler kryptografischer Algorithmen basiert auf der Verwendung eines kryptoanalyseresistenten PRNG. Einige Algorithmen können einen Wert als zusätzliches Argument verwenden
seedund für jeden Wert dieses Parameters eine vorhersagbare Sequenz generieren. In diesem Fall basiert die Sicherheit des Systems auf der Annahme, dass die Werte seednicht vorhersehbar sind.
Das Salz ist im Quellcode angegeben... Erinnern wir uns, wofür Salz ist. Um ein Passwort mit der Brute-Force-Methode zu knacken, werden vorkompilierte Tabellen mit Werten von Hash-Funktionen aus gängigen Passwörtern verwendet. Salt ist eine beliebige Zeichenfolge, die zusammen mit dem Kennwort der Eingabe der Hash-Funktion zugeführt wird, um einen solchen Angriff zu erschweren.
Wenn das Salz im Quellcode gespeichert ist, treten genau die gleichen Probleme auf wie bei Passwörtern und Schlüsseln. Der Wert von Salt steht Entwicklern zur Verfügung und kann von Eindringlingen leicht abgerufen werden. Salt kann erst mit dem nächsten Update der Anwendung aus der endgültigen Version der Anwendung entfernt werden.
Manipulation mit Protokollen
Verschiedene Fehler in den Protokollen sind mit der Einführung von Schadcode in Anwendungen behaftet. Die häufigsten mit der Protokollierung verbundenen Sicherheitslücken sind Manipulationen an Protokolldateien und unstrukturierte Protokollierung.
Manipulationen an Protokolldateien treten auf, wenn eine Anwendung nicht vertrauenswürdige Daten in das Ereignisprotokoll (Protokoll) schreibt. Ein Hacker kann Protokolleinträge fälschen oder schädlichen Code in sie einfügen.
In der Regel protokollieren Anwendungen den Transaktionsverlauf zur weiteren Verarbeitung, zum Debuggen oder zur Erfassung von Statistiken. Protokolle können manuell oder automatisch analysiert werden.
Wenn die Daten "wie sie sind" in das Protokoll geschrieben werden, kann ein Angreifer gefälschte Datensätze in das Protokoll einfügen, die Dateistruktur verletzen, indem der Protokollprozessor ausfällt, oder bösartigen Code einfügen, der bekannte Schwachstellen im Prozessor ausnutzt.
In diesem Beispiel versucht eine Webanwendung, einen ganzzahligen Wert aus einem Anforderungsparameter zu lesen. Wenn der eingegebene Wert nicht in eine Ganzzahl konvertiert werden konnte, protokolliert die Anwendung diesen Wert zusammen mit einer Fehlermeldung:
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
Ein Angreifer kann dem Protokoll einen beliebigen Eintrag hinzufügen. Die Zeile
twenty-one%0a%0aINFO:+User+logged+out%3dbadguywird beispielsweise wie folgt im Protokoll angezeigt:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
Ebenso können beliebige Datensätze in das Protokoll eingebettet werden.
Sichere Option (verwendet
NumberFormatException):
public static final String NFE = "Failed to parse val. The input is required to be an integer value."
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException nfe) {
log.info(NFE);
}
Die unstrukturierte Protokollierung , dh die Ausgabe von Fehlermeldungen an die Standard-Out- oder Err-Streams, ist eine unsichere Methode. Es wird empfohlen, stattdessen die strukturierte Protokollierung zu verwenden. Mit letzterem können Sie ein Protokoll mit Ebenen, Zeitstempeln und Standardformatierungen erstellen. Wenn das Programm einen strukturierten Protokollierungsmechanismus implementiert, aber Fehlermeldungen an Standard-Streams ausgegeben werden, enthält das Protokoll möglicherweise keine kritischen Informationen.
Die Ausgabe von Fehlermeldungen in Standard-Streams ist nur in den frühen Entwicklungsstadien zulässig.
Unsichere Cookie-Behandlung
Die mit der Erfassung von Benutzer-Cookies verbundenen Sicherheitslücken sind sehr unterschiedlich.
Unsicherer Umgang mit Cookies . Die Anwendung enthält Daten aus einer nicht vertrauenswürdigen Quelle im Cookie, die zu Cache-Vergiftungen, XSS (Cross-Site Scripting) und Angriffen zur Aufteilung von Antworten führen können.
Wenn bösartiger Code (Cross-Site-Scripting) in eine Anwendung eingefügt wird, kann ein Angreifer das Cookie des Benutzers ändern.
Da Cookies im HTTP-Antwortheader gesetzt sind, kann die Nichtbestätigung der im Cookie enthaltenen Daten zu einem Split-Response-Angriff führen. "Aufteilung der HTTP-Antwort" ist ein Angriff, bei dem ein Hacker eine HTTP-Anfrage sendet, deren Antwort vom Opfer in zwei HTTP-Antworten gleichzeitig (anstelle der richtigen) akzeptiert wird.
Wenn der Angreifer eine
authorZeichenfolge des Formulars als Parameter angibt Hacker \r\nHTTP/1.1 200 OK\r\n..., wird die Antwort wie folgt in zwei Teile geteilt:
HTTP/1.1 200 OK
...
Set-Cookie: author=Hacker
HTTP/1.1 200 OK
...
Der Inhalt der zweiten Antwort unterliegt vollständig der Kontrolle des Angreifers, was zu Cache-Vergiftungen, XSS, böswilligen Weiterleitungen und anderen Angriffen führt.
Cookies ohne HttpOnly . Die App erstellt Cookies ohne Flagge
httpOnly. Wenn httpOnlyin der Antwort - Header enthalten http, müsste ein Angreifer nicht in der Lage sein , Cookies zu erhalten , mit Hilfe von JavaScript - Code. Wenn ein Benutzer eine Seite mit einer XSS-Sicherheitsanfälligkeit (Cross-Site Scripting) öffnet, gibt der Browser die Cookies nicht an Dritte weiter. Wenn das Flag httpOnlynicht gesetzt ist, können Cookies (normalerweise Sitzungscookies) mithilfe eines Skripts gestohlen werden.
Ein Beispiel für das Erstellen eines Cookies ohne Flag
httpOnly:
Cookie cookie = new Cookie("emailCookie", email);
response.addCookie(cookie);
Setzen Sie das Flag
httpOnlybeim Erstellen von Cookies. Beachten Sie jedoch, dass es Möglichkeiten gibt, Angriffe zu umgehen. Daher httpOnlysollten Sie auch darauf achten, die Eingabe sorgfältig zu überprüfen.
NB Gemäß der internationalen OWASP- Klassifizierung stehen Sicherheitslücken in Bezug auf "Vertraulichkeit von Datenlecks" an dritter Stelle in Bezug auf die Kritikalität von Sicherheitsbedrohungen für Webanwendungen.
Cookies für eine zu allgemeine Domain . Wenn die Cookie-Domäne beispielsweise zu allgemein ist
.example.com, setzt eine Sicherheitsanfälligkeit in einer Anwendung andere Anwendungen in derselben Domäne Sicherheitsanfälligkeiten aus.
Im folgenden Beispiel setzt eine an einer Adresse installierte sichere Webanwendung
http://secure.example.comein Cookie mit einem Domänenwert .example.com:
Cookie cookie = new Cookie("sessionID", sessionID);
cookie.setDomain(".example.com");
Wenn
http://insecure.example.comeine Anwendung, die beispielsweise XSS enthält, unter der Adresse installiert ist, können die Cookies des autorisierten Benutzers der sicheren Anwendung, der die Adresse http://insecure.example.comaufgerufen hat, kompromittiert werden.
Ein Angreifer kann auch einen Cookie-Vergiftungsangriff ausführen: Cookies mit einer gemeinsamen Domain
http://insecure.example.comüberschreiben den Cookie http://secure.example.com.
Sichere Option:
Cookie cookie = new Cookie("sessionID", sessionID);
cookie.setDomain("secure.example.com");
Cookies mit zu allgemeinen Parametern
path . Wenn der Pfad im Cookie ungenau ist (z. B. /), tritt das gleiche Problem auf wie bei der freigegebenen Domäne: Eine Sicherheitsanfälligkeit in einer Anwendung macht andere Anwendungen in derselben Domäne verfügbar.
Im folgenden Beispiel setzt eine unter einer URL installierte Anwendung
http://pages.example.com/forumein Cookie mit dem Pfad /:
Cookie cookie = new Cookie("sessionID", sessionID);
cookie.setPath("/");
Dann kann eine unter der Adresse installierte schädliche Anwendung
http://pages.example.com/evildie Cookies des Benutzers gefährden. Ein Angreifer kann auch einen Cookie-Vergiftungsangriff ausführen: Ein Cookie mit einem gemeinsam erstellten Pfad /evilüberschreibt den Cookie /forum.
Sichere Option:
Cookie cookie = new Cookie("sessionID", sessionID);
cookie.setPath("/forum");
Cookies sind nicht über SSL . Die Anwendung erstellt Cookies, ohne das Flag
securegleich zu setzen true. Diese Cookies können unverschlüsselt über HTTP übertragen werden. Die Sicherheitsanfälligkeit "Verwenden des unsicheren HTTP-Protokolls" wird sofort zurückgerufen.
Im folgenden Beispiel erstellt die Anwendung Cookies ohne Flag
secure:
Cookie cookie = new Cookie("emailCookie", email);
response.addCookie(cookie);
Wenn die Anwendung sowohl HTTPS als auch HTTP verwendet, werden die im Rahmen der HTTPS-Anforderung erstellten Cookies ohne das sichere Flag unverschlüsselt in nachfolgenden HTTP-Anforderungen übertragen, was zu einer Gefährdung der Anwendung führen kann. Dies ist besonders gefährlich, wenn das Cookie wertvolle Daten enthält, insbesondere die Sitzungs-ID.
Sichere Option:
Cookie cookie = new Cookie("emailCookie", email);
cookie.setSecure(true);
response.addCookie(cookie);
Cookies mit unbegrenzter Gültigkeit . Wenn Sie wertvolle Cookies zu lange speichern, kann ein Angreifer darauf zugreifen.
Standardmäßig werden nicht persistente (Sitzungs-) Cookies verwendet, die nicht auf der Festplatte gespeichert und nach dem Schließen des Browsers gelöscht werden. Der Entwickler der Webanwendung kann jedoch angeben, wie lange die Cookies aufbewahrt werden. In diesem Fall werden sie auf die Festplatte geschrieben und zwischen dem Neustart des Browsers und dem Neustart des Computers gespeichert. Dies gibt dem Angreifer eine lange Zeit, um einen Angriffsplan zu entwickeln.
Entwicklerempfehlungen: Stellen Sie sicher, dass die App keine langlebigen Cookies erstellt:
Cookie cookie = new Cookie("longCookie", cookie);
cookie.setMaxAge(5*365*24*3600); // 5 !
Geben Sie ein angemessenes maximales Zeitlimit gemäß den OWASP- Richtlinien an .
Informationsleck
Möglicherweise die empfindlichste Art von Sicherheitsanfälligkeit für Anwendungsbenutzer.
Externer Informationsverlust durch Fehlerseiten . Die Anwendung verwendet Standardfehlerseiten, die Informationen zur Systemkonfiguration enthalten können.
Fehlermeldungen und Debug-Informationen werden in das Protokoll geschrieben, auf der Konsole angezeigt oder an den Benutzer übertragen. Anhand von Fehlermeldungen kann ein Angreifer Informationen zu Systemschwachstellen erhalten, die ihm das Leben erleichtern. Beispielsweise kann ein Datenbankfehler auf Unsicherheit gegen SQL-Injection hinweisen. Informationen zur Betriebssystemversion, zum Anwendungsserver und zur Systemkonfiguration erleichtern es einem Hacker, einen Angriff auf eine Anwendung zu planen.
Externer Verlust wertvoller Informationen... In diesem Fall handelt es sich um den Verlust technischer Informationen über die Anwendung, indem diese über das Netzwerk auf einen anderen Computer übertragen werden. Im Allgemeinen sind externe Lecks gefährlicher als interne Lecks.
Interner Verlust wertvoller Informationen . Der Betriebsmechanismus ähnelt den beiden vorherigen Arten von Lecks, in diesem Fall werden jedoch Informationen zum System in das Protokoll geschrieben oder auf dem Bildschirm des Benutzers angezeigt.
Verlust vertraulicher Daten . Wertvolle personenbezogene Daten von Benutzern gelangen aus verschiedenen Quellen in die Anwendung: vom Benutzer selbst, aus verschiedenen Datenbanken, aus Speichern von Drittanbietern. Manchmal werden diese Daten nicht als vertraulich markiert oder sie erweisen sich nicht an sich als wertvoll, sondern nur in einem bestimmten Kontext.
Dies ist genau dann der Fall, wenn sich Anwendungssicherheit und Datenschutz widersprechen. Aus Sicherheitsgründen ist es ratsam, detaillierte Informationen über die Aktivität im System aufzuzeichnen, um böswillige Aktivitäten zu erkennen. Aus Sicht des Datenschutzes ist dagegen bei der Protokollierung vertraulicher Informationen das Risiko eines Verlusts größer. Im Allgemeinen hat die Gewährleistung der Vertraulichkeit der personenbezogenen Daten der Anwendungsbenutzer eine höhere Priorität.
Nachwort
Die in diesem Artikel berücksichtigten Arten von Sicherheitslücken decken die meisten "universellen" Lücken in Anwendungen ab, die in verschiedenen Programmiersprachen geschrieben wurden. Einige Sprachen haben jedoch ihre eigenen spezifischen Schwachstellen. Dies ist jedoch bereits ein Thema für einen separaten Artikel. Denken Sie zum Schluss daran: Vergessen Sie beim Erstellen von Anwendungen nicht, die obigen Empfehlungen zu befolgen, lesen Sie die Dokumentation sorgfältig durch und überprüfen Sie Anwendungen mithilfe spezieller Software auf Schwachstellen.
Autor: Elizaveta Kharlamova, Leiterin der Abteilung Analytics, Solar AppScreener