当我在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开头。
我试着用
注入sqlselect * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );
我安全吗?
我可以注射哪种情况?
此致
答案 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