PostgreSQL.这样的功能容易受到SQL注入还是安全?



有问题的函数

我正在探索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为整数

DB Fiddle for the: 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');

将返回"查询错误:Error: cannot open multi-query plan as cursor">.

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

那么我们可以得出这样的结论:这个函数实际上是安全的吗?

如果是,那么为什么?

更新。可能的攻击计划

也许我没说清楚:我不是在问一般的指导方针,而是在问实验性的漏洞利用,或者证明这种漏洞不可能被利用。

DB Fiddle for this: https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/4(或者你可以提供其他当然)

我的结论到目前为止

。如果_orderby有部件,这种攻击是可能的:

  1. sql代码抑制第一个SELECT的输出
  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很容易。我不知道怎么做第一部分。

这会生成:"error: cannot open multi-query plan as cursor">

B。如果不能抑制第一个SELECT

:

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

?我们能得出这样的结论吗?

还是我错过了什么?

更新2。使用准备函数进行攻击

从答案https://stackoverflow.com/a/69189090/1168212

。通过昂贵的计算实现拒绝服务攻击是可能的

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攻击?

想法?

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

例如,您可以传递任意子查询,只要它只返回单行:(SELECT max(i) FROM generate_series(1, 100000000000000) AS i)。如果查询的开销足够大,那么很容易将其用于拒绝服务攻击。或者,像这个例子一样,您可以在临时文件中造成(短暂的)空间不足的情况。

如果你把一个有副作用的函数放进ORDER BY子句,你也可以修改数据。

相关内容

  • 没有找到相关文章

最新更新