代码之家  ›  专栏  ›  技术社区  ›  Luc M

我对SQL注入安全吗

  •  3
  • Luc M  · 技术社区  · 16 年前

    我想知道,当我在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开头。

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

    我安全吗?

    哪种情况下我可以注射?

    7 回复  |  直到 16 年前
        1
  •  7
  •   MkV    16 年前

    SELECT * FROM sp_list_name(?); “在你的 应用程序代码 . 类似于“ SELECT * FROM sp_list_name('$start_name'); ');delete from t_player where last_name NOT IN (' “。因此,请使用参数化查询或健全性检查程序中的输入。

    对于其他人,请注意存储过程中的变量 扩展到代码中,即使它包含“或;”;,(不包括传递给 处决 ,您将使用 quote_literal ,不是手滚的 replace (b)如此取代;或“完全没有必要(在存储过程中,使用它的应用程序当然是另一回事),并且会阻止您始终找到” tl;dr “或” O'Grady “团队。

    Leo Moore,Karl,LFSR咨询公司 : v_temp_name 将扩展为SP中的代码(否 ),检查需要在应用程序中进行,而不是在SP中进行(或者OP可以在其应用程序代码中使用参数化查询)。其他人的建议类似于担心

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

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

        2
  •  6
  •   Jan Jungnickel    16 年前

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

        3
  •  4
  •   Gavin Miller    16 年前

    White Listing *-长字符和短字符用于设置要接受的字符并将其过滤掉。

    错误的方法是 Black List -黑名单哪些字符不被接受将导致麻烦,因为 你不能 跟上攻击者。通过ASCII表格、转义字符以及其他方式,可以绕过黑名单。

    还有,这里有一个很好的例子 cheat sheet 在您的网站上试用。运行一些测试并尝试让事情失败。

    *

        4
  •  1
  •   GvS    16 年前

    您没有为自己生成SQL,因此(在我看来)这看起来很安全。

        5
  •  1
  •   Noelie Dunne    16 年前

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

    我为一个特定的客户端工作,该客户端允许用户名/密码访问受保护的资源(这最终可以让您进入机场的安全部分!)。您可以通过输入“登录”字段绕过登录字段,然后从中构建SQL查询以检索用户帐户和密码。

    问题是,客户已经花了20万英镑与一家似乎从未进行过web开发的供应商一起建立了网站。修复是另外一个60k,这是一个validate func(),它只检查union、select、have等关键字。当被问及他们对犬齿化/编码做了什么(我必须解释一下)时,是风滚草时间了。

    开发公司和(昂贵的)项目被解雇了。

        6
  •  -1
  •   Karl    16 年前

     v_start_name 
    . 检查字符串中是否有分号、注释字符、等于等。记住同时检查字符和十六进制值。请记住允许使用连字符的名称,例如,“Smith-Brown”可能是可以接受的,“Smith-Brown”可能是注射剂。

    如果不熟悉SQL注入中的十六进制,以下是快速介绍

    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;
    

    当做

        7
  •  -2
  •   Leo Moore    16 年前

    只需在你的v_start_名称上做一个替换,以摆脱“;”等

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

    这将取代;使用blanks阻止SQL注入攻击

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

    SQL Injection Attacks