这不是那么相关,所以我只是对以下内容感到好奇(Python 2.7):
我刚刚开始使用psycopg并阅读文档,他们总是使用字符串(%s)和元组将值传递给查询。
变量占位符必须始终为%s
因此,请考虑以下示例 -
在名为' test'的表格中使用字段value_1(varchar)和value_2(int)将查询创建为:
value_1 = "test"
value_2 = "100"
cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",\
(value_1,value_2))
我的问题是,使用“格式”是不是一种不好的做法,甚至是有问题的。方法改为(如下):
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".\
format(value1=value_1,value2=value_2))
根据您的经验,您说什么,这真的很危险或有问题吗?
答案 0 :(得分:5)
电话
cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",\
(value_1,value_2))
有一个字符串参数和一个附加参数,它是替换值的元组。
这允许psycopg2
插值,并且比简单的字符串插值更安全。
♯传递数据以填充查询占位符并让Psycopg执行
♯正确的转换(不再进行SQL注入!)
&GT;&GT;&GT; cur.execute(&#34; INSERT INTO test(num,data)VALUES(%s,%s)&#34;,...(100,&#34; abc&#39; def&#34;))< / p>
在通话中
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".\
format(value1=value_1,value2=value_2))
你是自己插值,只是将结果字符串传递给游标执行方法。
简单插值易受SQL注入的影响。你可能最好使用第一种形式。
您应该始终考虑"Little Bobby Tables"。
答案 1 :(得分:1)
在阅读了一些文档和资源并自行测试后,直截了当。 简单的回答:这是不安全的。不仅适用于psycopg2,也适用于任何数据库模块(至少对于我测试的那些)。 将此与psycopg2相关联,使用(%s),(变量)允许psycopg2自动转义这些变量以防止这样的混乱。
我试图找出它可以造成的小麻烦:
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}','{value2}')".\
format(value1=value_1,value2='1); drop table test; --killer instinct'))
就是这样,adiós测试表:-P
答案 2 :(得分:1)
是的,Psycopg2对所有类型都使用%s,psycopg2将参数转换为字符串表示形式并在查询中使用它
INSERT INTO test (value_1,value_2) VALUES('test','100');
有时您可能需要将某些值强制转换为适当的类型。
cur.execute("""INSERT INTO test (value_1,value_2)
VALUES (%s,%s::integer)""",
(value_1,value_2))
你提出的方法是非常糟糕的做法,你已经为value_1和value_2的几个可能的值注入了sql。例如:
value_1="',0); rollback; drop table test ; --"