2012-10-11 15 views
6

Chcę przekazać parametry zapytania do cursor.execute() metody MySQLdb jako nazwanego słownika, tak, że są one uciekł z SQL injection.Python MySQLdb: Parametry kwerendy nazwanego słowniku

Czy możesz wyjaśnić, dlaczego to daje KeyError:

>>>c.execute('select id from users where username=%(user)s', {'user':'bob',}) 
KeyError: 'user' 

MySQLdb ręcznego http://mysql-python.sourceforge.net/MySQLdb.html mówi:

* paramstyle stała

String określający rodzaj znacznika parametru formatowania oczekiwane przez interfejs. Ustaw na "formatuj" = kody formatu printf ANSI C, np. "... WHERE name =% s". Jeśli obiekt odwzorowania jest używany dla conn.execute(), interfejs faktycznie używa "pyformat" = rozszerzonych kodów formatu Python, np. "... WHERE name =% (name) s '. Jednak API nie obecnie umożliwiają określenie więcej niż jednego stylu w paramstyle *

Odpowiedz

6

Linia w dokumentacji następujące czego wklejony może odpowiedzieć na to pytanie.

Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.

+0

Wstawiam wartość *** kolumny ***. Linia w dokumentacji oznacza, że ​​następujący kod jest nielegalne: 'c.execute ('select id% s gdzie username =% s' ('użytkowników', 'bob'))' – mercador

+1

@mercador prawo, 'from% s' piece jest przyczyną niepowodzenia, ponieważ próbujesz sparametryzować nazwę tabeli. Zaletą korzystania z 'execute' w ten sposób jest to, że pomaga zapobiegać iniekcji SQL, ale jeśli podejmiesz odpowiednie środki ostrożności (które nie jestem ekspertem, ale wymagałyby odpowiedniego odkażenia/uniknięcia parametrów), możesz użyj wbudowanego formatowania napisów w Pythonie do zbudowania zapytania, a następnie przekaż je do 'execute'. Ponownie głównym problemem jest iniekcja SQL. Mam nadzieję że to pomoże! – RocketDonkey

5

MySQLdb pozwala dicts jako parametry zapytania . This response pokazuje wszystkie różne sposoby zrobienia tego. Musisz tylko podać secuence jako parametr (krotka, dict ...) jako drugi parametr "wykonaj". NIE formatuj zapytania jako tylko jednego parametru metody "wykonaj" lub będziesz prawdopodobnie narażony na ataki typu SQL injection. Zobacz:

"SELECT * FROM users WHERE username = '%s'" % (user) 

pomyśleć, co by się stało, jeśli:

user = "peter;DROP TABLE users" :_(

Innym sposobem jest zabezpieczona, gdyż pozwala biblioteki MySQLdb do obsługi niezbędnej kontroli.

Nie wiem co jest nie tak, bo zapytanie działa dobrze dla mnie:

# Connect to db 
# Open a cursor 
stmt = "SELECT * FROM users WHERE username = %(user)s" 
cursor.execute(stmt, {"user": "bob"}) 
user = cursor.fetchone() 
print user 

{'username': 'bob', 'alias': 'bobby', 'avatar': 'default', 'fullname': 'bob'} 

możesz dać nam więcej informacji?

Powiązane problemy