Лучшая практика Python и securest для подключения к MySQL и выполнения запросов

каков самый безопасный способ запуска запросов на mysql, я знаю об опасностях, связанных с MySQL и SQL-инъекцией.

однако я не знаю, как я должен запускать свои запросы, чтобы предотвратить инъекцию переменных, которыми могут манипулировать другие пользователи (webclients). Раньше я писал свою собственную функцию escape, но, по-видимому, это "не сделано".

Что я должен использовать и как я должен использовать его для запроса и делать вставки безопасно в базе данных MySQL через python без риска инъекции в MySQL?

3 ответов


чтобы избежать инъекций, используйте execute С %s вместо каждой переменной, а затем передать значение через список или кортеж в качестве второго параметра execute. Вот это пример из документации:

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

обратите внимание, что это с помощью запятая, а не % (что было бы прямой заменой строки, не экранированной). не делай этого:

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

кроме того, вам не нужны кавычки держатель позиции ('%s'), если параметр является строкой.


в качестве расширения ответа Бруно ваша клиентская библиотека MySQL может поддерживать любой из нескольких различных форматов для указания именованных параметров. От PEP 249 (DB-API), вы можете написать свои запросы, такие как:

'qmark'

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

'numeric'

>>> 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})

вы можете увидеть, что ваша клиентская библиотека поддерживает, посмотрев на paramstyle переменной уровня модуля:

>>> clientlibrary.paramstyle
'pyformat'

любой из вышеперечисленных вариантов должен сделать правильную вещь в отношении обработки ваших, возможно, небезопасных данных. Как отметил Бруно, пожалуйста, никогда не пытайтесь вставлять параметры самостоятельно. Обычно используемые клиентские библиотеки намного лучше обрабатывают данные правильно,чем мы, простые смертные.


Если вы используете mysqldb, вы можете использовать встроенную функцию escape_string. Вроде этого.

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

Я всегда предпочитаю использовать функцию escape соединителя базы данных - он работает по назначению, и ручное кодирование функций escape само по себе является риском для безопасности.