我想知道当我在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;--' );我安全吗?
哪种情况下我可以被注射?
问候
发布于 2009-03-09 21:43:15
就您的过程而言,您似乎是安全的,因为SP中的变量不会扩展到代码中,但是如果您在应用程序代码中不使用"SELECT * FROM sp_list_name(?);“这样的参数化查询,您仍然可以暴露自己。用户通过传递起始名称"');delete from t_player where last_name NOT IN ('".可以破坏类似"SELECT * FROM sp_list_name('$start_name');“的内容因此,在程序中使用参数化查询或健全性检查输入。
NB:对于其他人,请注意,存储过程中的变量将不会扩展到代码中,即使它包含‘;或;,(不包括传递它以执行,对于执行,您将使用quote_literal,而不是手工滚动的replace函数),因此替换;or’是完全不必要的(当然,在存储过程中,使用它的应用程序是另一回事),并且会阻止您总是找到"tl;dr“或"O'Grady”团队。
Leo Moore,Karl,LFSR Consulting:存储过程中的v_temp_name不会扩展到SP中的代码(不执行),检查将需要在应用程序中完成,而不是SP (否则OP可能只在其应用程序代码中使用参数化查询)。其他人的建议类似于担心
my $bar = "foo; unlink('/etc/password');";
my $baz = $bar;实际上在没有eval的情况下运行unlink。
发布于 2009-03-09 20:40:58
防止sql注入的规则#1 :清理来自你不能信任/无法控制的人/物的所有输入。
问题本身不在于数据库代码,而在于执行这些语句的应用程序。
发布于 2009-03-09 22:19:47
防止SQL注入的正确方法是通过White Listing* -长整型和短型是设置您要接受的字符并将其过滤掉。
不正确的方法是将不被接受的字符列在黑名单上会导致麻烦,因为你不能和攻击者保持一致( Black List up )。有一些方法可以通过ASCII表、转义字符等等来绕过黑名单。
另外,这里有一个很好的cheat sheet,可以在你的网站上试用。运行一些测试,并尝试让事情失败。
应用程序中的*,而不是数据库(感谢詹姆斯)
https://stackoverflow.com/questions/627918
复制相似问题