PostgreSQL.这样的功能容易受到 SQL 注入的攻击还是安全的?
PostgreSQL. Is such function vulnerable to SQL injection or is it safe?
看起来有问题的函数
我正在探索 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 offset
'
USING _limit, _offset;
END;
$$;
示例用法:
SELECT * FROM paginated_class(_orderby:='reltype DESC, relowner ASC ')
重复是:
_orderby
作为 text
传递。它可以是 returned SETOF 类型字段的任意组合。例如。 'relname ASC, reltype DESC'
_orderby
参数未以任何方式清理或检查
_limit
和 _offset
是整数
DB Fiddle 为: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');
will return “查询错误:错误:无法打开多查询计划作为游标”.
我没有找到利用 UPDATE
/INSERT
/DELETE
.
漏洞的方法
那么我们可以断定这样的功能实际上是安全的吗?
如果是这样:那为什么?
更新。可能的攻击计划
也许我不清楚:我不是在询问一般准则,而是在询问对漏洞的实验性利用或证明这种利用是不可能的。
DB Fiddle 为此:https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/4(当然你也可以提供其他的)
到目前为止我的结论
一个。如果 _orderby
将具有以下部分,则这种攻击是可能的:
- sql 抑制第一个
SELECT
输出的代码
- 做一些有害的事情
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 部分的方法。
这将生成:“错误:无法作为游标打开多查询计划”
乙。如果不能先压制SELECT
然后:
- 每个 postgresql 函数在单独的事务中工作
- 由于错误,此事务将被回滚
- 没有 Oracle 中的自治事务
- 对于非事务操作:我只知道与序列相关的操作
- DML 或 DDL 都是事务性的
所以呢?我们可以断定这样的功能实际上是安全的吗?
或者我遗漏了什么?
更新 2. 使用准备好的函数进行攻击
来自回答
一个。有可能实施拒绝服务攻击投入昂贵的计算
乙。副作用:
If you put a function with side effects into the ORDER BY clause, you may also be able to modify data.
让我们试试后者:
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
子句中。
例如,您可以传递任意子查询,只要它 returns 只有一行:(SELECT max(i) FROM generate_series(1, 100000000000000) AS i)
。如果查询的开销足够大,那么它可以很容易地用于拒绝服务攻击。或者,就像这个例子一样,您可以用临时文件引起(短暂的)超出 space 的情况。
如果将具有副作用的函数放入 ORDER BY
子句中,您也许还可以修改数据。
看起来有问题的函数
我正在探索 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 offset
'
USING _limit, _offset;
END;
$$;
示例用法:
SELECT * FROM paginated_class(_orderby:='reltype DESC, relowner ASC ')
重复是:
_orderby
作为text
传递。它可以是 returned SETOF 类型字段的任意组合。例如。'relname ASC, reltype DESC'
_orderby
参数未以任何方式清理或检查_limit
和_offset
是整数
DB Fiddle 为: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');
will return “查询错误:错误:无法打开多查询计划作为游标”.
我没有找到利用 UPDATE
/INSERT
/DELETE
.
那么我们可以断定这样的功能实际上是安全的吗?
如果是这样:那为什么?
更新。可能的攻击计划
也许我不清楚:我不是在询问一般准则,而是在询问对漏洞的实验性利用或证明这种利用是不可能的。
DB Fiddle 为此:https://www.db-fiddle.com/f/vF6bCN37yDrjBiTEsdEwX6/4(当然你也可以提供其他的)
到目前为止我的结论
一个。如果 _orderby
将具有以下部分,则这种攻击是可能的:
- sql 抑制第一个
SELECT
输出的代码
- 做一些有害的事情
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 部分的方法。
这将生成:“错误:无法作为游标打开多查询计划”
乙。如果不能先压制SELECT
然后:
- 每个 postgresql 函数在单独的事务中工作
- 由于错误,此事务将被回滚
- 没有 Oracle 中的自治事务
- 对于非事务操作:我只知道与序列相关的操作
- DML 或 DDL 都是事务性的
所以呢?我们可以断定这样的功能实际上是安全的吗?
或者我遗漏了什么?
更新 2. 使用准备好的函数进行攻击
来自回答
一个。有可能实施拒绝服务攻击投入昂贵的计算
乙。副作用:
If you put a function with side effects into the ORDER BY clause, you may also be able to modify data.
让我们试试后者:
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
子句中。
例如,您可以传递任意子查询,只要它 returns 只有一行:(SELECT max(i) FROM generate_series(1, 100000000000000) AS i)
。如果查询的开销足够大,那么它可以很容易地用于拒绝服务攻击。或者,就像这个例子一样,您可以用临时文件引起(短暂的)超出 space 的情况。
如果将具有副作用的函数放入 ORDER BY
子句中,您也许还可以修改数据。