Python “防止sql的最佳方法”;注射;使用列作为变量时

Python “防止sql的最佳方法”;注射;使用列作为变量时,python,sql-server,sql-injection,pymssql,Python,Sql Server,Sql Injection,Pymssql,我正在使用pymssql更新、删除和向MS SQL server添加列。列是由外部源设置的变量,例如读取数据库、从另一个数据库读取。现在我正试图阻止“坏”sql通过,因为我不知道其他数据库到底给了我什么 'ALTER TABLE tablenameA ADD [' + columnname + '] varchar(25) NULL' 'ALTER TABLE tablenameA DROP COLUMN ['+columnname+']' ('UPDATE tablenameA SET ['

我正在使用pymssql更新、删除和向MS SQL server添加列。列是由外部源设置的变量,例如读取数据库、从另一个数据库读取。现在我正试图阻止“坏”sql通过,因为我不知道其他数据库到底给了我什么

'ALTER TABLE tablenameA ADD  [' + columnname + '] varchar(25) NULL'
'ALTER TABLE tablenameA DROP COLUMN ['+columnname+']'
('UPDATE tablenameA SET [' + columnname + ']=%s WHERE id = 2', value)
现在我不能使用白名单,因为我不知道要添加哪些列名,我唯一能想到的其他选择是使用黑名单,但我想知道是否存在第三种选择


(列名来自字符串类型的表中的列)

Transact-SQL具有将SQL字符串转换为安全对象名的功能:。在绑定参数周围使用它,让数据库驱动程序提供正确引用的SQL对象:

cursor.execute('SELECT QUOTENAME(%s)', (columnname,))
quoted_columnname, = next(cursor)
现在,您可以在新查询中使用该字符串:

query = 'ALTER TABLE tablenameA ADD {} varchar(25) NULL'.format(quoted_columnname)

我使用
str.format()
在这里插入字符串,而不是使用字符串连接。请注意,
[…]
方括号不再需要
QUOTENAME()
解决了这个问题。

Transact-SQL具有将SQL字符串转换为安全对象名称的功能:。在绑定参数周围使用它,让数据库驱动程序提供正确引用的SQL对象:

cursor.execute('SELECT QUOTENAME(%s)', (columnname,))
quoted_columnname, = next(cursor)
现在,您可以在新查询中使用该字符串:

query = 'ALTER TABLE tablenameA ADD {} varchar(25) NULL'.format(quoted_columnname)

我使用
str.format()
在这里插入字符串,而不是使用字符串连接。请注意,
[…]
方括号不再需要
QUOTENAME()
解决了这个问题。

您可以使用相同的
QUOTENAME
文档:返回添加了分隔符的Unicode字符串,以使输入字符串成为有效的SQL Server分隔标识符。字符串在这里仍然不起作用,因为它没有创建完整的SQL语句。是否使用
查询数据库一次,然后选择QUOTENAME(%s)
,然后将其插入查询中?do…?@deceze:确实可以。我不太担心我的更新,因为我对列名使用SELECT,而不是从表行使用SELECT。我从中选择的另一个数据库是Oracle DB,我在其中查询行值而不是列名。这就是我担心的地方,在相同的
QUOTENAME
文档中可能隐藏着一些东西:返回一个添加了分隔符的Unicode字符串,以使输入字符串成为有效的SQL Server分隔标识符。字符串在这里仍然不起作用,因为它没有创建完整的SQL语句。是否使用
查询数据库一次,然后选择QUOTENAME(%s)
,然后将其插入查询中?do…?@deceze:确实可以。我不太担心我的更新,因为我对列名使用SELECT,而不是从表行使用SELECT。我从中选择的另一个数据库是Oracle DB,我在其中查询行值而不是列名。这就是我担心可能有什么东西潜伏的地方