我很确定答案是现在要求的不仅仅是要求宽恕......
我的理解是,当我们在服务器端代码中创建查询并直接针对数据库运行时,通常会发生SQL注入:
db.any('SELECT * FROM Foo WHERE id = '${bar}')
但是,如果我们使用存储过程,它是否总是安全的?我的理解(以及我能够找到的搜索主题)是,只要我们使用正确的类型,那是因为如果我们使用
db.any('SELECT * FROM Foo WHERE id = $1', [bar])
如果bar不是与列id匹配的类型,则抛出类型转换。如果id是一个字符变化或文本字段,我们做了类似的事情:
const bar = "1'; DROP TABLE users;";
db.any('SELECT * FROM Foo WHERE id = $1', [bar])
会(在这种情况下是Postgres)告诉它是一个字符变化或文本字段并安全地将其输入数据库??或者,为了安全起见,我们应该在将数据发送到存储过程之前对其进行消毒吗?
答案 0 :(得分:1)
这取决于函数内部发生的事情。
封装动态SQL的函数的唯一优点是将检查参数的类型,如果没有参数是字符串,这将使动态SQL安全。
除此之外,你将不得不使用一种常见的结构:
EXECUTE format('SELECT * FROM Foo WHERE id = %s', bar);
或
EXECUTE 'SELECT * FROM Foo WHERE id = ' || quote_literal(bar);
答案 1 :(得分:0)
是的,您需要在使用SP中的值之前进行清理,至少对于字符串字段。
const bar = "1'; DROP TABLE users;";
db.any('SELECT * FROM Foo WHERE id = $1', [bar]
如果id
是字符串,则您提到的此方案将创建SQL注入。