No Comments

SQL Injection Protection in PHP mit PDO

Datenbankabstraktionsschichten wie die Portable Data Objects (PDO) von PHP sind kein neues Konzept, aber viele Entwickler scheinen den Sicherheitsvorteil, den sie durch ihre Verwendung kostenlos erhalten, nicht zu erkennen – inhärenter Schutz gegen SQL-Injection.

SQL Injection ist der Pufferüberlauf der Webanwendungswelt – es gibt ihn schon immer, und jeder Webanwendungsentwickler sollte wissen, wie man sicheren Code schreibt, der nicht dafür anfällig ist. Für Unbekannte ist SQL Injection eine Technik, bei der ein böswilliger Angreifer eine unzureichende Datenüberprüfung ausnutzen kann, um beliebigen SQL-Code in die Abfragen Ihrer Anwendung einzufügen und ihn so ausführen zu lassen, als wäre er eine legitime Abfrage. Ich werde in diesem Artikel nicht zu tief auf die SQL-Injection eingehen, aber hier ist ein einfaches Beispiel:

Auf der Startseite Ihrer Anwendung befindet sich ein Anmeldeformular, das an ein PHP-Skript gesendet wird, um die Anmeldeinformationen des Benutzers zu überprüfen und den Zugriff auf die Anwendung zuzulassen oder zu verweigern. Das Anmeldeformular sendet zwei Variablen per POST wie folgt:

Benutzername = fred & Passwort = Fr3dRul3z

Die POST-Daten werden dann verwendet, um eine SQL-Abfrage zum Überprüfen der Anmeldeinformationen wie folgt zu erstellen:

$ sql = “SELECT * FROM users WHERE username = ‘”. $ _ REQUEST[‘username’]. “‘AND password ='”. $ _ REQUEST[‘password’]. “‘”;

Dies würde zu der SQL-Abfrage führen:

SELECT * FROM users WHERE Benutzername = ‘fred’ UND Passwort = ‘Fr3dRul3z’

Angenommen, in der Datenbank ist eine Zeile mit diesen Anmeldeinformationen vorhanden, kann sich der Benutzer anmelden. Ein Angreifer kann dieses Authentifizierungsschema leicht umgehen, indem er aus dem Feld Benutzername in die SQL-Abfrage entweicht, indem er nichts in das Kennwortfeld und dies in das Feld eingibt Feld für den Benutzernamen:

‘ODER 1 == 1 –

Die resultierende SQL-Abfragezeichenfolge würde folgendermaßen aussehen:

SELECT * FROM users WHERE Benutzername = ‘fred’ ODER 1 == 1 – ‘AND password =’ ​​’

Wie Sie sicher sehen können, werden alle Benutzer aus der Datenbank ausgewählt, da die Bedingung 1 == 1 immer erfüllt ist. Der Rest der Abfrage wird mit dem Kommentaroperator ‘-‘ verworfen. Um diese Art von Angriff zu vermeiden, müssen Sie die an das Formular gesendeten Daten bereinigen, indem Sie alles umgehen, was verwendet werden könnte, um die Grenzen der Anführungszeichen um die Felder zu umgehen (z. B. mysql_real_escape_string (), wenn Sie MySQL verwenden). In einem weit entfernten Land erfand jedoch jemand Datenbankabstraktionsschichten …

Das Hauptziel von Datenbankabstraktionsschichten wie PDO ist die saubere Abstraktion Ihres Codes von der Datenbankplattform weg. Theoretisch könnten Sie also Datenbankplattformen von MySQL zu PostgreSQL oder Oracle mit minimalen Änderungen am Code wechseln. In der Praxis hängt dies stark davon ab, inwieweit Ihr Code von plattformspezifischen Funktionen wie Triggern und gespeicherten Prozeduren abhängt. Wenn Sie sich jedoch überhaupt nicht auf diese verlassen und nur einfache INSERT / UPDATE / DELETE-Vorgänge ausführen, ist dies eine kostenlose Fahrt . Klingt mäßig nützlich, aber nichts Aufregendes, oder? Richtig. Eine weitere nette Funktion, die vor langer Zeit erfunden wurde, sind vorbereitete Anweisungen, und die meisten Datenbankabstraktionsschichten (einschließlich PDO) implementieren dies, um dieselbe Abfrage mehrmals mit unterschiedlichen Datensätzen durchzuführen (z. B. Einfügen einer ganzen Reihe neuer Zeilen). Wenn Sie jetzt Anweisungen mit PDO erstellen, anstatt die SQL-Zeichenfolge manuell zu erstellen, wie zuvor gezeigt, erstellen wir die Anweisung mit Platzhaltern wie folgt:

$ sql = “IN Früchte EINFÜGEN (Name, Preis) WERTE (?,?)”;

und führen Sie dann die Abfrage mit einem Datensatz aus, der wie folgt an die Abstraktionsschicht übergeben wird:

$ sth = $ dbh-> prepare ($ sql);

$ sth-> execute (Array ($ruit, $ price));

Wenn die Daten auf diese Weise an PDO übergeben werden, werden sie entweder direkt an den Datenbanktreiber weitergeleitet oder die Abfrage wird intern auf sichere Weise mit potenziell böswilligen Daten erstellt, die verschlüsselt oder maskiert sind. Wie Sie sehen können, ist dies ein einfacher Weg, um das Problem der SQL-Injection zu umgehen.

Vorbereitete Aussagen mit PDO sind jedoch nicht nur Welpen und Regenbogen. Die Verwendung vorbereiteter Anweisungen kann eine Reihe interessanter Einschränkungen mit sich bringen, die Entwickler beachten sollten. Beispielsweise können in der MySQL-Client-API vorbereitete Anweisungen bestimmte Abfragetypen nicht ausführen[1] und sie verwenden den Abfragecache nicht[1][2] Dies kann sich auf die Leistung Ihrer Anwendung auswirken.

Die inhärente Sicherheit bei der Verwendung vorbereiteter Anweisungen klingt großartig, aber Entwickler sollten sich nicht von PDO und anderen Abstraktionsschichten / vorbereiteten Anweisungsimplementierungen in ein falsches Sicherheitsgefühl wiegen lassen. Nicht vertrauenswürdige Daten sollten immer validiert und bereinigt werden. PDO ist nur eine weitere Verteidigungslinie. Es deckt nicht das Gebiet einer Vielzahl anderer Sicherheitslücken bei der Eingabevalidierung ab, wie z. B. Cross Site Scripting, aber es schützt Anwendungen gut vor SQL-Injection. Die beste Strategie besteht darin, nur bekannte gute Daten zuzulassen, indem Zeichen auf die Whitelist gesetzt und Eingabedaten mit Mustern regulärer Ausdrücke abgeglichen werden. Anschließend werden vorbereitete Anweisungen verwendet, um alles zu erfassen, was bei der Eingabevalidierung in Bezug auf die SQL-Injektion fehlt, und dies alles in Verbindung mit einer Webanwendungs-Firewall wie ModSecurity.

PDO ist seit Version 5.1.0, die im November 2005 veröffentlicht wurde, in PHP integriert. Wenn Sie keinen guten Grund haben, es nicht in Ihren PHP-Apps zu verwenden, sollten Sie es sein – es ist ein tragbarer Ersatz für das alte mysql_ * Funktionen und andere plattformspezifische Funktionen mit dem zusätzlichen Vorteil des Schutzes vor SQL-Injection.

 

Das könnte dir auch gefallen

More Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Please enter a valid email address.