Daten sicher in Tabelle speichern

  • Hallo zusammen,
    ich brauche einen Rat. Wie speicher ich Daten sicher in einer Datenbank.
    Es geht um ein Textarea Feld, wo die benutzer schrieben können was sie wollen.
    Natürlich wünsche ich dabei kein XSS.
    Bis dato filter ich die Eingabe mit htmlspecialchars+ENT_QUOTES+UTF8


    Reicht das aus oder bedraf es noch einen weiteren Filter?


    Dazu möchte ich wissen, ob ich die Ausgabe aus der Datenbank dann auch wieder filtern muß?


    Grüße,
    Denis

  • Hallo,


    hier kann dir die richtige Wahl der "Schnittelle" viel Arbeit abnehmen. PHP bietet mittlerweile so einige Klassen zum Datenbankmanagement. Gegenwärtig solltest du MySQLi oder PDO nutzen. Letzteres bevorzuge ich wegen der Möglichkeit mehrere unterschiedliche Datenbanken parallel anzusprechen (mehrere Driver, also nicht nur MySQL).


    Beide Klassen bringen jedoch die Möglichkeit mit, Datenbankabfragen abzusichern. Hier ein Beispiel mit PDO:



    Abgesehen von der echo-Ausgabe, kann dir bei diesem Code nichts passieren. Mit prepare bereitest du einen Query vor. ? dient dabei als Platzhalter (kann man auch weiter spezifizieren, dafür einfach mal die Dokumentation lesen). Via execute werden für die Platzhalter "Daten" übergeben und der Query wird ausgeführt. Fetch holt die Daten (als Object). Fertig.

  • Hallo,
    erstmal vielen Dank!
    Wie bekomme ich denn raus welche Version ich nutze? Und woher bekomme ich diese Klasse?
    Ich bin bei Allinkl.de
    Der Code sieht ja recht kompliziert aus :-)
    Ist das ähnlich der WP Funktion esc() ?
    Für mich sinniger wäre vielleicht einfach so eine Funktion wie bei WP.
    Warum würde denn dieses htmlspecialchars+ENT_QUOTES+UTF8 nicht ausreichen?
    Grüße,
    Denis

  • Hallo,


    es würde schon ausreichen. Aber folgendes Beispiel:
    Du musst von Berlin nach Köln. Du kannst dir nun ein eigenes Auto bauen und versuchen die lockeren Reifen mit htmlspecialchars+ENT_QUOTES+UTF8 zu befestigen. Oder du steigst um auf den Zug, welcher schneller, sicherer und günstiger ist.


    Die Klassen sind in PHP bereits enthalten. D.h. du kannst sie sofort nutzen.


    Zum Thema kompliziert: Wenn du bisher mit mysql_*-Funtionen gearbeitet hast, wird dir der Umstieg nicht schwer fallen. Die Querys bleiben gleich (sind ja auch unabhängig vom PHP-Code, welcher quasi nur der Wrapper zwischen den beiden Ebenen ist) und du musst nur die Variablen übergeben.


    Wordpress solltest du in diesem Zusammenhang ganz schnell vergessen. Die aktuelle 3.5.1-Version benutzt noch immer mysql_*-Funktionen (wie mysql_query etc). Das ist schlecht, weil genau diese Funktionen von PHP als veraltet gelten. Den größten Kritikpunkt greifst du mit deiner Frage selber auf: Sicherheit! mysql_*-Funktionen haben keinen nativen Schutz vor Code Injections (neben anderen Nachteilen). Das ist halt mit PDO (und MySQLi) anders.


    Hier eine kleine Erklärung zu meinem Code. Eventuell ist es dir danach einfacher ihn zu verstehen:


    PHP
    1. $pdo = new PDO ( 'mysql:host=localhost;dbname=datenbank;port=3306', 'meinUser', 'meinPasswort' );


    Mit diesem Befehl bauen wir die Verbindung zum MySQL-Server auf. Die Klasse PDO ist, wie bereits geschrieben, in aktuellen PHP-Versionen verfügbar (sollte bei All-Inkl auf jeden Fall so sein!). Wir speichern die Datenbankverbindung in $pdo um jederzeit auf diese zuzugreifen. I.d.R. musst du localhost nicht ändern. Leidlich die Datenbank (dbname=xyz) muss angepasst werden. Und natürlich die Zugangsdaten.

    PHP
    1. $statement = $pdo->prepare('SELECT * FROM user WHERE name = ? && passwort = ? LIMIT 1;');


    Hier bereiten wir den Query vor. Da kannst du jeden anderen Query nehmen. Wichtig dabei ist, dass du Variablen mit dem Platzhaler "?" ersetzt. PDO weiß später, dass es das Fragezeichen in der Reihenfolge der übergebenen Variablen ersetzen soll (siehe execute). Wenn du weißt, dass für ein feld nur ein bestimmter Wert vorkommen kann, kannst du ihn auch direkt in den Query schreiben:

    SQL
    1. SELECT * FROM user WHERE name = ? && passwort = ? && login_erlaubt = 1 LIMIT 1;

    Was aber vom User kommt, MUSS (aus Sicherheitsgründen - darum geht es ja hier) mit dem Platzhalter aufgelöst werden.


    PHP
    1. $statement->execute($_POST['username'], $_POST['password']);


    Hier binden wir die Daten aus dem POST-Request an den Query. Dabei wird $_POST['username'] das erste Fragezeichen ersetzen, $_POST['password'] das zweite Fragezeichen.


    Aus unserem Query wurde nun "intern" folgendes:

    Code
    1. $_POST['username'] => Heinzi
    2. $_POST['password'] => geheim
    3. SELECT * FROM user WHERE name = 'Heinzi' && passwort = 'geheim' LIMIT 1;


    Die Variablen werden dabei automatisch escaped (abgesichert). Danach wird der MySQL-Befehl an den Server geschickt.


    PHP
    1. $result = $statement->fetch(PDO::FETCH_OBJ);

    Nun wollen wir natürlich auch die Daten irgendwie verarbeiten können, die wir abgefragt haben. Mit fetch holen wir diese. Der Parameter PDO::FETCH_OBJ besagt dabei, dass wir gerne ein Objekt der Daten hätte. Somit enthält $result->name den Namen und $result->passwort das Passwort.


    Wenn du einmal etwas Hirnschmalz investiert hast, wirst du erkennen welche Vorteile PDO dir bringt. Irgendwann wirst du nimmer darauf verzichten möchten.

  • Hey Bastey,
    das muß ich zu Hause mal in Ruhe lesen. Ich muß dazu sagen, das ich einfach DWCS5 nutze. Da ist ja bei jeder Abfrage so eine große Funktion dabei, die die Eingabe überprüft. So scheint es mir auf jeden Fall.



    Nun kommt ja genau das drin vor :-) " mysql_ "


    Eigenen Abfragen mache ich ja quasi nicht...