我是否可以安全地反对SQL注入

时间:2009-03-09 20:35:08

标签: sql security postgresql sql-injection

当我在PostgresSQL中使用类似的东西时,我想知道我是否可以安全地使用SQL注入:

CREATE or REPLACE FUNCTION sp_list_name( VARCHAR )
RETURNS SETOF v_player AS '
   DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;
' LANGUAGE 'plpgsql' VOLATILE;

我想使用此功能列出以字母开头的玩家姓名。

select * from sp_list_name( 'A' );

给我的球员姓氏以A开头。

我试着用

注入sql
select * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );

我安全吗?

我可以注射哪种情况?

此致

7 个答案:

答案 0 :(得分:7)

就您的程序而言,您似乎很安全,因为SP中的变量不会扩展为代码,但如果您不使用参数化查询,例如“ SELECT * FROM sp_list_name(?);,您仍然可以展示自己“在您的应用代码中。通过起始名称“ SELECT * FROM sp_list_name('$start_name'); ”的用户可能会破坏“ ');delete from t_player where last_name NOT IN (' ”之类的内容。因此,请使用参数化查询或完整性检查程序中的输入。

NB:请注意,存储过程中的变量会扩展为代码,即使它包含'或;,(不包括传递给它) EXECUTE ,您将使用 quote_literal ,而不是手动 replace 函数),因此替换;或者“完全没必要(在存储过程中,使用它的应用程序当然是一个不同的故事)并且会阻止你总是找到”tl;dr“或”O'Grady“团队。

Leo Moore,Karl,LFSR咨询:存储过程中的v_temp_name NOT 扩展为SP中的代码(无 EXECUTE < / em>),需要在应用程序中进行检查,而不是SP(或者OP可能只是在他们的应用程序代码中使用参数化查询)。其他人的建议类似于担心

my $bar = "foo; unlink('/etc/password');"; 
my $baz = $bar;

在没有评估的情况下实际运行取消链接。

答案 1 :(得分:6)

防止sql注入的规则#1:清理所有来自某人/你无法信任/无法控制的内容的输入。

问题本身并不在于数据库代码,而在于执行这些语句的应用程序。

答案 2 :(得分:4)

防止SQL注入的正确方法是通过White Listing * - 长和短设置你要接受的字符并将其过滤掉。

错误的方法是Black List - 黑名单列出哪些字符不被接受会导致麻烦,因为你不能跟上攻击者。有很多方法可以通过ASCII表,转义字符以及其他方式来处理黑名单。

此外,这是一个很好的cheat sheet试用你的网站。运行一些测试并尝试让事情失败。

*在应用程序中,而不是DB(感谢James)

答案 3 :(得分:1)

您不是为自己生成SQL,所以这看起来很安全(对我而言)。

我不知道您调用存储过程的数据来自哪里。所以你仍然要防止缓冲区溢出等。

答案 4 :(得分:1)

参考。白名单。如果遵循某些其他条件,这是可以的。将所有输入分解为最简单的形式是绝对必要的,所以不要只检查SQL查询名称,单引号等。它们可以使用其他字符集来表示或编码,这就是白色列表的一部分而不是具体的SQL关键字本身。

我正在为一个特定的客户工作,该客户端允许使用受保护资源的用户名/密码(最终可以获得访问机场安全部分的访问权限!)。您可以通过输入'然后从那里构建SQL查询来检索用户帐户和密码来绕过登录字段。

问题是客户已经用一个似乎从未进行过web开发的供应商建立了该网站的20万英镑。修复是另一个£60k,这是一个验证func()只检查union,select,等等关键词。当被问及他们为canicolisation /编码做了什么(我必须解释)时,它是风滚草时间。

开发房屋和(昂贵的)项目得到了罐装。

答案 5 :(得分:-1)

您可以考虑验证

 v_start_name 
的内容。检查字符串是否有冒号,注释字符,等号等。请记住检查字符和十六进制值。请记住允许使用带连字符的名称,例如“史密斯 - 布朗”可能是可以接受的'史密斯 - 布朗'可能会注射。

如果不熟悉SQL注入中的Hex,以下是快速介绍

http://www.arejae.com/blog/sql-injection-attack-using-t-sql-and-hexadecimal.html

http://www.securityfocus.com/infocus/1768

DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      --  new pseudo code here
      if v_start_name has bad chars exit with error message
      -- end pseudo code here
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;

此致 卡尔

答案 6 :(得分:-2)

只需对v_start_name进行替换即可删除“;”等等。

v_clean_name VARCHAR;
Select v_clean_name = Replace(v_start_name,';','');

这将取代;与空白挫败SQL注入攻击

有关详细信息,请参阅String Functions in PostgresSQL

LFSR咨询公司也评论道。最好使用WhiteList(即不处理任何带有无效字符的输入,如';')而不是BlackList(即尝试清理数据,因为用户也可以对你的Replace进行SQL注入攻击)。

有关详细信息,请查看SQL Injection Attacks