我正在保护我的应用程序:
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插入数据库中的整数条目中。为了使事情保持一致,我几乎将所有字符串都以这种方式处理,并且所有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$$$$
其中注入的字符串为:$$ or 1=1$$
。我当时想我可以通过强制转换为字符串然后替换关键字符来解决它。但是在注入或选择的过程中,我注意到NULL的情况,并试图弄清楚如何绕过它?
也许我应该自定义查询以执行以下操作:
q = "insert into foo (name, description, fk) values
( $${}$$, $${}$$, {} );".format(
name.replace("$$",""),
description.replace("$$",""),
"$${}$$".format(str(FK).replace("$$","")) if FK is not None else "NULL"
)
相反,如果不是{none},则仅添加$$
吗?这样就可以了。
TLDR:是否存在一种将“ NULL”传递给int字段并将其理解为null的属性方法?
编辑:似乎人们在想我应该遵循Cursor的execute函数的第二个属性下在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)
因为网站允许第二个参数为序列,列表或字典。