Security-Lehrstück StudiVZ

Sicherheit ist doch eigentlich SOOO einfach... Ich kanns kaum glauben... Langsam wird das definitiv zum Kavaliersdelikt... Furchtbar!

Ein Tutorial von mir für sichere Passwörter, die sich nicht mit Rainbow-Tables knacken lassen: http://www.cybton.com/tutorials_show,Siche...0,tut,1463.html
Wenn man sich an das Tut hält, ist man genau bei einem solchen Angriff sicher.

Eine grosse Rainbow-Table online zum Testen der eigenen PWDs ist übrigens z.B. gdataonline.

Die wichtisten Regeln:
- Passwort-Hashes generieren, die am besten gemäss einem eigenen Algorithmus verschlüsselt werden sollten (am sinnvollsten ist eine Weiterverarbeitung des MD5-Hashes)
- JEDE Variable, die vom User/Browser kommt, muss "entschärft" werden. Sogar der Browsername oder die Sprache müssen mit addslashes() für Logs mit Slashes versehen werden! Genauer:
* Datenbanken: addslashes(), falls magic_quotes off (gegen MySQL-Injections)
* URLs: urlencode() (gegen XSS)
* HTML-Text: htmlentities() (gegen XSS)
* Mail-Header-Daten: Zeilenumbrüche entfernen (gegen Spam)
* JavaScript-Alerts & Co.: addslashes() und htmlentities() (je nach Bedarf, gegen XSS)
- Single Quotes im HTML-Code vermeiden (In diesem Beispiel ist die vom User eingegebene Bildbeschreibung rot hervorgehoben: <img src='bild.jpg' alt='bild' width='1000' height='1000' onmouseover='...' />, gegen XSS) ODER bei htmlentities() als zweite Variable die Konstante ENT_QUOTES verwenden, die auch Single Quotes umwandelt.
- POST-Formulare (v.a. für E-Mail-Adressen- und Passwortänderung): In einem HIDDEN-Feld die Session-ID mitsenden, den Referer checken (kann evtl. umgangen werden) oder das Passwort in jedem Formular mitverlangen (schlecht für die Usability). Scheint auf Ayom nur teilweise geschlossen zu sein. (Notizen können von aussen geändert werden, jedoch ist das nicht weiter schlimm. Trotzdem sollte es behoben werden.) (gegen externe AutoSubmit-Formulare)
- GET-Formulare für Änderungen (UPDATE- oder INSERT-Befehle) vermeiden. Abfragen sind jedoch erlaubt. (wichtige Variablen stehen sonst in der URL und können von externen Anbietern aus dem Referer gelesen werden, oder aber es existiert dasselbe Problem wie bei POST)

Wenn man diese wenigen Regeln befolgt, hat man bereits 99% der Angriffe abgewehrt.

Ayom ist in dieser Hinsicht Vorbild (Im Vergleich zu phpBB, StudiVZ und vielen anderen wirklich VIEL genutzten Services).
 
Hm, ich versteh es nicht.
Kann man mit den ID Veränderungen auch Daten anderer Nutzer ändern bzw. wichtige interne Daten sehen oder was?
 
QUOTE (DaBone @ So 4.3.2007, 14:52)- POST-Formulare (v.a. für E-Mail-Adressen- und Passwortänderung): In einem HIDDEN-Feld die Session-ID mitsenden, den Referer checken (kann evtl. umgangen werden) oder das Passwort in jedem Formular mitverlangen (schlecht für die Usability).

Den Tipp verstehe ich nicht. Warum denn zusätzlich in einem Hidden-Feld?
Ich lese bei jedem Seitenaufruf die Session des Users aus und frage diese ab. Reicht das oder gibt es einen Grund für das Hidden-feld?
z.B.

CODE if(hatRecht($_SESSION['userid'],$vorgang)){
.........
}


Ansonsten sehr interessante Zusammenfassung! Habe ich noch nicht alles gekannt.

 
QUOTE Sicherheit ist doch eigentlich SOOO einfach.


QUOTE * Datenbanken: addslashes(), falls magic_quotes off (gegen MySQL-Injections)


Sicherheit ist leider nicht einfach wie diese Sätze zeigen. Addslashes oder magic_quotes gelten ja nicht gerade als die sicherste Lösung!
 
addslashes() halte ich für nicht so toll.
ich benutze htmlentities ( string string,ENT_QUOTES)
und bei numerischen angaben einfach vorher testen ob is_numeric() true ist.
 
QUOTE Den Tipp verstehe ich nicht. Warum denn zusätzlich in einem Hidden-Feld?
Ich lese bei jedem Seitenaufruf die Session des Users aus und frage diese ab. Reicht das oder gibt es einen Grund für das Hidden-feld?


Nehmen wir an, das E-Mail-Adressen-Änderungs-Formular sieht so aus:

CODE <form action="" method="post">
<input type="text" name="email" />
<input type="submit" name="submit" value="Absenden" />
</form>


Nun erstellt der Angreifer eine Seite, die so aussieht (stark gekürzt etc.):

CODE <html>
<head><title></title></head>
<body onload="form.submit()">
<form action="" method="post" id="form">
<input type="text" name="email" value="mail-adresse-des@angreifers.com" />
<input type="submit" name="submit" value="Absenden" />
</form>
</body>
</html>

Diese Seite schickt er dem Opfer zu (gleiches Vorgehen wie bei XSS).
Nun wird die Adresse in Unwissenheit der Users geändert und der Angreifer kann die "Passwort vergessen"-Funktion des Dienstes verwenden, um Zugriff zu bekommen.
Klar?


QUOTE Ansonsten sehr interessante Zusammenfassung! Habe ich noch nicht alles gekannt.
Danke.


QUOTE Sicherheit ist leider nicht einfach wie diese Sätze zeigen. Addslashes oder magic_quotes gelten ja nicht gerade als die sicherste Lösung!
Kommt drauf an. Wenn man die Abfragen entsprechend formuliert (immer Anführungszeichen verwenden), ist es, so weit ich weiss, 100% sicher. Ansonsten freue ich mich über ein Gegenbeispiel, ich lerne auch immer wieder gerne dazu.


QUOTE testen ob is_numeric() true
Aufgepasst damit. 5*10E2 ist, soweit ich weiss, auch ein numerischer Wert. Je nach dem gibts da evtl. noch eine Angriffsmöglichkeit, die Chance ist zwar extrem klein, aber man sollte sich dessen bewusst sein.


QUOTE addslashes() halte ich für nicht so toll.
ich benutze htmlentities ( string string,ENT_QUOTES)
HTML-Entities in der Datenbank halte ich für zweckentfremdend. Die HTML-Entities sollte man meiner Meinung nach so spät wie möglich generieren, damit sie wirklich nur im HTML-Code stehen. In die Datenbank gehört die möglichst ursprüngliche Version.
Sonst gibt es ein Durcheinander (Textareas, URLs etc. müssen dann wieder zurückgewandelt werden).

htmlentities(,ENT_QUOTES): Genau das habe ich vergessen! Die Konstante ENT_QUOTES habe ich bei meinem obigen Post noch ergänzt.
 
QUOTE (DaBone @ So 4.3.2007, 18:14)Diese Seite schickt er dem Opfer zu (gleiches Vorgehen wie bei XSS).
Nun wird die Adresse in Unwissenheit der Users geändert und der Angreifer kann die "Passwort vergessen"-Funktion des Dienstes verwenden, um Zugriff zu bekommen.
Klar?

Das ist ein schönes Beispiel für konzeptionelle Fehler, die nicht durch die obige Liste abgefangen werden.

Die Änderung der Mailadresse muß zwingend die Eingabe des Passwortes erfordern.

Diese Liste stopft deshalb - vielleicht - 5% der potentiellen Sicherheitslücken, nicht 99%.

Und bei einem Nutzer, der Daten in ein per Mail zugesandtes Formular eingibt und es absendet, bei dem ist ohnehin alles vergeblich.
 
QUOTE (hatschi1810 @ So 4.3.2007, 18:50)Ein Beispiel wie addslashes versagen kann:
http://shiflett.org/archive/184

Leider gibt es halt auch Methoden um mysql_real_escape_string zu umgehen.

Jo, solche Dinge skizzieren einige der Probleme. Die eigentliche Schlußfolgerung steht gleich im ersten Kommentar:


QUOTE My main advice to people is to always use prepared statements and then bind your parameters. Even if you are not planning to reuse the prepared statement, and won't get any performance benefit from doing so, it will prevent your apps from being attached using SQL injections because parameters are bound after the statement is compiled.
People just shouldn't be using anything else!


Aber dies ist das, was die meisten PHP/mySql - Nutzer leider nicht so gerne hören möchten, da dann nämlich der Entwicklungsaufwand dramatisch ansteigt:

Alle Datenänderungen über gespeicherte Prozeduren abwickeln und nur ein Backend nutzen, das dies unterstützt.

Und spätestens dann ist nichts mehr mit 'StudiVZ in einer Woche entwickeln'.
 
QUOTE
Nennt sich dann Rainbow-Tables und existiert in der Tat bereits. Komplexe Passwörter, insbesondere auch mit Sonderzeichen sind aber dennoch recht sicher, da es keine "Kompletten" Rainbow-Tables geben kann. .


Dass MD5-Hashes mit Rainbow-Tables gehackt werden, kann man jedoch ganz einfach mit Salts verhindern.


CODE
<?PHP
md5( "$userid-$password" );
?>


Somit hat jeder User ein eigenes Salt, was natürlich Rainbow-Tables unnütz macht. Der einzige Weg die Passwörter dann noch zu knacken ist bruite force, was sehr lange dauern kann...
 
QUOTE Das ist ein schönes Beispiel für konzeptionelle Fehler, die nicht durch die obige Liste abgefangen werden.
???
Ich hab ja die entsprechende Lösung in der Liste genannt.

Für die andere Methode habe ich jedoch keine Konzeptlösung parat. Allerdings steckt hier der Fehler meiner Meinung nach eher bei PHP, da addslashes() seinen Dienst nicht zu 100% korrekt verrichtet. Ich habe mir bereits überlegt, dass entsprechende Zeichen existieren müssen (Sonderzeichen bestehen ja immer aus 2 Zeichen, wie man es immer an den Umlauten sieht, die falsch interpretiert werden). Hier könnte man allerdings auch alle "bösen" Sonderzeichen vorher rausfiltern.

Die von madox genannte und sehr sinnvolle Variante ist genau so eine von mir genannte Weiterverarbeitung des MD5-Hashs.
Man kann beispielsweise auch ganz einfach den MD5-Hash nochmals hashen, und schon bringen die ganzen Rainbowtables nichts mehr.

EDIT: Aaah das ewige Character Encoding... Kennt da jemand ein gutes allgemeines Tutorial? Ich blick da kaum durch.
 
Lasst uns doch mal eine Funktion entwickeln, die man dann auf alle DB einträge anwenden kann. Das wäre sicherlich für viele praktisch.
z.B.
function mysql_insert_format($text,$feldtyp,$feldgroesse){

}

Aufruf zb mit $_POST['Username'] = mysql_insert_format($_POST['Username'],"varchar","15");


Oder gibt es sowas schon?
 
Zurück
Oben