2008-08-21 13 views
1

Für meine Abschlussarbeit habe ich ein Programm entwickelt, das mithilfe vorbereiteter Anweisungen automatisch Schwachstellen in der SQL-Injection erkennt und vorschlägt. Speziell die mysqli-Erweiterung für PHP. Meine Frage für die SO-Community lautet: Was wäre Ihr bevorzugter Ansatz, um SQL im PHP-Quellcode zu erkennen?Beste Vorgehensweise zum Parsen für SQL in PHP-Dateien?

Ich verwendete eine enum mit der SQL keywords (SELECT, INSERT, ...) und im Grunde jeder Zeile geparst, Iterieren über die Enumeration, um festzustellen, ob SQL vorhanden war. Außerdem musste ich sicherstellen, dass der Parser nicht irrtümlicherweise HTML entdeckte (zum Beispiel < \ select>).

Für mich funktionierte diese Lösung gut, aber jetzt habe ich ein wenig mehr Zeit in meinen Händen und habe darüber nachgedacht, den Code zu refaktorieren, um eine elegantere (und effizientere) Lösung zu verwenden. Bitte beschränken Sie Ihre Lösungen auf C# als das ist, was ich mein Programm schrieb.

Antwort

1

Ihre Lösung scheint mir gut. Der andere Weg wäre, die PHP-Datei mit einem Lex/Yacc-Parser unter Verwendung der Grammatik für PHP zu parsen. Es gibt ein gutes C# -Tool, Coco/R http://www.ssw.uni-linz.ac.at/coco/.

Allerdings glaube ich, wenn Sie die Sprache analysieren, werden Sie am Ende verbrauchen zu viel Zeit (in der Entwicklung und in der EDV) für keine zusätzlichen Ergebnisse.

Ich würde mit Ihrem opportunistischen Ansatz bleiben, aber testen Sie es gegen verschiedene PHP-Code und zwicken Sie es, um alle möglichen Fälle abzudecken.

1

Vielleicht gibt es einige Kilometer in Parsing Textzeilen gegen die BNF für, sagen wir SQL92, und Scoring jeder Zeile auf wie eng die Fragmente der Grammatik entsprechen.

Klingt wie etwas schweres Heben. Ihr einfacher Ansatz wird bereits einen so großen Prozentsatz von Fällen aus der Praxis erfassen.

1

Ich weiß nicht, die Besonderheiten der Variablen in C#, so dass Sie mich haben, zu vergeben oder nach unten stimmen PHP aber 70% der Zeit, meine SQL-Abfrage geht in eine Variable wie so

$sql = "SELECT * FROM table;"; 

für die Verwendung von Darüber hinaus kann ich an nichts denken, was Sie tun können, um das zu verbessern, was Sie bereits haben.

Berücksichtigen Sie Anweisungen, die über mehrere Zeilen hinweg erstellt werden und Variablen innerhalb des Strings verwenden? (Beispiel unten)

$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname"; 
0

Ich weiß nicht, die Besonderheiten von Variablen in C#, so dass Sie müssen mir verzeihen oder nach unten stimmen mit PHP, aber 70% der Zeit, meine SQL-Abfrage geht in eine Variable wie so ..

Ja, war mein ursprünglicher Ansatz aussieht nur für den $ sql vars, da das, was meist Menschen verwenden, aber nach dem Test gegen ein paar PHP-Anwendungen ich warf schnell, dass die Lösung aus, da einig Entwickler verwenden einige funky Variablennamen ...

Berücksichtigen Sie Aussagen, die über mehrere Zeilen hinweg erstellt werden und Variablen innerhalb des Strings verwenden? (Beispiel unten)

Ja.Ich habe auch versucht, Statements zu verarbeiten, die bedingt erzeugt wurden, aber das hat nicht immer so gut funktioniert. ;)

0

Eine einfache regex alle CRUD SQL-Anweisungen mit Funktionen (unter der Annahme $ Skript enthält das gesamte PHP-Skript)

preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?\)\s*?;/is', 
       $script, $matches); 

Es sollte DELETE-Anweisungen entsprechen alle möglichen SELECT, INSERT, UPDATE verwendet zu erfassen, wenn Sie werden in Klammern und Anführungszeichen gesetzt. Es ist Fall insensetive und sollte Anweisungen übereinstimmen, die sich über mehrere Zeilen erstrecken.

bearbeiten # 1: Regex für übereinstimmende CRUD-Anweisung wie String-Zuweisungen;

preg_match_all('/\$\w+\s*?=\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?;/is', 
       $script, $matches); 

bearbeiten # 2:

// $variable detecting version of #1 regex 
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?(?:\$\w+){1}.*?"\s*?\)\s*?;/is', 
        $script, $matches); 
1

Ich würde sagen, es wäre am besten für die Funktion aussehen fordert stattdessen SQL selbst suchen. Ändern Sie möglicherweise den PHP-Parser, um nach Funktionsaufrufen zu suchen, die zum Ausführen einer SQL-Abfrage führen, die keine vorbereitete Abfrage ist.