这实际上是对SQL注入开放吗?

时间:2018-01-29 14:00:34

标签: postgresql sql-injection

我们有一个构建一些XML的函数,并使用EXECUTE / USING来防止SQL注入。这是:

CREATE OR REPLACE FUNCTION public.f1(t TEXT)
    RETURNS XML AS
$BODY$
DECLARE
    ret_val XML;
BEGIN
    EXECUTE 'SELECT ''<'' || $1 || ''>'''
    --rest of xml building
    INTO ret_val
    USING t;
    RETURN ret_val;
END
$BODY$
    LANGUAGE plpgsql IMMUTABLE;

由于连接,我不喜欢这么多。如果我们可以做SELECT '''<$1>''会更好,但结果是文字$ 1而不是用值替换它。

由于连接,它让我想知道我们是否甚至需要SQL注入预防。它不是从表中读取,只是构建一个返回的XML字符串。

在这种情况下,不使用USING是否存在实际风险?连接$ 1会否定USING的影响,或者USING是否会对不使用表的语句产生任何影响?

2 个答案:

答案 0 :(得分:1)

此处没有SQL注入的危险,因为您使用的是USING

请注意,您可能一直在使用静态SQL来实现相同的目标:

SELECT '<' || t || '>' INTO ret_val;

答案 1 :(得分:1)

这里要解开一些东西。

首先,你在那里的SQL实际上是一个固定的字符串:

'SELECT ''<'' || $1 || ''>'''

所以没有什么可以直接注入这里,因为没有动态SQL。正如Laurenz Albe指出的那样,这个特定示例中的SQL可以写成非动态语句:

SELECT '<' || t || '>'

此处仍然没有SQL注入,因为您不是评估 t的内容,只是将其作为字符串进行操作,就像SELECT a + 1一样将a操纵为数字。

关键是实际的SQL是硬编码的,而连接只是该SQL中的指令。

请注意,这个看似相似的查询是危险的(语法突出显示了差异的线索):

EXECUTE 'SELECT ''<' || t || '>''' -- DON'T DO THIS!

这里,t的值被用作作为SQL字符串的一部分 - 首先发生连接,然后执行结果。因此,'1'; DROP TABLE users; --'的值会导致查询SELECT '<1'; DROP TABLE users; --,这显然是不受欢迎的。

其次,作为explained in the docs$1参数,由USING子句作为数据提供,因此它SQL注入也是安全的。这类似于在数据库外部的编程语言中使用参数化查询 - 您将查询构建为字符串,仔细地将引用的表和列列入白名单,然后单独提供变量数据,而不能将其重新解释为SQL。或者换句话说,它就像另一个函数&#34;更深一层......&#34;,USING子句指定的参数就像实际函数的参数一样。

最后,请注意: 或危险的XML。例如,考虑如果t的值为t并且结果最终解析为HTML,会发生什么。