Python中的sqlite3:手动设置字符串格式对于选择或更新变量列是否安全?
众所周知,不应该使用本机字符串操作组装SQL查询,而应该使用带有占位符的准备语句作为变量。Python中的sqlite3是这样处理的:Python中的sqlite3:手动设置字符串格式对于选择或更新变量列是否安全?,python,sqlite,Python,Sqlite,众所周知,不应该使用本机字符串操作组装SQL查询,而应该使用带有占位符的准备语句作为变量。Python中的sqlite3是这样处理的: c.execute('UPDATE stock SET price = ? WHERE symbol = ?', the_price, the_symbol) 这种方法的限制是无法为选定或更新的列设置参数。在上面的示例中,价格列被更新。但是,其他请求将以相同的方式更新另一列。除了列的名称之外,这些请求中的每一个都几乎相同。因此,对于干燥(不要重复你自己),很容
c.execute('UPDATE stock SET price = ? WHERE symbol = ?', the_price, the_symbol)
这种方法的限制是无法为选定或更新的列设置参数。在上面的示例中,价格列被更新。但是,其他请求将以相同的方式更新另一列。除了列的名称之外,这些请求中的每一个都几乎相同。因此,对于干燥(不要重复你自己),很容易采取以下措施:
if my_col in LIST_OK_COLUMNS:
c.execute('UPDATE stock SET {} = ? WHERE symbol = ?'.format(my_col), the_symbol, the_price)
不过,这是一个使用本机字符串操作构建的查询,根据文档,这是不安全的
正确执行此操作的最标准方法是什么?如果直接插入SQL语句的任何字符串可能由用户控制,则说明您有问题 对于值,可以使用SQL参数 表/列名没有这种机制(因为向用户询问这些名称通常不会发生;SQL是在邪恶的互联网出现之前设计的,一半的应用程序运行在不受信任的客户端上) 要生成列名称,例如
price=-100,其中1或symbol=--代码>无害,您必须正确地避开它:
def sql_escape_identifier(s):
return '"' + s.replace('"', '""') + '"'
c.execute('UPDATE stock SET {} = ...'.format(sql_escape_identifier(my_col)), ...
如果直接插入到SQL语句中的任何字符串可能由用户控制,则会出现问题
对于值,可以使用SQL参数
表/列名没有这种机制(因为向用户询问这些名称通常不会发生;SQL是在邪恶的互联网出现之前设计的,一半的应用程序运行在不受信任的客户端上)
要生成列名称,例如price=-100,其中1或symbol=--代码>无害,您必须正确地避开它:
def sql_escape_identifier(s):
return '"' + s.replace('"', '""') + '"'
c.execute('UPDATE stock SET {} = ...'.format(sql_escape_identifier(my_col)), ...
晚一点可以。。。由于您控制着SQL的输入(列名等)-风险在于实际参数通常位于程序外部,很容易忘记对其进行清理,因此建议使用现有功能,而不是字符串格式。(当然…如果你让my_col
来自外部源-那是件坏事(tm))好吧,我的_col确实来自外部源,因为只有前端最终知道要更新什么。啊,对不起-我误读了最后一个代码块-是的-只要你验证-那很好…)后者没问题。。。由于您控制着SQL的输入(列名等)-风险在于实际参数通常位于程序外部,很容易忘记对其进行清理,因此建议使用现有功能,而不是字符串格式。(当然…如果你让my_col
来自外部源-那是件坏事(tm))好吧,我的_col确实来自外部源,因为只有前端最终知道要更新什么。啊,对不起-我误读了最后一个代码块-是-只要你验证-那很好…)