2012-11-28 9 views
9

Jak sugeruje tytuł, chciałbym wiedzieć, czy ten kod jest podatny na SQL Injection? A jeśli tak, czy istnieje lepszy, bezpieczniejszy sposób na osiągnięcie tego samego?Czy ten kod Pythona jest podatny na iniekcję SQL? (SQLite3)

def add(table,*args): 
    statement="INSERT INTO %s VALUES %s" % (table,args) 
    cursor.execute(statement) 
+1

Proponuję, abyś przeczytał na czym polega iniekcja SQL. Powinno to być bardzo jasne. –

Odpowiedz

21

Tak, jest. Użyj czegoś takiego, aby temu zapobiec:

cursor.execute("INSERT INTO table VALUES ?", args) 

Pamiętaj, że nie możesz wejść do tabeli w ten sposób. W idealnej sytuacji tabela powinna być zakodowana na sztywno, w żadnym wypadku nie powinna pochodzić z jakiegokolwiek rodzaju wejścia użytkownika. Możesz użyć łańcucha podobnego do tego, co zrobiłeś dla tabeli, ale lepiej uczynić 100% pewności, że użytkownik nie może go w jakiś sposób zmienić ... Więcej informacji można znaleźć w artykule Can I use parameters for the table name in sqlite3?.

Zasadniczo chcesz umieścić parametry w poleceniu kursora, ponieważ spowoduje to, że baza danych będzie bezpieczna. Przy pierwszym poleceniu stosunkowo łatwo byłoby zrobić specjalne table lub args, które wprowadzają coś do twojego kodu SQL, który nie byłby bezpieczny. Zobacz python pages i odniesienie http://xkcd.com/327/. W szczególności, strony python zacytować:

Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack (see http://xkcd.com/327/ for humorous example of what can go wrong).

Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.)

zasadzie ktoś mógłby dawać argumenty, które wykonywane inne polecenie, coś takiego:

args="name; DELETE table" 

Korzystanie cursor.execute rzeczy będzie wartość podana, tak że Argument może być na liście, a kiedy zrobisz zapytanie, to właśnie to otrzymasz. XKCD wyjaśnia to również z humorem.

enter image description here

+0

Dzięki. Czy możesz nieco wyjaśnić, dlaczego jest on podatny na ataki? – Sheldon

+1

To może być cicho oczywiste, ale po prostu dla bezpieczeństwa: Zrób to dla WSZYSTKICH instrukcji, a nie tylko INSERT. Instrukcja SELECT jest tak samo wrażliwa. –

+0

@PearsonArtPhoto Otrzymuję "TypeError: funkcja przyjmuje co najwyżej 2 argumenty (3 podane)" – Sheldon