有没有安全的方法可以在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语法在即将测试时遇到问题”。

即使这是供个人使用,我也确实不想直接将用户提供的字符串直接插入任何类型的查询中。它违反了我的宗教信仰。有没有一种安全的方法可以将用户提供的数据库名称插入python(或任何语言)的mySQL查询中,以确保诸如的用户输入test_db; DROP some_other_db;将被正确拒绝或转义?


问题答案:

经过一番挖掘,事实证明phpmyadmin使用反引号来引用数据库,表和列名称。他们只是这样做:

$sql_query = 'CREATE DATABASE ' . PMA_backquote($new_db);

这将在上面的错误情况下给出类似

CREATE DATABASE `test_db; DROP some_other_db`;

当然,输入字符串中的任何反引号都需要转义,根据phpmyadmin的代码,这可以通过用双反勾号替换所有单反勾号来完成。我找不到任何地方可以确认这是正确的。

我也在网上注意到,尽管反引号不是标准的SQL。