Есть ли безопасный способ параметризации имен баз данных в запросах MySQL?
Я пишу небольшой скрипт на python, чтобы помочь мне автоматизировать создание баз данных mysql и связанных учетных записей для моих личных проектов. Часть этого скрипта представляет собой функцию, которая принимает имя базы данных в виде строки, а затем переходит к созданию базы данных.
def createDB(dbConn, dbName):
import MySQLdb
c = dbConn.cursor()
query = """CREATE DATABASE %s;""";
c.execute(query, (dbName,))
Это не работает, потому что MySQL CREATE DATABASE запрашивает имя базы данных без кавычек, как в
CREATE DATAbASE test_db
но мой код, который пытается безопасно вставить предоставленное пользователем имя базы данных в запрос, создает:
CREATE DATABASE 'test_db'
И вы получите "у вас проблема в синтаксисе MySQL рядом с тестом".
Несмотря на то, что это для личного использования, я действительно не хочу просто вставлять предоставленную пользователем строку в запрос любого вида. Это против моей религии. Существует ли безопасный способ вставить предоставленное пользователем имя базы данных в запрос MySQL на Python (или на любом языке), который обеспечит ввод данных пользователем, например test_db; DROP some_other_db;
будет отклонен или сбежал правильно?
2 ответа
После некоторого копания выясняется, что phpmyadmin использует обратные кавычки для цитирования имен баз данных, таблиц и столбцов. Они просто делают:
$sql_query = 'CREATE DATABASE ' . PMA_backquote($new_db);
Что бы дать в случае ошибки выше что-то вроде
CREATE DATABASE `test_db; DROP some_other_db`;
Конечно, любые обратные пометки во входной строке необходимо экранировать, что в соответствии с кодом phpmyadmin выполняется путем замены всех одинарных обратных тиков двойными обратными тиками. Я не могу найти, где это подтверждает, что это правильно.
Я также заметил онлайн, хотя обратные помехи не являются стандартным SQL.
Имя базы данных (ни имена столбцов, ни таблиц) не являются значениями данных и, следовательно, не являются подходящим использованием заполнителей. Желание сделать это, как правило, плохой знак; только администратор базы данных должен иметь возможность выдавать create database
, поскольку это требует значительных привилегий. Большинству приложений требуется, чтобы администратор БД выдал базу данных create, а затем использует созданную базу данных в качестве параметра, который будет использоваться в аргументах dbapi.Connection.
Если вы уверены, что вам это нужно, вы доверяете источнику ввода и проверили ввод на наличие недопустимых символов, вы просто сделали бы подстановку в python, что-то вроде:
def createDB(dbConn, dbName):
c = dbConn.cursor()
query = """CREATE DATABASE %s;""" % dbName
c.execute(query)