使用pymysql
(一个MySQLdb
替代方案),我想知道对数据库或字段名这样的事情进行字符串替换的更好方法是什么。例如:我们想要创建一个数据库,它的名称来自变量(dbname = "test"
)。
c.execute("CREATE DATABASE `test`;")
由于添加了引号,这不起作用。
c.execute("CREATE DATABASE %s;", (dbname,))
这很容易被sql注入。
c.execute("CREATE DATABASE `{}`;".format(dbname))
有更好的想法吗?
答案 0 :(得分:2)
没有办法参数化表格或数据库名称等标识符,因此唯一可行的方法是执行一些名称是安全的检查,然后使用字符串连接。
根据MySQL documentation,引用的标识符可以包含U+0001
到U+FFFF
中的任何Unicode字符。 NUL
以后的U+10000
字符和补充字符是不允许的,因此您需要以任何给定的名称检查它们,如果找到任何名称则引发异常。如果名称本身包含反引号,则必须通过加倍来逃避它。 (或者,如果标识符包含任何反引号,您可以选择引发异常。)
此外,标识符不能为空,尽管我很难看到MySQL文档指出的位置。
因此,清理标识符的合适功能可能类似于以下内容(我会留给您填写详细信息):
def sanitise_identifier(name):
# raise exception if name is empty or not a string
# raise exception if name contains NUL chars
# raise exception if name contains Unicode supplementary characters (U+10000 onwards)
return name.replace("`", "``")
然后你会按如下方式使用它:
c.execute("CREATE DATABASE `{}`;".format(sanitise_identifier(dbname)))