Python 在postgres中使用$$将NULL插入到可为NULL的行中

Python 在postgres中使用$$将NULL插入到可为NULL的行中,python,postgresql,psycopg2,Python,Postgresql,Psycopg2,我正在努力保护我的申请: q = "insert into foo (name, descr, some_fk_int) values ($${}$$, $${}$$, $${}$$);".format( name.replace("$$",""), description.replace("$$",""), str(fkToAnotherTable).replace("$$","") if fkToANotherTable is not None else 'NULL' ) cur

我正在努力保护我的申请:

q = "insert into foo (name, descr, some_fk_int) values ($${}$$, $${}$$, $${}$$);".format(
  name.replace("$$",""),
  description.replace("$$",""),
  str(fkToAnotherTable).replace("$$","") if fkToANotherTable is not None else 'NULL'
)
cur.execute(q)
我注意到,在执行此操作时,它会尝试将字符串NULL插入DB中的整数条目中。为了保持一致性,我几乎用这种方式处理所有字符串,所有int都转换成字符串,然后也这样做(只覆盖基数)

当它只是:

.... ($$Tony$$,$$Bar$$, NULL)
但现在是:

.....($$Tony$$, $$Bar$$, $$NULL$$) 
它失败了。我在想有一种统一的方式来实现这一点。我这样做是因为在查找索引时,我注意到它将int理解为字符串

select * from foo where id = $$id$$
所以我把用户输入输入数据库的应用程序屏蔽了。我可以从int中删除它,但我认为如果有人试图将字符串传递到int中以查看“会发生什么”,这将是一个明智的做法

我在想,如果ID是int,那么查询将失败,而您确实做到了:

 select * from foo where id = $$hello$$
但我想到了更有趣的案例,有人会尝试sqlinjection

 select * from foo where id = $$$$ or 1=1$$$$
其中注入的字符串为:
$$或1=1$$
。我想我可以通过转换为字符串,然后替换关键字符来解决这个问题。但在注入或选择的过程中,我注意到了空的情况,并试图找出如何绕过它

也许我应该自定义查询以执行以下操作:

q = "insert into foo (name, description, fk) values
  ( $${}$$, $${}$$, {} );".format(
  name.replace("$$",""),
  description.replace("$$",""),
  "$${}$$".format(str(FK).replace("$$","")) if FK is not None else "NULL"
)
如果不是“无”,则只添加
$
?那就行了

TLDR:是否有一种属性方式将“NULL”传递到int字段中,并将其理解为NULL

编辑:人们似乎认为我应该遵循psycopg2中游标执行函数第二个属性下的参数化查询定义

我不确定它是否能解决SQL注入问题,但我正在考虑做以下事情:

q = "select * from foo where name in ({}) and user_id = %s".format(
  ",".join(["%s" for d in my_list])
) 
# creates: select * from foo where name in (%s, %s, %s, %s, %s) and user_id = %s;
args = [d for d in my_list] + [user_id]
# creates [1,2,3,4,5,7493]
cursor.execute(q, args)

由于网站允许第二个参数是序列、列表或指令。

您希望使用预处理语句。避免sql注入的最佳方法是使用预处理语句。我正在查看execute函数,该函数允许我执行以下操作:
cursor.execute(“插入到foo(a,b)值(%{}s,%{}s)”,(“foo”,“bar”))
但一些需要构建值列表的批量插入使我无法确定传递到参数中的道具是否是超级动态的。我正在动态地构建
(..)
中的内容。我想我可以根据需要的大小动态地附加到paren块上。准备好的语句会自动清理吗?我不确定在使用prepared语句时是否还需要做一些额外的事情。我不确定prepared语句在这里会有什么帮助,但我鼓励您让psycopg2进行参数转义,请参见例如。