Neue Seite erstellen

Bei der einfachen Abfrage nicht, und ich habe extra durch das Typecasting nach Integer schon sämtliche Hürden vermieden. Wenn du es absolut idiotensicher machen möchtest, kannst du noch [phpf]mysql_real_escape_string[/phpf] verwenden:

PHP:
$sql = "
    SELECT  `namen`, `links`, `...`
    FROM  `tabelle`
    WHERE  `id` = '" . mysql_real_escape_string($_GET['id']) . "';";

Aber das ist total unnötig in diesem Fall, da ein Integerwert keine Schadhaften Sequenzen einfügen kann (Außer einen eventuellen Bufferoverflow oder was nicht alles - Aber das läge dann an der Datenbank selbst ;) - Und sowas ist via MySQL zB gar nicht möglich).

Böse kann nur zB folgendes Statement werden:
PHP:
<?php
// überprüfen, ob passwort und user auf eingabe zutreffen. wenn ja --> login
$sql = "
    SELECT COUNT(*)
    FROM `user`
    WHERE `username` = '{$_POST['username']}' AND
        `password` = '{$_POST['password']}';";
Denn da könnte man in POST['password'] folgende Sequenz einschleusen:
Code:
' OR `password` != NULL
Und das Resultat wäre:
SQL:
SELECT COUNT(*)
FROM `user`
WHERE `username` = 'eingabe' AND
      `password` = '' OR `password` != NULL;

Vorbeugend kann hier das Query ein wenig umgebaut werden, so dass alle bösartig nutzbaren Zeichen escaped werden:

PHP:
<?php
// überprüfen, ob passwort und user auf eingabe zutreffen. wenn ja --> login
$sql = "
    SELECT COUNT(*)
    FROM `user`
    WHERE `username` = '" . mysql_real_escape_string($_POST['username']) . "' AND
        `password` = '" . mysql_real_escape_string($_POST['password']) . "';";
 
Code:
$password=crypt($password,$schluessel);
$password .= "\n";
$log=0;

$user_check=mysql_query("SELECT * FROM " . PRE_DB . "user WHERE Name='" . $_REQUEST['username'] . "'");
$user_check=mysql_fetch_array($user_check);

if($user_check['Passwort']===$_REQUEST['password'])
    {
    $log=1;
    }
    
if ($log==1)
{

Wäre der Code denn sicher?

Gruß und danke =)
 
Erstes Leck: Eigentlich solltest du wissen, ob der Request über POST oder GET reinkommt. $_REQUEST ist nicht empfohlen, es sei denn, du brauchst es wirklich.
Zweites Leck: Ungeprüfte Eingabe an Datenbank übergeben...
SQL:
SELECT *
FROM " . PRE_DB . "user
WHERE Name = '$_REQUEST['username']';
Mögliche Injection wäre zB:
SQL:
SELECT *
FROM " . PRE_DB . "user
WHERE Name = '' OR Name !='';
Und eventuellerweise hat jemand ein Passwort, dass mit der Eingabe übereinstimmt. Reduzierung der Gefahr:
PHP:
$sql = "
    SELECT COUNT(*)
    FROM `prefix_user`
    WHERE `Name` = '" . mysql_real_escape_string($_POST['username']) . "' AND
          `Passwort` = '" . mysql_real_escape_string(crypt($_POST['password'], $schluessel)) . '"
    LIMIT 0,1;";

$result = mysql_query($sql);
list($user_exists) = mysql_fetch_row($result);
settype($user_exists, 'boolean');
if ($user_exists == true) {
    // ...
}
Das zweite Escapen ist optional, aber außer 0.000001 Sekunden mehr schadet es niemandem. Des Weiteren wird direkt in der Abfrage übreprüft, ob User und Passwort auf einen Record zutreffen. Die Limit Clause vermeidet, dass eventuell mehrere Datensätze abgeholt werden, ist aber nicht wirklich notwendig.
Anschließend wird die Anzahl (Maximal 1, minimal 0) im Script abgeholt und nach boolean umgewandelt. Wenn das dann wahr ist, kannst du zB den Benutzer als eingeloggt ansehen.

Die Grundregel für PHP - so genial ich die Programmier-, Script- oder Templatesprache auch finde - lautet: Vertraue nie der Eingabe eines Client. Demnach solltest du auch wirklich alles immer überprüfen und validieren, bevor du damit arbeitest.
 
Hm..jedoch zeigt er bei mir immer

Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result

in Zeile: list($user_exists) = mysql_fetch_row($result);
an. Das fehlende ' hab ich schon nach LIMIT 0,1" gesetzt.
 
Hm.. Ok das Problem wäre gelöst, aber trotzdem geht er in die Else-Anweisung, also Benutzername bzw Passwort falsch.... :eek:

Hab mal die übertragenen Daten ausgegeben: Die Daten (NAME und PW) werden ordnungsgemäß übertragen.....

Liegt wohl am Schlüssel ( '" . mysql_real_escape_string(crypt($_POST['password'], $schluessel)) . '")

Ohne den Schlüssel geht es - aber sind die Daten dann nicht unverschlüsselt und somit leicht angreifbar?
 
Zuletzt bearbeitet:
Kleiner Tippfehler im Query, sorry^^

Grundsätzlich sind sie deswegen nicht unsicherer, aber es geht dennoch sicherer mit einem sogenannten SALT-Value, also dem Salz in der Suppe. Ein einfaches Beispiel dazu bietet die vBulletin Forensoftware, die es folgendermaßen löst:
Bei der Registrierung wird ein einzigartiges SALT für den Nutzer festgelegt. Das ist eine, in diesem Fall, dreistellige Zeichenkette, die man zB über substr(md5(microtime()), 0, 2) erhalten könnte. Das unverschlüsselte Passwort wird nun über folgendes Verfahren mit dem Salz gewürzt:
PHP:
$store_in_db = md5(md5($clear_pw) . $salt_from_db);

Beim LogIn wird das Passwort dann über Javascript bereits als md5-verschlüsselter String an den Server geschickt und dort über
PHP:
if ($fetched_pw_from_db === md5($sent_pw . $salt_from_db))
verwertet. So oder ähnlich, oder ganz anders lässt sich die Sache nochmal ein bisschen besser absichern.

Dachte nur, da du was mit $schluessel bereits stehen hattest, dass ich es so übernehmen hätte können^^
 
Zurück