Najlepsza praktyka Pythona i najbezpieczniejsza do łączenia się z MySQL i wykonywania zapytań

Jaki jest najbezpieczniejszy sposób uruchamiania zapytań w mysql, zdaję sobie sprawę z zagrożeń związanych z MySQL i SQL injection.

Jednak Nie wiem, jak powinienem uruchamiać moje zapytania, aby zapobiec wtrysku zmiennych, do których inni użytkownicy (webclients) mogą manipulować. Kiedyś pisałem własną funkcję ucieczki, ale najwyraźniej jest to "nie-zrobione".

Czego powinienem używać i jak powinienem używać go do bezpiecznych zapytań i wstawiania w bazie danych MySQL przez python bez ryzykowania mysql zastrzyk?

Author: Lucas Kauffman, 2011-10-28

3 answers

Aby uniknąć zastrzyków, użyj execute z %s zamiast każdej zmiennej, a następnie przekaż wartość za pomocą listy lub krotki jako drugi parametr execute. Oto przykład z dokumentacji :

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

Zauważ, że używa się przecinka, Nie % (co byłoby bezpośrednim podstawianiem łańcuchów, a nie unikaniem). nie rób tego :

c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""" % (max_price,))

Dodatkowo, nie potrzebujesz cudzysłowów wokół posiadacza pozycji ('%s'), Jeśli parametr jest ciągiem znaków.

 63
Author: Bruno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-14 02:56:59

Jako rozszerzenie odpowiedzi Bruno, Twoja biblioteka klienta MySQL może obsługiwać dowolny z kilku różnych formatów do określania nazwanych parametrów. Z PEP 249 (DB-API) możesz pisać swoje zapytania w stylu:

"qmark"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))

"numeryczny"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))

"named"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})

"format"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %s", (lumberjack,))

"pyformat"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %(jack)s", {'jack': lumberjack})

Możesz zobaczyć, która biblioteka obsługuje twój Klient, patrząc na zmienną paramstyle na poziomie modułu:

>>> clientlibrary.paramstyle
'pyformat'

Każdy z powyższe opcje powinny działać prawidłowo w odniesieniu do obsługi potencjalnie niebezpiecznych danych. Jak zauważył Bruno, proszę nigdy nie próbować wstawiać parametrów samodzielnie. Powszechnie używane biblioteki klienckie są znacznie lepsze w poprawnym przetwarzaniu danych niż my zwykli śmiertelnicy kiedykolwiek będziemy.

 61
Author: Kirk Strauser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-01 19:23:47

Jeśli używasz mysqldb, możesz użyć wbudowanej funkcji escape_string. W ten sposób.

sql = "SELECT spam FROM eggs WHERE lumberjack = '" + MySQLdb.escape_string(str(lumberjack)) + "';"
cursor.execute(sql)

Zawsze wolę korzystać z funkcji escape łącznika bazy danych - działa zgodnie z przeznaczeniem, a ręczne kodowanie funkcji escape jest Zagrożeniem bezpieczeństwa.

 0
Author: Wayne Workman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 19:10:29