mmofacts.com

Sicherheit

gepostet vor 13 Jahre, 11 Monate von MisterTom

Hallo,

ich habe das Gefühl, dass ich bei www.born2hack.de eine (oder sogar mehrere) Sicherheitslücken habe bzw. dass einzelne User an Daten in der DB kommen. Bekomme seit 2 Tagen solche "lustigen" Nachrichten...

Mein Problem ist allerdings, dass ich nicht weis, wie ich diese aufspüren soll, wo ich suchen soll und ob diese Lücken überhaupt existieren... Könnt ihr mir da ein paar Tipps geben?

Danke Tom

gepostet vor 13 Jahre, 11 Monate von DrakeL

Alle SQL Statements nach SQL Injection überprüfen wäre mein erster Schritt.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

ich würde mich ja im spiel registrieren und bisschen sicherheitslücken raussuchen.. jedoch kommt bei mir eine fehlermeldung, dass meine email nicht gültig ist.. meine email hat als endung @wmw.cc und die mail ist gültig

gepostet vor 13 Jahre, 11 Monate von MisterTom

Original von BlackScorp

ich würde mich ja im spiel registrieren und bisschen sicherheitslücken raussuchen.. jedoch kommt bei mir eine fehlermeldung, dass meine email nicht gültig ist.. meine email hat als endung @wmw.cc und die mail ist gültig

Da hast du Recht. Ich habe den Text der Fehlermeldung erweitert.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

wieso nur .com .net .at .ch .eu .de ? was ist wenn ich zuhause einen eigenen mailserver laufen habe mit DynDNS und dann mit einer .ath.cx ändung? ich würde an deiner stelle folgenden reg ex nehmen

/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/

damit kann man auch prüfen ob mail eine richtige syntax hat..

gepostet vor 13 Jahre, 11 Monate von DrakeL

Original von BlackScorp

wieso nur .com .net .at .ch .eu .de ? was ist wenn ich zuhause einen eigenen mailserver laufen habe mit DynDNS und dann mit einer .ath.cx ändung? ich würde an deiner stelle folgenden reg ex nehmen

/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/

damit kann man auch prüfen ob mail eine richtige syntax hat..

"[email protected]" reicht als Prüfung auch um den Benutzer davor zu schützen aus Versehen einen Nicknamen statt einer E-Mail Adresse eingegeben zu haben.

Alles Andere führt in der Regel zu Problemen und bietet kaum Mehrwert. Man muss ja wegen solchen unnötigen Prüfungen ja Angst haben irgendwelche Umlaute in E-Mail Adressen zu verwenden oder gar nicht lateinische Schriftzeichen.

Im Bestenfall validiert der Benutzer seine E-Mail Adresse im Nachhinein per Bestätigungslink. Das ist die einzige Möglichkeit relativ sicherzustellen, dass der Benutzer auch seine E-Mail Adresse eingetragen hat.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

Original von DrakeL


"[email protected]" reicht als Prüfung auch um den Benutzer davor zu schützen aus Versehen einen Nicknamen statt einer E-Mail Adresse eingegeben zu haben.


und wie willste das machen? explode('.',$email) und was wäre dann mit user die [email protected] als mail haben.. laut der webseite http://www.regular-expressions.info/email.html soll dieser pattern 99,99% der mails validieren und ein kleiner

if(preg_match($patter,$mail)){

}else{

ist besser als explode und bla... wie dem auch sei..  sein anliegen war doch dass er denkt dass er sicherheitslücken hat, das wollte ich prüfen und seine validierung erlaubt es mir nicht...

MFG

gepostet vor 13 Jahre, 11 Monate von DrakeL

Original von BlackScorp

Original von DrakeL


"[email protected]" reicht als Prüfung auch um den Benutzer davor zu schützen aus Versehen einen Nicknamen statt einer E-Mail Adresse eingegeben zu haben.


und wie willste das machen? explode('.',$email) und was wäre dann mit user die [email protected] als mail haben.. laut der webseite http://www.regular-expressions.info/email.html soll dieser pattern 99,99% der mails validieren und ein kleiner

Per Regex zum Beispiel (bin kein Regex Spezialist, das überlasse ich gerne Anderen, aber könnte so in der Art funktionieren): "/.+@.+/..+/"

Ich habe nichts gegen Regex Allgemein, aber diese zeilenlangen Prüfungen um eine E-Mail Adresse nach allen Standards zu validieren halte ich für sinnlos. Vor allem gibt es X Varianten wovon ich noch nicht eine gesehen hab die zu 100% alle validen E-Mail Adressen erkennt ohne dass man eine Doktorarbeit braucht um den Regex zu verstehen.

Also warum solch einen Aufwand mit komplexen Regex, wenn es kaum Mehrwert bringt? Oder was bringt es dir zu wissen dass die E-Mail Adresse nach allen Eigenarten valide ist?

Der Sinn für mich eine E-Mail Adresse überhaupt bei der Eingabe zu validieren besteht in meinen Augen nur darin dass ein Benutzer nicht einen Nicknamen oder Wohnort etc. eingegeben hat.

sein anliegen war doch dass er denkt dass er sicherheitslücken hat, das wollte ich prüfen und seine validierung erlaubt es mir nicht...

Das sowieso, aber warum nicht bei der Gelegenheit seine anderen Probleme mit ansprechen und diskutieren.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

Original von DrakeL


Also warum solch einen Aufwand mit komplexen Regex, wenn es kaum Mehrwert bringt? Oder was bringt es dir zu wissen dass die E-Mail Adresse nach allen Eigenarten valide ist?


naja die beste validierung ist ja die email bestätigung aber dennoch finde ich halt ein regex(wenn man schon emails validiert) besser als so ein explode und checke ob es so ausschaut [email protected] und wie will man das checken? man spaltet alles nach . und  @ und dann haben ja einige email adressen doppelte namen vor dem @ oder doppelte nach dem @ (yahoo.aol.com) dann hat man plötzlich viel mehr elemente die man prüfen müsste ... und und und... desswegen so ein ellenlanger regex.. mir gefällt es persönlich besser als wenn ich mir gedanken machen müsste wie ich jetzt den string aufspalte was ich da prüfe... vor allem diesen regex habe ich einfach mit copy und paste eingefügt und hatte weniger aufwand dadurch;)

MFG

gepostet vor 13 Jahre, 11 Monate von TheUndeadable

> explode

Wieso bist du so bockisch auf ein Explode?

$validMail = strrpos ( $mail, '@' ) < strrpos ( $mail, '.' );

Oder so ähnlich...

Aber abgesehen davon... Diese Diskussion hilft dem Threadersteller momentan wenig.

Nur als Tip: Sicherheit nachträglich reinzufriemeln ist nahezu hoffnungslos. Man fängt bei der Konzeptphase an.

Ich empfehle dir folgende Website:

http://msdn.microsoft.com/de-de/library/ms995349.aspx

Kurz und schmerzlos: Sicherheit entsteht von Grund auf. Gibt meines Wissens nach auch einen Thread hier im Forum von mir.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

Original von TheUndeadable

Diese Diskussion hilft dem Threadersteller momentan wenig.

das habe ich auch gesagt..

Nur als Tip: Sicherheit nachträglich reinzufriemeln ist nahezu hoffnungslos. Man fängt bei der Konzeptphase an.

Ich empfehle dir folgende Website:

http://msdn.microsoft.com/de-de/library/ms995349.aspx

ja aber dann müsste er ja von vorne anfangen mit dem game:D und außerdem schau mal an die letzte stelle in dem bild auf der msdn seite "Security Updates" .. also es ist nicht so hoffnungslos;)

gepostet vor 13 Jahre, 11 Monate von NeoWhoRU

Also lücken kann es mehrere geben ..um mal aufs Thema zurück zukommen und dir ein paar hilfreiche ansätze zugeben.

1. SQL Injektion (wurde ja genannt)
Meistens durch fehlendes escapen der Usereingaben. Wichtig hierbei : mysql_real_escape_string bei jedem Wert der von aussen in die Datenbank getragen wird (egal bei welcher Art von Queries).

Ein stumpfes beispiel:
Wir haben $_GET['value'] und dies hat auch einen Wert .
Wenn du mit dem Wert direkt im SQL Query arbeiten willst dann solltest du folgendes tun :
"SELECT * FROM tabelle WHERE fieldname='".mysql_real_escape_string($_GET['value'])."' "
Injections können durch $_POST, $_GET und $_COOKIE Variablen kommen .
2. XSS (Cross Site Scripting)
Wird oft ebenfalls unterschätz. Nun wie funktioniert XSS ? XSS bedeutet ein User kann (schadhaften) Javascript Code ausführen.
Dabei gibt es hier mehre ansätze. Zum einen sollten Fileuploads überprüft werden (bei Bilderuploads wirklich nur bilder erlauben).
Zum anderen sollte man usereingaben in Textfelder und Input Felder generell filtern mit htmlentities bzw. strip_tags (falls man gar kein html erlauben will).
Sollte man nix filtern, und die Werte stumpf in die DB schreiben und diese auch so wiederausgeben, so ist es möglich daß der user beispielsweise folgende html Tags setzen kann:

alert("XSS");
Btw. hab ich gerad gemerkt das auch galaxynews eine XSS Lücke hat und zwar kam gerad das alert hoch :)

3. Mögliche andere Ursachen
Es gibt auch mögliche andere ursachen (wie es mir schon passiert ist), daß beispielsweise sicherheitslöcher in software von dritten steckt. Beispielsweise : PHPmyadmin , statistik tools etc.
Daher gilt hier : bleibe immer up2date.

4. Register_globals off
Sollte standardmäßig gesetzt sein. Wenn der Wert auf On steht, ist es im Code nicht mehr relevant ob du nun $var als cookie, post oder get übergibts. Dies sollte aber zwingend auf off stehen und du solltest generell im Code sauber $_POST und $_GET unterscheiden in der hinsicht ;).

gepostet vor 13 Jahre, 11 Monate von BlackScorp

was auch noch oft unterschätzt wird, sind die Hiddenfelder sowie select option felder.. oft denkt man ja dass der User damit nichts machen kann.. aber mit dem Tool firebug kann man einfach den Value wert verändern;)

EDIT: ist das nicht Ironie das spiel "Born 2 Hack" wurde gehackt....

gepostet vor 13 Jahre, 11 Monate von Eckstoss

Jeder hat mal klein angefangen

Deswegen ist ein Konzept das a und o, um auch Fehler zu vermeiden.

Eventuell solltet Ihr für neue Projekte ein Framework einsetzen, da sind zwar auch ein paar Bugs vorhanden, aber dahinter stehen Teams.

Jedenfall viel Erfolg, und einfach aus den Fehlern lernen.

Nobody is perfect

gepostet vor 13 Jahre, 11 Monate von MisterTom

Hallo,

und erstmal Danke für die zahlreichen Antworten :)

Kurze Frage zu SQL-Injection: Ist es wichtig, dass mysql_real_escape_string direkt in jedem SQL-Query steht? Ich übergebe Werte mittels $_POST und $_GET und nutze diese dann in mehreren Querys.

$var = mysql_real_escape_string($_POST['var']);

SELECT * FROM tab1 WHERE Feld1 = '$var'

SELECT * FROM tab72 WHERE Feld4 = '$var'

Oder

SELECT * FROM tab1 WHERE Feld1 = 'mysql_real_escape_string($_POST['var'])'

SELECT * FROM tab72 WHERE Feld4 = 'mysql_real_escape_string($_POST['var'])'

Bieten beide Möglichkeiten die gleiche Absicherung?

Tom

gepostet vor 13 Jahre, 11 Monate von Miphois

zum Thema Sicherheit
Das wichtigste vorweg, ich traue nie den Daten die du von User erhältst. Aber das solltest ihr ja schon wissen.
Also was sicher gefiltert werden muss sind HTML und SQL Elemente also grösser und kleiner als und Anführungzeichen, am besten gleich ersetzten mit < > usw.
Ich hoffe GN kann die ganzen Zeichen auch alle richtig darstellen.
Ich habe es bei mir so gelöst. Alle Daten welche vom Benutzer übergeben werden. Egal ob GET POST COOKIE oder SESSION durchlaufen erst einen Filter der genau diese Zeichen rausholt.
Das ist eine Grundfunkion welche ich immer direkt nach dem setzen er Headerdaten aufrüfe:
Wenn man keine Sessions oder Cookies verwendet kann man den ganzen Teil dazu natürlich auch weglassen.

while (list($key,$value) = each($_GET)) {
    $_GET[$key] = filterbase($_GET[$key]);
}
while (list($key,$value) = each($_POST)) {
    $_POST[$key] = filterbase($_POST[$key]);
}
while (list($key,$value) = each($_SESSION)) {
    $_SESSION[$key] = filterbase($_SESSION[$key]);
}
while (list($key,$value) = each($_COOKIE)) {
    $_COOKIE[$key] = filterbase($_COOKIE[$key]);
}
Die Filterfunktion sieht so aus (Ich übergebe Teils auch Array Sessions, daher der Array Zusatz):
function filterbase($value) {
    $trans = array ("<" => "<", ">" => ">", "\\'" => "'", "\\\"" => """, "&" => "&");
    if(is_array($value)){ //Prüft ob Array
        while (list($key,$avalue) = each($value)) { //Alle Arrayelemente einzeln Filtern
            $value[$key] = strtr($value[$key], $trans); //Zeichen ersetzen
        }
    }
    else{
        $value = strtr($value, $trans); //Zeichen ersetzen
    }
    return $value;
}
Ohne diese Zeichen ist ein JS, HTML oder mySQL Angriff doch nur schwer möglich? Und in Texten die der User schreibt werden diese dann trotzdem vom Browser richtig dargestellt.
Einziges Manko ist, Text kann so in den Datenbankfeldern mehr Platz brauchen. Also ein Nickname Sak'Kra würde dann 13 statt 7 Zeichen lang. Ich lasse aber eh keine Sonderzeichen in Nicknamen zu von daher ist dies kein Problem bei mir.
Zusätzlich verwendete bis jetzt immer addslashes zum implementieren in SQL Statmends. Ich habe aber dies wegen dieses Threads nun in mysql_real_escape_string geändert.
Reicht diese Sicherheitsmassnahmen oder was meint Ihr?

gepostet vor 13 Jahre, 11 Monate von BlackScorp

Sessions kommen vom User??

und was ist hiermit?

htmlentities

und dann while(list($key... ? würde foreach($_COOKIE as $keks => $fuellung) es auch net tun?

@ mister tom.. ich mache das bei mir immer so(bzw bevor ich PDO genutzt habe):

PHP:


$query = "SELECT * FROM tabelle WHERE foo = '%s' AND bar '%s' AND id = %d"; if(is_numeric($_POST['id'])){ $id = $_POST['id']; }else{ $id = mysql_real_escape_string($_POST['id']); //numeriche zahlen baucht man nicht escapen } $foo = mysql_real_escape_string($_POST['foo']);
$bar = mysql_real_escape_string($_POST['bar']);
$sql = mysql_query(sprintf($query,$foo,$bar,$id));
while($row = mysql_fetch_object($sql)){
echo $row->spalte1;
}

und wenn du eine variable einmal escaped hast, musst du die nicht nochmal escapen

gepostet vor 13 Jahre, 11 Monate von Miphois

foreach mag ich nicht so :D
Nee der Code hat schon einige Jährchen auf dem Buckel heute würde ich auch foreach verwenden.

Gibts dadurch eigentlich nen Speedvorteil? Dann ändere ich das nämlich.

htmlentities liefert mir nicht das gewünschte Ergebnis da bei " und ' die \ davor nicht gleich mit entfernt werden.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

ich weis nciht ob es ein speedvorteil gibt aber ich denke mal schon, weil du ja die funktion list nicht mehr aufrufst(ich denke aber dass es nicht merkbar ist, keine ahnung)

zu htmlentities, da kannste noch als 2en parameter ENT_QUOTES angeben und diese funktion mit stripslashes bzw stripcslashes verwenden.. oder schau dir mal die funktion htmlspecialchars an und vergiss die 2en übergabe parametern nicht;)

zu dem würde niemals von vornerein die variablen verändern, manchmal führe einfach nur rechnung oder setze strings erstmal zusmmen aus den variablen.. ich würde es ,vor dem eintragen in die datenbank , umwandeln

MFG

gepostet vor 13 Jahre, 11 Monate von Miphois

quote_stylehabe ich schon durchprobiert da kann man einfach " oder ' ausschliessen.
PHP übergibt mir aber Formulardaten mit \' und \" und ich moechte es ungern in der php.ini deaktivieren, da sonst eventuell andere Seiten davon Betroffen sind.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

naja jedem das seine;)

gepostet vor 13 Jahre, 11 Monate von NeoWhoRU

Du kannst natürlich auch vorher escapen.

das mit dem "is_numeric" ist übrigends auch ne tolle variante.

Aber was viele nicht wissen : seit PHP (ich bin mir nicht sicher, glaub aber es war 5.2.X - korrigiert mich wenn ich falsch liege :)) gibt es eine Filter extension (die generell von einigen Frameworks auch benutz wird, beispielsweise cakephp).
Die Filter Extension erlaubt es dir Daten vereinfacht zu validieren / zu filtern . Dies wurde extra dazu eingeführt, gerade neulinge das Filter von Variablen zu vereinfachen.
Filter Var
Ihr könnt zum beispiel prüfen ob eine Variable ein String , INT oder eine URL oder E-Mail sein soll.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

Original von NeoWhoRU

das mit dem "is_numeric" ist übrigends auch ne tolle variante.

ist das Ironisch gemeint;)?

muss gestehen das mit dem Filter habe ich mir mal früher angeschaut aber auch schnell wieder  verdrängt.. denke das könnte ich in mein FW implementieren dann bruach ich diesen ellenlangen regex nicht mehr:D und is_numeric würde auch wegfallen:D

gepostet vor 13 Jahre, 11 Monate von TheUndeadable

Original von MisterTom

Hallo,

und erstmal Danke für die zahlreichen Antworten :)

Kurze Frage zu SQL-Injection: Ist es wichtig, dass mysql_real_escape_string direkt in jedem SQL-Query steht? Ich übergebe Werte mittels $_POST und $_GET und nutze diese dann in mehreren Querys.

$var = mysql_real_escape_string($_POST['var']);

SELECT * FROM tab1 WHERE Feld1 = '$var'

SELECT * FROM tab72 WHERE Feld4 = '$var'

Oder

SELECT * FROM tab1 WHERE Feld1 = 'mysql_real_escape_string($_POST['var'])'

SELECT * FROM tab72 WHERE Feld4 = 'mysql_real_escape_string($_POST['var'])'

Bieten beide Möglichkeiten die gleiche Absicherung?

Tom

Oberes reicht aus, allerdings würde ich nicht die SQL-Statements von Hand zusammenbauen, da bereits '1x Vergessen' zu einer Lücke führen kann.

Besser ist es sicherere APIs, wie zum Beispiel PDO für den Datenbank-Zugriff werden.

Nicht nur Sicherheitslücken müssen vermieden werden, es muss bereits vermieden werden Sicherheitslücken zu erzeugen!

Defense in Depth!

gepostet vor 13 Jahre, 11 Monate von knalli

Das ganze findet man unter der Thematik "Prepared Statements". Gute Wrapper bieten die an, und einige Datenbanksysteme (etwa Oracle) können damit sogar direkt angeben (ein prepared Statement kann logischerweise besser gehashed werden als eins mit finalen Literalen (sprich Werten)).

In PHP kann man das (vereinfacht!) zB auch so machen:

$pstm = 'SELECT name FROM users WHERE emailAddress = "%s"';

$sql = sprintf($sql, escape($var));

Hier: Die Funktion escape ist dann bspw. ein mysql_real_escape. Bei *printf nicht vergessen, dass auch ein '%' => '%%' gemacht werden muss.

gepostet vor 13 Jahre, 11 Monate von BlackScorp

schau mal im thread nr 17;)

gepostet vor 13 Jahre, 11 Monate von dreaddy

Um konkret den Fehler zu finden(obige Dinge machen trotzdem Sinn) würde einfach mal alle sql abfragen wrappen:

Speichere dir je nach Userzahl in Datenbank(wenig user) oder Datei(viele user)

- SQL-Befehl, User, timestamp, aktuell offene Seite mit dazugehörigen Variablen, ggf post und get variablen

Sobald es ein User wieder macht, hast du die Lücke indem du zb nach seiner dir geschickten Botschaft suchst (und den User, was aber eher unwichtig ist, immerhin heißt das Spiel born2hack ;) ).

Auf diese Diskussion antworten