【问题标题】:PostgreSQL. Is such function vulnerable to SQL injection or is it safe?PostgreSQL。这样的函数是否容易受到 SQL 注入的影响,或者它是否安全?
【发布时间】:2023-04-07 05:14:02
【问题描述】:

看起来有问题的函数

我正在探索 postgresql 数据库,我看到了一个反复出现的模式:

CREATE OR REPLACE FUNCTION paginated_class(_orderby text DEFAULT NULL, _limit int DEFAULT 10, _offset int DEFAULT 0)
RETURNS SETOF pg_class
LANGUAGE PLPGSQL
AS $$
BEGIN
        return  query  execute'
            select * from pg_class
        order by '|| coalesce (_orderby, 'relname ASC') ||'
        limit $1 offset $1
        '
        USING _limit, _offset;
END;
$$;

示例用法:

SELECT * FROM paginated_class(_orderby:='reltype DESC, relowner ASC ')

重复是:

  • _orderby 作为 text 传递。它可以是返回的 SETOF 类型的字段的任意组合。例如。 'relname ASC, reltype DESC'
  • _orderby 参数未以任何方式清理或检查
  • _limit_offset 是整数

为此提供数据库小提琴:https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/1

问题:这样的函数是否容易受到 SQL 注入的影响?

通过外部迹象可以怀疑此类函数容易受到 sql 注入。

但是我所有寻找参数组合的尝试都失败了。

例如

CREATE TABLE T(id int);
SELECT * FROM paginated_class(_orderby:='reltype; DROP TABLE T; SELECT * FROM pg_class');

将返回“查询错误:错误:无法将多查询计划作为游标打开”

如果存在UPDATE/INSERT/DELETE,我没有找到利用漏洞的方法。

那么我们可以断定这样的函数实际上是安全的吗?

如果是这样:那为什么?

更新。可能的攻击计划

也许我不清楚:我问的不是一般准则,而是针对漏洞的实验性利用或证明这种利用是不可能的。

为此提供数据库小提琴:https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/4(或者您当然可以提供其他)

到目前为止我的结论

A.如果_orderby 有部分,那么这种攻击是可能的:

  1. 抑制第一个SELECT 输出的sql 代码
  2. 做一些有害的事情
  3. select * from pg_class 满足RETURNS SETOF pg_class

例如

SELECT * FROM paginated_class(_orderby:='relname; DELETE FROM my_table; SELECT * FROM pg_class')

对于 2 和 3 来说这很容易。我不知道如何做第 1 部分。

这将生成:“错误:无法打开多查询计划作为光标”

B.如果无法先压制SELECT

然后:

  • 每个 postgresql 函数都在单独的事务中工作
  • 由于错误,此事务将被回滚
  • 没有像 Oracle 中那样的自治事务
  • 对于非事务性操作:我只知道与序列相关的操作
  • 其他一切都是 DML 或 DDL 是事务性的

所以?我们能否得出结论,这样的功能实际上是安全的?

或者我错过了什么?

更新 2. 使用准备好的函数进行攻击

来自答案https://stackoverflow.com/a/69189090/1168212

A.实施拒绝服务攻击是可能的,代价是昂贵的计算

B.副作用:

如果你在 ORDER BY 子句中加入一个有副作用的函数,你也可以修改数据。

让我们试试后者:

CREATE FUNCTION harmful_fn()
RETURNS bool
LANGUAGE SQL
AS '
DELETE FROM my_table;
SELECT true;
';

SELECT * FROM paginated_class(_orderby:='harmful_fn()', _limit:=1);

https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/8

是的。

所以如果攻击者有权创建函数:非DOS攻击也是可能的。

我接受 Laurenz Albe 的回答,但是:是否可以在没有功能的情况下进行非 DOS 攻击?

想法?

【问题讨论】:

  • 一个经验法则是,如果用户可以传递被解释为代码的任意文本,那么您就有潜在的 SQL 注入,因此不安全。您总是需要清理用户输入数据。
  • @TedKleinBergman 问题不在于一般准则,而在于如何利用此类漏洞。能否举例说明如何利用此类漏洞?
  • 我明白了。我的意思是回答您发布的问题是否安全。如果用户可以传递被解释为代码的任意文本,那么无论如何它都是不安全的。即使你找不到漏洞。即使你证明不存在这样的东西,它仍然不安全,因为它是一个可能迟早会打开的洞。

标签: postgresql sql-injection


【解决方案1】:

不,这不安全。攻击者可以通过_orderby 参数将任何代码放入您的ORDER BY 子句中。

例如,您可以传递任意子查询,只要它只返回一行:(SELECT max(i) FROM generate_series(1, 100000000000000) AS i)。如果查询足够昂贵,那么这很容易用于拒绝服务攻击。或者,就像这个示例一样,您可能会导致临时文件出现(短暂的)空间不足的情况。

如果你在ORDER BY子句中加入一个有副作用的函数,你或许还可以修改数据。

【讨论】:

  • 您能否举例说明如何利用此漏洞?因为我没有找到做有害的事情的方法
  • 您建议的方法是否出错?在ORDER BY子句中调用带有副作用的函数很容易造成伤害。
  • 看看:db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/5。我得出的结论是“错误:无法将多查询计划作为游标打开”将导致回滚。所以很容易传递一些有害的东西但它会被回滚
  • 嗯。你给了我一个想法:即使不可能破坏数据 - 也应该可以减慢 postgresql 实例的速度。
  • 也许吧。取决于现有的功能。如果你不能马上想到一个漏洞利用,那并不意味着攻击者不能。做正确的事,使用format()quote_literal() 转义字符串,你的头痛就消失了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
相关资源
最近更新 更多