8 Stimmen

Wie kann dieser SQL-Abfragecode durch Benutzereingaben gebrochen/ausgenutzt werden?

Mögliches Duplikat:
Kann ich mich gegen SQL Injection schützen, indem ich einfache Anführungszeichen ausklammere und Benutzereingaben mit einfachen Anführungszeichen umschließe?

Wir haben eine Legacy-Anwendung, die keine Abfragen mit Positionsparametern durchführt, und überall gibt es SQL. Es wurde beschlossen (bevor ich hier anfing), dass, da Benutzereingaben Apostrophe enthalten können, jede Zeichenkette Eingabe sollte manuell für diese Apostrophe escaped werden.

Hier ist der wesentliche Originalcode (nicht von mir geschrieben), der Einfachheit halber in C# übersetzt:

private string _Escape(string input)
{
    return input.Replace("'", "''");
}

private bool _IsValidLogin(string userName, string password)
{
    string sql =
        string.Format
        (
            @"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = '{1}'",
            _Escape(userName),
            _Escape(password)
        );
    // ...
}

Es sieht wirklich so aus, als ob es auf irgendeine Art und Weise gebrochen werden kann, aber ich weiß nicht, wie es durch Benutzereingaben ausgenutzt werden könnte. Angenommen, die Benutzereingabe ist ungefiltert, bis sie auf _IsValidLogin und vergessen, dass Kennwörter offenbar im Klartext gespeichert werden.

Die Lösung liegt auf der Hand - Verwendung von Positionsparametern - aber ich brauche Munition, um dem Management zu zeigen, warum/wie dieser Code unsicher ist, damit Zeit/$ für die Behebung bereitgestellt werden kann.

Anmerkung: Ich bin unter der Annahme, dass dies kann gebrochen werden, aber das muss nicht der Fall sein. Ich bin kein SQL-Superstar.

Anmerkung 2: Ich habe diese Frage als datenbankunabhängig formuliert, aber wenn Sie diesen Code für eine bestimmte Engine ausnutzen können, begrüße ich Ihren Beitrag.

3voto

erenon Punkte 18471

Es könnte durch Backslashes ausgedrückt werden.

password = foo\' OR 1=1 --

wird:

password = foo\'' OR 1=1 --

die Abfrage:

"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = 'foo\'' OR 1=1 --'"

-- Ist in diesem Beispiel das Kommentarzeichen.

Die Lösung geht davon aus, dass das Programm nur Apostrophe filtert (dupliziert).

0voto

James Curran Punkte 98228

Nun, ich sehe keine Möglichkeit, dass sie angreifbar ist. Also, lassen Sie uns einen anderen Grund anführen, warum es geändert werden sollte - es ist ziemlich ineffizient. In MSSQL (und ich denke, in den meisten anderen High-End-SQL-Servern) werden Abfragen geparst und ein Ausführungsplan erstellt, und dann werden die Abfrage und der Plan gespeichert. Wenn eine exact Kopie der Abfrage erneut angefordert wird, wird der gespeicherte Ausführungsplan verwendet. Parameter haben darauf keinen Einfluss. Wenn Sie also Parameter verwenden, werden die Pläne wiederverwendet; wenn Sie den Text einbetten, geschieht dies nie.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X