kostenloser Webspace werbefrei: lima-city


Wie sicher ist $pdo->prepare($query)

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    all-in1

    Kostenloser Webspace von all-in1

    all-in1 hat kostenlosen Webspace.

    Wie sicher ist
    $pdo->prepare($query)


    Sollte man dennoch auf SQL Injection acht geben?
    Arbeitet es genauso wie mysqli_real_escape_string?


    Und wie sicher sind die Filter Funktionen von PHP, insbesondere für string, url und email?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. all-in1 schrieb:
    Wie sicher ist
    $pdo->prepare($query)
    Da kann nichts mehr schief gehen - vorausgesetzt, du verwendest es auch richtig. Die
    $query
    muss konstant sein oder aus sicherer Quelle kommen. Also auf keinen Fall ungefiltert Benutzereingaben einfügen. Diese werden über
    bind_param
    mit eingebunden und alles ist sicher. Die Funktionsweise ist etwas anders, als bei
    mysql_real_escape_string()
    , doch das passiert alles zwischen dem PHP-Parser und DB-Server. Das PHP-Skript hat mit der Maskierung nicht mehr direkt zu tun.


    all-in1 schrieb:
    Und wie sicher sind die Filter Funktionen von PHP, [...]

    String:
    Meinst du das?
    filter_var($userInput, FILTER_SANITIZE_STRING);
    Dann erklär mir bitte mal jemand, was diese Funktion tut, außer alles in einen String zu verwandeln. Schlägt die auch irgendwann mal fehl und gibt false zurück?
    Oder anders gefragt: Wenn du einen String prüfst, welche Bedingung sollte dieser deiner Meinung nach erfüllen?

    Url:
    filter_var($userInput, FILTER_VALIDATE_URL);
    Diese prüft nur, ob es sich um eine Url handeln könnte. Vergiss aber nicht zu maskieren, wenn du z.B. einen Link zusammenbaust.

    E-Mail:
    filter_var($userInput, FILTER_VALIDATE_EMAIL);
    Diese Funktion arbeitet sehr streng. Du kannst die gefilterte Eingabe verwenden, um an die Adresse eine E-Mail zu senden. Ein Angreifer kann dann über deinen Webserver keine Spam-Mails (mit eigenem Text) versenden. Ohne Filter wäre das dagegen denkbar.
  4. g****e

    Die Frage ist ungefähr so so beantworten wie "Wie sicher ist dieses Boot auf hoher See". Es kommt drauf an wie du es fährst (naja, und auf das Boot, aber PDO ist ein sehr gutes)!

    Prinzipiell, wenn du prepared Statements korrekt verwendest, sind mir keine Angriffsmöglichkeiten mehr bekannt, aber fangen wir vorne an.

    Eine SQL Injektion funktioniert durch ein ungewolltes manipulieren des SQL Statements. Das passiert besonders einfach durch das unachtsame verwenden von GPC (Nutzereingaben):

    mysql_query('SELECT * FROM `users` WHERE password=' . $_GET['data']);


    Ein prepared Statement geht dabei aber total anders mit dem SQL Statement um. Vereinfacht gesagt evaluiert das prepare das Statement bereits, und es wird bereits übersetzt. Das heißt, das Statement ist nicht mehr änderbar. Du fütterst es nurnoch mit Daten:

    $stmt = $pdoDb->prepare('SELECT * FROM `users` WHERE password=?');
    $stmt->execute(array($_GET['data']));


    Dadurch, dass das Prepare die Query unveränderbar macht, kann das Execute beinhalten was du willst, es wird immer sicher vor SQL Injections sein.

    Wenn du allerdings:

    $stmt = $pdoDb->prepare('SELECT * FROM `users` WHERE password=' . $_GET['data']);
    $stmt->execute();


    Schreibst, hast du nichts gewonnen, weil dann die Nutzereingaben mit ausgewertet werden.

    Bei richtiger Verwendung ist mir keine Möglichkeit bekannt, wie eine SQL Injection noch möglich ist. Bei falscher Verwendung gibt es die selben Probleme.

    mysqli_real_escape_string escaped den String, sodass "Böse" Zeichen nicht mehr ausgewertet würden. Ob man das umgehen kann, weiß ich nicht.

    Und welche Filterfunktionen meinst du genau?
    Meistens liest man inden Kommentaren zu der Doku auf php.net schon hilfreiche Dinge, wie gut etwas ist. Bei den Email Filtern war damals, wenn ich mich recht erinnere, das Problem, dass sowas wie @test valide war, ohne eine Topleveldomain. KA ob das noch besteht

    Liebe Grüße

    Beitrag zuletzt geändert: 3.7.2015 20:44:51 von ggamee
  5. Autor dieses Themas

    all-in1

    Kostenloser Webspace von all-in1

    all-in1 hat kostenlosen Webspace.

    Ich bin gerade dabei mir einen dbhandler auf zubauen. War früher ja mal aktiv bei PHP-Fusion und habe mich da an die Funktionen etwas gewöhnt.

    Also wäre so etwas sicher:

    function dbquery($query, $execute='') {
    	global $pdo, $mysql_queries_count, $mysql_queries_time;
    	$mysql_queries_count++;
    	$query_time = get_microtime();
    	$result = $pdo->prepare($query);
    	$query_time = substr((get_microtime()-$query_time), 0, 7);
    	$mysql_queries_time[$mysql_queries_count] = array($query_time, $query);
    	if (!$result) {
    		print_r($result->errorInfo());
    		return FALSE;
    	} else {
    		$result->execute($execute);
    		return $result;
    	}
    }
     function check_user($name, $pass){
        $sql="SELECT userid
        FROM ".DB_USER."
        WHERE user_name=:name AND user_pass=:pass 
        LIMIT 1";
        $result= dbquery($sql, array(':name' => $name , ':pass' => $pass));
        if ($result){
            $user=dbarray($result);
            return $user['userid'];
        }else return false;
    }


    Wobei das Passwort schon bei Aufruf der Funktion entsprechend gehascht wird.

    Bei den Filtern benötige ich der Regel nur Email, URL, und natürlich integer, wobei man letzteres ja auch sehr gut mit is_numeric validieren kann.

    Mir geht es dabei in erster Linie auch nicht darum, ob es dann wirklich eine Email Adresse ist, sondern nur darum, dass man eben Spammails vermeidet.
    Bei der Url ja auch nur darum, dass kein Crosssitescripting möglich ist. Obwohl ich das auch noch etwas anders zusätzlich filtere. Nur wäre es durch aus schön, wenn ich eben den zusätzlichen Filter nicht benötigen würde, da es doch ein paar Zeilen Code mehr sind.
  6. XSS oder Header-Injections verhinderst du damit allerdings nicht. Lediglich SQL-Injections.
    Den Rest musst du selbst bei Ausgabe filtern. Das ist wie mit HTML-Spielereien und htmlentities.

    OT: Wofür benutzt du denn $mysql_queries_count und nicht einfach nur $mysql_queries_time[].
  7. Autor dieses Themas

    all-in1

    Kostenloser Webspace von all-in1

    all-in1 hat kostenlosen Webspace.

    muellerlukas schrieb:

    OT: Wofür benutzt du denn $mysql_queries_count und nicht einfach nur $mysql_queries_time[].


    $mysql_queries_count zählt alle DB Anfragen. Ich selbst benötige es zur Zeit gar nicht.

    Eventuell nachher bei einem meiner Großprojekte wieder, damit man sehen kann, wo noch etwas verbessert werden kann.

    Den Code habe ich noch mal etwas geändert nach einem Testlauf.

    function dbquery($query, $execute=array()) {
    	global $pdo, $mysql_queries_count, $mysql_queries_time;
    	$mysql_queries_count++;
    	$query_time = get_microtime();
    	$result = $pdo->prepare($query);
    	$query_time = substr((get_microtime()-$query_time), 0, 7);
    	$mysql_queries_time[$mysql_queries_count] = array($query_time, $query);
    	if (!$result) {
    		print_r($result->errorInfo());
    		return FALSE;
    	} else {
    		$result->execute($execute);
    		return $result;
    	}
    }


    So funktioniert das ganze besser und man muss den 2 Parameter nicht unbedingt angeben. Zum Beispiel bei Anfragen, wo definitiv keine SQL Injections möglich sind.
  8. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!