dedlfix: Sicherheit bei Formular erhöhen

Beitrag lesen

Hi!

Im php_manual meine ich gelesen zu haben, das PDO die sql-Anfragen automatisch vor sql injection schützt.

Das kann es natürlich nur dann machen, wenn es weiß, was Wert und was SQL-Statement ist.

Wenn du die Methode PDO::query() verwendest, dann übergibst du ein fix und fertiges SQL-Statement, in das von PDO nicht weiter eingegriffen wird. Du musst dabei - so wie es auch im Manual steht - für die Behandlung von eingefügten Werten selbst sorgen ("Data inside the query should be properly escaped.")

Da gibt's auch ein beispiel , bei dem direkt eine $_GET Varibale in das Statement eingebaut wird, mit dem Hinweis, dass PDO automatisch vor SQL_injection schützt.

Du musst Prepared Statemens verwenden und dort die Parameter wie vorgesehen übergeben, sprich: binden. Prepared Statements schützen nicht per se vor SQL-Injection - viel besser: bei ihnen tritt bei richtiger Verwendung das Problem erst gar nicht auf. Üblicherweise geht das Statement zuerst zum DBMS (Prepare), erst dann folgen die Parameter getrennt davon (Execute mit vorherigem Bind). Da sie nicht in das Statement eingefügt werden, müssen sie auch nicht mit Begenzungszeichen versehen werden, und es ergibt sich dann keine Verwechslungsgefahr zwischen Anführungszeichen als Begrenzungszeichen und als Datenbestandteil. Die mit Bind gebundenen Werte sind komplett Daten.

Es hindert dich aber niemand daran, das SQL-Statement mit selbst eingefügten Werten statt Platzhaltern (oder beides gemischt) zu versehen und es dann über den Prepared-Statement-Mechanismus abzusenden.

SELECT feldliste FROM tabelle WHERE foo='bar' AND baz=:qux

Nur qux ist ein Platzhalter, der - siehe oben - nicht anfällig für SQL-Injection ist. bar ist keiner und muss wie üblich selbst behandelt werden.

Das gleiche Prinzip gilt auch für die mysqli-Extension: herkömmliche Query versus Prepared Statement. Die immer noch häufig verwendete mysql-Extension kennt hingegen keine Prepared Statements.

Achte übrigens mal auf Example 6. Das erste ist nicht richtig angewendet, interessiert aber grad nicht. Beim zweiten sind zwar die Jokerzeichen für das LIKE an der richtigen Stelle, es kann sich aber ein ählicher Problemfall wie bei SQL-Injection ergeben. In $_GET[name] können sich vom Anwender eingegebene % und _ befinden, die ebenso vom Server als Jokerzeichen ausgewertet werden. Man kann damit zwar nicht ins SQL-Statement ausbrechen, doch es können sich Suchtreffer ergeben, die vom Programmierer nicht vorgesehen sind. Wenn dies nicht beabsichtigt ist, müssen die % und _ durch die im DBMS üblichen Ersatzschreibweisen ausgetauscht werden.

Lo!