This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
Difference between revisions of "Germany/Projekte/Top 10 fuer Entwickler-2013/A6-Verlust der Vertraulichkeit sensibler Daten"
Timo Pagel (talk | contribs) |
Timo Pagel (talk | contribs) m (Correct typo) |
||
Line 268: | Line 268: | ||
= '''PHP''' = | = '''PHP''' = | ||
{{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=2|risk=7|year=2010|language=de}} | {{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=2|risk=7|year=2010|language=de}} | ||
− | Um vorerstellte Hash-Tabellen zu verhindern, kann jedem Datensatz eine zufällige Zeichenfolge hinzugefügt werden, welche als Salt (Deutsch: Salz) bezeichnet wird. Ein Beispiel für die sichere Erstellung eines Hashwerts ist im | + | Um vorerstellte Hash-Tabellen zu verhindern, kann jedem Datensatz eine zufällige Zeichenfolge hinzugefügt werden, welche als Salt (Deutsch: Salz) bezeichnet wird. Ein Beispiel für die sichere Erstellung eines Hashwerts ist im Folgendemn gegeben. Dafür muss das GIT-Projekt [https://github.com/ircmaxell/password_compat] eingebunden werden, ab PHP-Version 5.5 ist dies im Kern enthalten. |
Das Salt wird bspw. bei einem Linuxsystem in der Funktion password_hash() durch Zugriff auf /dev/urandom erstellt. Der Rückgabewert der Funktion ist eine Zeichenkette und beinhaltet u.a. den Hashwert, das Salt und den genutzten Algorithmus. | Das Salt wird bspw. bei einem Linuxsystem in der Funktion password_hash() durch Zugriff auf /dev/urandom erstellt. Der Rückgabewert der Funktion ist eine Zeichenkette und beinhaltet u.a. den Hashwert, das Salt und den genutzten Algorithmus. | ||
Die Kosten, welche die Anzahl der Hash-Iterationen angeben, können über den dritten Parameter festgelegt werden. | Die Kosten, welche die Anzahl der Hash-Iterationen angeben, können über den dritten Parameter festgelegt werden. |
Revision as of 16:28, 12 January 2014
← A5-Sicherheitsrelevante Fehlkonfiguration | A7-Fehlerhafte Autorisierung auf Anwendungsebene → |
______ | Ausnutzbarkeit SCHWIERIG |
Verbreitung SELTEN |
Auffindbarkeit DURCHSCHNITTLICH |
Auswirkung SCHWERWIEGEND |
Application / Business Specific |
Jeder Benutzer des Systems ist zu betrachten.
Haben diese ein Interesse, auf geschützte Daten unberechtigt zuzugreifen? Wie steht es um Administratoren? |
Angreifer brechen üblicherweise nicht die eigentliche Kryptografie. Statt dessen finden Sie Schlüssel, Klartexte oder greifen über Kanäle mit automatischer Entschlüsselung auf Daten zu. | Fehlende Verschlüsselung vertraulicher Daten ist die häufigste Schwachstelle, gefolgt von unsicherer Schlüsselerzeugung, der Speicherung statischer Schlüssel und die Nutzung schwacher Algorithmen. Schwache Hashwerte ohne Salt kommen zum Passwortschutz oft vor. Ein eingeschränkter Zugriff lässt externe Angreifer solche Probleme i.d.R. nicht leicht entdecken. Den nötigen Zugriff müssen sie vorher auf andere Weise erlangen. | Fehler kompromittieren regelmäßig vertrauliche Daten. Es handelt sich hierbei oft um sensitive Daten wie personenbezogene Daten, Benutzernamen und Passwörter oder Kreditkarteninformationen. | Betrachten Sie den Wert verlorener Daten und die Auswirkungen auf die Reputation des betroffenen Unternehmens. Hat es ggf. auch juristische Konsequenzen, wenn die Daten bekannt werden? |
Mögliche Angriffsszenarien
Szenario 1: Eine Anwendung speichert verschlüsselt Kreditkartendaten in einer Datenbank, um Sie vor Angreifern zu schützen. Die Datenbank ist so eingerichtet, dass die Daten beim Auslesen automatisch entschlüsselt werden. Durch SQL-Injection können in diesem Fall alle Kreditkartendaten im Klartext ausgelesen werden. Das System hätte so konfiguriert sein sollen, dass nur nachgelagerte Anwendungen und nicht die Webanwendung selbst entschlüsseln dürfen. |
Wie kann ich 'Kryptografisch unsichere Speicherung' verhindern?
Eine Übersicht über alle Tücken unsicherer Kryptografie liegt weit außerhalb des Rahmens der Top 10. Für alle vertraulichen Daten sollten Sie zumindest:
|
Example Attack Scenarios
temporär: Auszug aus Top 10-2013 RC1: A6-Sensitive_Data_ExposureScenario #1: An application encrypts credit card numbers in a database using automatic database encryption. However, this means it also decrypts this data automatically when retrieved, allowing an SQL injection flaw to retrieve credit card numbers in clear text. The system should have encrypted the credit card numbers using a public key, and only allowed back-end applications to decrypt them with the private key. Scenario #2: A site simply doesn't use SSL for all authenticated pages. Attacker simply monitors network traffic (like an open wireless network), and steals the user’s session cookie. Attacker then replays this cookie and hijacks the user’s session, accessing all their private data. Scenario #3: The password database uses unsalted hashes to store everyone’s passwords. A file upload flaw allows an attacker to retrieve the password file. All the unsalted hashes can be exposed with a rainbow table of precalculated hashes. |
How Do I Prevent 'Sensitive Data Exposure'?
temporär: Auszug aus Top 10-2013 RC1: A6-Sensitive_Data_ExposureThe full perils of unsafe cryptography, SSL usage, and data protection are well beyond the scope of the Top 10. That said, for all sensitive data, do all of the following, at a minimum:
Ensure passwords are stored with an algorithm specifically designed for password protection, such as bcrypt, PBKDF2, or scrypt.
|
Verteidigungs-Option 1 gegen 'Kryptografisch unsichere Speicherung':
Ein einfaches Beispiel für die Veschlüsselung von Texten, hier mit dem AES-128 Algorithmus. Die Auswahl an Verschlüsselungsparametern wie beispielsweise Algorithmus, Ciphermodus oder Schlüssellänge ist groß und kommt immer auf die jeweiligen Daten und die Anwendung an. String plainText = "HelloWorld"; // password setzen String password = "my128bitPassword"; // CBC Cipher immer mit einem zufällig erzeugten // Initialization Vector (IV) initialisieren (Länge 16 Byte) byte[] ivBytes = new byte[16]; (new SecureRandom()).nextBytes(ivBytes); // den Schlüssel erzeugen SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES"); // Container für die Verschlüsselungs Parameter IvParameterSpec paramSpec = new IvParameterSpec(ivBytes); // Chiffrierer erzeugen und initialisieren // Algorithmus: AES // Modus: CBC // Padding: PKCS5Padding Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); // Verschlüsselung durchführen byte[] encrypted = cipher.doFinal(plainText.getBytes()); Die Benutzung der ESAPI erleichtert die Handhabung, da neben einer großen Bandbreite an Verschlüsselungs-, Hash-, und Signaturalgorithmen auch Methoden für die Schlüsselerzeugung und -verwaltung unterstüzt werden. Nach Initialisierung der Parameter in der Konfigurationsdatei ESAPI.properties, reduziert sich die eigentliche Verschlüsselung eines Textes beispielsweise zu: CipherText ciphertext = ESAPI.encryptor().encrypt( new PlainText(myplaintext) ); |
Verteidigungs-Option 2 gegen 'Kryptografisch unsichere Speicherung':
Beispiele für das Hashen von Passwörtern. Um die Sicherheit zu erhöhen sollte jedes Passwort mit einem Zufallswert (Salt) berechnet und gespeichert werden sowie möglichst viele Iterationen beim Hashing genutzt werden. String password = "mypassword"; // salt anlegen und mit zufälligen Bytes befüllen byte[] salt = new byte[8]; (new SecureRandom()).nextBytes(salt); // Hash-Generator anlegen (verwendeter Algorithmus ist SHA-256) // und mit salt initialisieren (=> höhere Sicherheit gegen Angriffe) MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset(); digest.update(salt); byte[] input = digest.digest(password.getBytes("UTF-8")); // Hash in mehreren Iterationen (n = 100.000) berechnen // mehr Iterationen verlangsamen Angriffe (signifikant?) for (int i = 0; i < 100000; i++) { digest.reset(); input = digest.digest(input); } // am Ende der Iterationen enthält input den berechneten Hash Sicherer ist allerdings die Nutzung einer PBKDF2 (Password-Based Key Derivation Function 2) wie im folgenden Beispiel: public byte[] generatePBKDF2Hash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] salt = new byte[20]; // salt mit zufälligen Bytes befüllen (new SecureRandom()).nextBytes(salt); int iterations = 10000; int keyLength = 160; // neuen Schlüssel erzeugen SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, iterations, keyLength); SecretKey mySecretKey = factory.generateSecret(pbeKeySpec); } byte[] hash = generatePBKDF2Hash(password).getEncoded(); Eine weiterer empfohlener Algorithmus ist bcrypt, hier bespielsweise unter Verwendung der jBCrypt-Bibliothek (siehe Referenzen). String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12)); Zu bcrypt gibt es mittlerweile eine noch sicherere Variante scrypt, der Link zu einer Beispielimplementierung findet sich bei den Referenzen. |
Verteidigungs-Option 3 gegen 'Kryptografisch unsichere Speicherung':
Um geheime Schlüssel sicher, aber auch gleichzeitig einfach zugänglich und austauschbar aufzubewahren empfiehlt sich eine spezielle Schlüsseldatei, wie beispielweise der Java KeyStore. In dieser Datei werden die Schlüssel mit einem Master-Password gesichert, die Datei selbst sollte getrennt von den verschlüsselten Daten abgelegt werden: // Erzeugung eines symmetrischen Schlüssels mittels der vorher beschriebenen PBKDF2 String password = "mypassword"; byte[] mySecretKey = generatePBKDF2Hash(password); // neuen KeyStore für symmetrische Schlüssel erzeugen KeyStore ks = KeyStore.getInstance("JCEKS"); ks.load(null, null); // Schlüssel speichern KeyStore.ProtectionParameter passwordProtection = new KeyStore.PasswordProtection(password); KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(mySecretKey); ks.setEntry("beispielkey", entry, passwordProtection); // KeyStore in Datei speichern FileOutputStream fos = new FileOutputStream("SecretKeyStoreDatei"); ks.store(fos,password); fos.close(); |
Verteidigungs-Option 1 gegen 'Verlust der Vertraulichkeit sensibler Daten':
Um die Verschlüsselung auf der Transportebene sollte sich der Entwickler nie selbst kümmern, sondern dies immer dem Webserver überlassen: Im J2EE-Deployment-Descriptor der Anwendung (= web.xml) ist die folgende Konfiguration vorzunehmen, um sicherzustellen, dass nur ausschließlich über https kommuniziert wird: <security-constraint> <web-resource-collection> <web-resource-name>Protected Context</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <!-- auth-constraint an dieser Stelle für Authentisierung --> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> Für Session-Cookies ist immer das Attribute SECURE zu setzen: <session-config> <cookie-config> <secure> true </secure> </cookie-config> </session-config> In der Server-Configuration ist sicherzustellen, dass nur TLS und SSL3 unterstützt werden. Das Speichern von vertraulichen Inhalten am Client oder auf einem Proxy kann über den Header Cache-Control verhindert werden: Header set Cache-Control "no-cache, no store, must-revalidate" Weitere Hinweise im Transport Layer Protection Cheat Sheet |
Verteidigungs-Option 1a gegen 'Unzureichende Absicherung der Transportschicht':
Die Sicherheitskonfiguration unter Option 1 hat noch eine Schwachstelle, so das MITM (Man In The Middle attack) nicht zuverlässig verhindert wird. MITM erzeugt einen Zertifikatsfehler am Client, der üblicherweise aber (durch den Anwender) ignoriert wird. Deshalb wurde der HTTP-Header "HTTP Strict Transport Security (HSTS)" eingeführt. Damit werden kompatible Browser (Firefox, Chrome, Opera aber bisher NICHT IE) angewiesen, dass
Konfiguration im Apache: Header set Strict-Transport-Security "max-age=16070400; includeSubDomains" Da der HSTS-Header nur über https übermittelt wird ist zusätzlich ein Redirect nötig: <VirtualHost *:80> ServerAlias * RewriteEngine On RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301] </VirtualHost> Quellen: |
Referenzen
OWASP Einen umfangreicheren Überblick über die Anforderungen und die hierbei zu vermeidenden Probleme gibt es unter ASVS requirements on Cryptography (V7). Des Weiteren:
Andere |
Verteidigungs-Option 2 gegen 'Kryptografisch unsichere Speicherung':
Um vorerstellte Hash-Tabellen zu verhindern, kann jedem Datensatz eine zufällige Zeichenfolge hinzugefügt werden, welche als Salt (Deutsch: Salz) bezeichnet wird. Ein Beispiel für die sichere Erstellung eines Hashwerts ist im Folgendemn gegeben. Dafür muss das GIT-Projekt [1] eingebunden werden, ab PHP-Version 5.5 ist dies im Kern enthalten. Das Salt wird bspw. bei einem Linuxsystem in der Funktion password_hash() durch Zugriff auf /dev/urandom erstellt. Der Rückgabewert der Funktion ist eine Zeichenkette und beinhaltet u.a. den Hashwert, das Salt und den genutzten Algorithmus. Die Kosten, welche die Anzahl der Hash-Iterationen angeben, können über den dritten Parameter festgelegt werden. $options = [ 'cost' => 12, ]; $inputHash = password_hash($_GET['password'], CRYPT_SHA256, $options); storeHash($user, $inputHash); // Speichere Hash $hash = getHash($user); // Hole Hash aus der Datenbank $isPasswordVerified = password_verify($_GET['password'], $hash); // Prüfe eingegebenes Passwort gegen gespeichertes Passwort if($isPasswordVerified) { // Password korrekt } else { throw new PasswordVerificationException(""); } |
Referenzen
OWASP Einen umfangreicheren Überblick über die Anforderungen und die hierbei zu vermeidenden Probleme gibt es unter ASVS requirements on Cryptography (V7). Des Weiteren:
Andere |
Verteidigungs-Option 1 gegen 'Kryptografisch unsichere Speicherung':
tbd Text |
Verteidigungs-Option 2 gegen 'Kryptografisch unsichere Speicherung':
tbd Text |
Verteidigungs-Option gegen 'Kryptografisch unsichere Speicherung':
tbd Text | |
Auswirkung(en) auf den Benutzer
(ganze Breite) Text |
Referenzen
|
← A5-Sicherheitsrelevante Fehlkonfiguration | A7-Fehlerhafte Autorisierung auf Anwendungsebene → |
![CC-by-sa-3 0-88x31.png](/images/6/64/CC-by-sa-3_0-88x31.png)