这段代码如何容易出现SQL注入?

时间:2013-11-01 13:08:23

标签: postgresql sql-injection defensive-programming

我正在阅读PostgreSql文档here,并遇到以下代码段:

EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
   INTO c
   USING checked_user, checked_date;

文档指出“这种方法通常比将数据值作为文本插入命令字符串更好:它避免了将值转换为文本和返回的运行时开销,而 则更少容易受到SQL注入攻击 ,因为不需要引用或转发“。

你能告诉我这段代码是如何容易进行SQL注入的吗?

我使用过的所有其他RDBMS中的

编辑将完全阻止SQL注入。在PostgreSql中以不同的方式实现了什么?

3 个答案:

答案 0 :(得分:2)

快速回答是它本身并不容易出现SQL注入,因为我理解你的问题,你在问我们为什么不这么说。因此,既然您正在寻找可能导致SQL注入的场景,请考虑mytable可能是一个视图,因此可能有其他功能。这些函数可能容易受到SQL注入的攻击。<​​/ p>

因此,您无法查看查询并得出结论,它绝对不会受到SQL注入的影响。您可以做的最好的事情是表明,在提供的级别,此应用程序的特定级别不会引发SQL注入问题。

这是一个sql注入很可能发生的例子。

CREATE OR REPLACE FUNCTION ban_user() returns trigger
language plpgsql security definer as
$$
begin
    insert into banned_users (username) values (new.username);
    execute 'alter user ' || new.username || ' WITH VALID UNTIL ''YESTERDAY''';
    return new;
end;

请注意,实用程序功能无法按照您的指示进行参数化,我们忘记在quote_ident()周围new.username,从而使该字段容易受到攻击。

CREATE OR REPLACE VIEW banned_users_today AS
SELECT username FROM banned_users where banned_date = 'today';

CREATE TRIGGER i_banned_users_today INSTEAD OF INSERT ON banned_users_today
FOR EACH ROW EXECUTE PROCEDURE ban_user();

EXECUTE 'insert into banned_users_today (username) values ($1)'
USING 'postgres with password ''boo''; drop function ban_user() cascade; --';

所以即使在任何地方都可以使用它,它也不能完全解决问题。正确使用quote_literal()quote_ident()并不能始终解决问题。

问题是问题总是低于您正在执行的查询。

答案 1 :(得分:1)

绑定参数可以防止垃圾操纵语句执行除了预期之外的任何操作。

这保证了SQL注入攻击不会出现Postgres错误。 (有关可能出错的示例,请参阅H2C03's link。)

我认为“更不容易发生SQL注入攻击”相当于CYA的措辞,这样的事情就会出现。

答案 2 :(得分:0)

SQL注入通常与 pastebin.com 上的大型数据转储相关联,并且此类方案在此处不起作用,即使该示例使用的是contatenation而非变量。这是因为COUNT(*)将聚合您试图窃取的所有数据。

但我可以想象任意记录的计数将是足够有价值的信息 - 例如竞争对手的客户数量,销售产品的数量等。实际上,回想起一些非常棘手的盲目SQL注入方法,有可能构建一个单独使用COUNT的查询,可以迭代地从数据库中恢复实际文本。

在数据库上利用足够旧和错误配置以允许;分隔符也会容易得多,在这种情况下,攻击者可能只是附加一个完全独立的查询。