gpt4 book ai didi

postgresql - 这实际上是对SQL注入(inject)开放的吗?

转载 作者:行者123 更新时间:2023-11-29 12:08:39 26 4
gpt4 key购买 nike

我们有一个函数可以构建一些 XML 并使用 EXECUTE/USING 来尝试防止 SQL 注入(inject)。它的思路是:

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 注入(inject)。它不是从表中读取,只是构建一个返回的 XML 字符串。

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

最佳答案

这里有一些东西需要解包。

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

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

所以这里不能直接注入(inject)任何东西,因为没有动态 SQL。正如 Laurenz Albe 指出的那样,这个特定示例中的 SQL 可以编写为非动态语句:

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

这里仍然没有 SQL 注入(inject),因为您没有评估 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 提供子句 as data,因此它也可以免受 SQL 注入(inject)攻击。这类似于在数据库外的编程语言中使用参数化查询——您将查询构建为一个字符串,小心地将引用的表和列列入白名单,然后单独提供可变数据,其中它不能被重新解释为 SQL。或者换句话说,它就像另一个函数“更深一层”,USING 子句指定的参数就像实际函数的参数一样。

不过,最后,请注意:您容易受到 XML 注入(inject)的攻击:如果没有任何其他验证或转义 t ,您可能会生成无效或危险的 XML。例如,考虑如果 t 的值会发生什么是'foo><script>alert("Hello, world!");</script></foo'结果最终被解析为 HTML。

关于postgresql - 这实际上是对SQL注入(inject)开放的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48503034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com