使用存储过程时是否需要清理数据?

时间:2017-12-21 04:03:13

标签: sql postgresql sql-injection

我很确定答案是现在要求的不仅仅是要求宽恕......

我的理解是,当我们在服务器端代码中创建查询并直接针对数据库运行时,通常会发生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)告诉它是一个字符变化或文本字段并安全地将其输入数据库??或者,为了安全起见,我们应该在将数据发送到存储过程之前对其进行消毒吗?

2 个答案:

答案 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注入。