Python: функция Mysql Escape генерирует поврежденный запрос - PullRequest
0 голосов
/ 26 сентября 2019

Выходная функция Python mysql по умолчанию, искажает запрос.Исходная строка запроса следующая.Он работает нормально и добавляет записи в базу данных по своему усмотрению

INSERT IGNORE INTO state (`name`, `search_query`, `business_status`, `business_type`, `name_type`, `link`) VALUES ("test_name1", "test", "test_status", "test_b_typ", "test_n_typ", "test_link"), ("test_name2", "test", "test_status", "test_b_typ", "test_n_typ", "test_link")

Но после выхода из него для обеспечения безопасности sql Injection с помощью функции fuction safe_sql = self.conn.escape_string (original_sql) safe_sql генерируется следующее

b'INSERT IGNORE INTO state (`name`, `search_query`, `business_status`, `business_type`, `name_type`, `link`) VALUES (\\"test_name1\\", \\"test\\", \\"test_status\\", \\"test_b_typ\\", \\"test_n_typ\\", \\"test_link\\"), (\\"test_name2\\", \\"test\\", \\"test_status\\", \\"test_b_typ\\", \\"test_n_typ\\", \\"test_link\\")'

Теперь, если я пытаюсь выполнить safe_sql, я получаю синтаксическую ошибку ниже

MySQLdb._exceptions.ProgrammingError: (1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near \'\\"test_name1\\", \\"test\\", \\"test_status\\", \\"test_b_typ\\", \\"test_n_typ\\", \\"tes\' at line 1')

Что заставляет меня задаться вопросом, что если используемая функция escape нарушена / не совместима, или я не используюэто правильный путь?Кроме того, я ввожу сотни записей одновременно, и из-за быстрой обработки (что я просто предполагаю) одного запроса по сравнению с подготовленными операторами, выполняемыми сотни раз, я создаю большой запрос.

1 Ответ

1 голос
/ 26 сентября 2019

Вы не можете избежать всего запроса! Вы не можете сконструировать запрос путем случайного объединения строк, а затем взмахнуть над ним волшебной палочкой и сделать ее "безопасной для инъекций".Вам нужно экранировать каждое отдельное значение до того, как вы введете его в запрос.Например:

"INSERT ... VALUES ('%s', ...)" % self.conn.escape_string(foo)

Но на самом деле ваш MySQL API, вероятно, предлагает подготовленных операторов , которые намного проще в использовании и менее подвержены ошибкам.Что-то вроде:

self.conn.execute('INSERT ... VALUES (%s, %s, %s, ...)',
                  (foo, bar, baz))
...