2013-12-09 14 views
9

Wenn eine lahme Eingabe in eine SQL-Abfrage direkt eingefügt wird, wird die Anwendung anfällig für SQL-Injection, wie im folgende Beispiel:Wie kann ich die SQL-Injektion in PYTHON-DJANGO verhindern?

dinossauro = request.GET['username'] 

sql = "SELECT * FROM user_contacts WHERE username = '%s';" % username 

die Tabellen oder etwas fallen zu lassen - die Abfrage machen:

INSERT INTO table (column) VALUES('`**`value'); DROP TABLE table;--`**`') 

Was kann man tun, um dies zu verhindern?

+3

Darf ich Sie fragen, warum Sie SQL-Abfragen manuell schreiben, anstatt django Models zu verwenden? – smeso

+2

Das Django-ORM, außerhalb von 'roh' und' extra', wird Ihren Anfragen für Sie entgehen. Siehe [Sicherheitsdokumente] (https://docs.djangoproject.com/de/dev/topics/security/#sql-injection-protection). – jonafato

Antwort

3

Vom Django Docs:

SQL-Injection-Schutz

SQL-Injection ist eine Art von Angriff, bei dem ein böswillige Benutzer in der Lage ist, beliebige SQL-Code in einer Datenbank auszuführen. Dies kann dazu führen, dass Datensätze gelöscht werden oder Daten verloren gehen.

Mithilfe von Djangos Querysets wird der resultierende SQL-Code ordnungsgemäß , der vom zugrunde liegenden Datenbanktreiber gemattert wird, erstellt. Allerdings gibt Django auch Entwickler Macht, rohe Abfragen zu schreiben oder benutzerdefinierte SQL auszuführen. Diese Funktionen sollten sparsam verwendet werden und Sie sollten immer vorsichtig sein , um alle Parameter ordnungsgemäß zu entkommen, die der Benutzer steuern kann. Unter sollten Sie bei der Verwendung von extra() Vorsicht walten lassen.

7

Zuerst sollten Sie wahrscheinlich nur Django ORM verwenden, es wird jede Möglichkeit der SQL-Injektion verhindern. Wenn Sie aus irgendeinem Grund nicht können oder wollen, sollten Sie Python Database API verwenden. Hier ist die Art und Weisen Sie in der Regel tun, dass in Django:

from django.db import connection 

cursor = connection.cursor() 
cursor.execute('insert into table (column) values (%s)', (dinosaur,)) 
cursor.close() 

Sie auch handy Python-Paket verwenden, um den Text zu reduzieren:

from handy.db import do_sql 

do_sql('insert into table (column) values (%s)', (dinosaur,)) 
2

Wenn Sie mit .extra() die Syntax ist:

YourModel.objects.extra(where=['title LIKE %s'], params=['%123%321%']) 

Wiederholen Sie hier von this answer, wie dies schwer zu finden ist, und die docs, die "you should always be careful to properly escape any parameters" sagen, gehen Sie nicht auf s ay wie um sie richtig zu entkommen!