我很确定答案是现在要求的不仅仅是请求宽恕......
我的理解是,当我们在服务器端代码中创建查询并直接针对数据库运行时,通常会发生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)告诉它是一个字符变化或文本字段并安全地将其输入数据库??或者我们应该在将数据发送到存储过程之前对其进行消毒以确保安全吗?
这取决于函数内部发生的事情。
封装动态SQL的函数的唯一优点是将检查参数的类型,如果没有参数是字符串,这使得动态SQL安全。
除此之外,你将不得不使用一个通常的结构:
EXECUTE format('SELECT * FROM Foo WHERE id = %s', bar);
要么
EXECUTE 'SELECT * FROM Foo WHERE id = ' || quote_literal(bar);
是的,您需要在使用SP中的值之前进行清理,至少对于字符串字段。
const bar = "1'; DROP TABLE users;";
db.any('SELECT * FROM Foo WHERE id = $1', [bar]
如果id
是一个字符串,那么您提到的这种情况将创建SQL注入。