有没有安全的方法来参数化MySQL查询中的数据库名称?

时间:2011-07-11 21:13:30

标签: python mysql mysql-python sql-parametrized-query

我正在编写一个小的python脚本来帮助我自动创建我的个人项目的mysql数据库和相关帐户。此脚本的一部分是将数据库名称作为字符串,然后创建数据库的函数。

def createDB(dbConn, dbName):
    import MySQLdb
    c = dbConn.cursor()
    query = """CREATE DATABASE %s;""";
    c.execute(query, (dbName,))

这不起作用,因为MySQL's CREATE DATABASE要求数据库的不带引号的名称,如

  CREATE DATAbASE test_db

但我的代码试图安全地将用户提供的数据库名称插入查询中,创建了:

  CREATE DATABASE 'test_db'

你得到“你的MySQL语法接近测试时遇到问题”。

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

2 个答案:

答案 0 :(得分:5)

数据库名称(也不是列名或表名)不是数据值,因此不适合使用占位符。想要做到这一点通常是一个不好的迹象;只有DBA应该能够发出create database,因为这样做需要一些相当大的特权。大多数应用程序都要求DBA发出create database,然后将创建的数据库作为参数用于dbapi.Connection的参数。

如果你确定需要这个,你相信输入的来源,你已经检查了无效字符的输入,你只需要在python中进行替换,例如:

def createDB(dbConn, dbName):
    c = dbConn.cursor()
    query = """CREATE DATABASE %s;""" % dbName
    c.execute(query)

答案 1 :(得分:2)

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

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

在错误情况下会出现类似

的内容
CREATE DATABASE `test_db; DROP some_other_db`;

当然输入字符串中的任何反引号都需要进行转义,根据phpmyadmin的代码,通过用双后退标记替换所有单个反向标记来完成。我找不到任何证实这是正确的地方。

我也注意到在线,虽然反引号不是标准的SQL。