当我在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开头的球员.
我试着用sject注入
select * from sp_list_name( 'A; delete from t_player;--' ); select * from sp_list_name( '''; delete from t_player;--' );
我安全吗?
我可以注射哪种情况?
问候
就您的程序而言,您似乎很安全,因为SP中的变量不会扩展为代码,但如果您不在应用程序代码中使用" SELECT * FROM sp_list_name(?);
" 这样的参数化查询,您仍然可以暴露自己.用户传递起始名称" "可能会破坏像" "这样的东西.因此,请使用参数化查询或完整性检查程序中的输入.SELECT * FROM sp_list_name('$start_name');
');delete from t_player where last_name NOT IN ('
注意: 对于其他人,请注意,存储过程中的变量不会扩展为代码,即使它包含'或;,(不包括传递给EXECUTE,您将使用它quote_literal
,而不是手动滚动replace
函数),因此替换; 或者"完全没必要(在存储过程中,使用它的应用程序当然是一个不同的故事)并且会阻止你总是找到" tl;dr
"或" O'Grady
"团队.
Leo Moore,Karl,LFSR咨询: v_temp_name
在存储过程中不会扩展到SP中的代码(没有EXECUTE),需要在应用程序中进行检查,而不是SP(或者OP可以只使用参数化查询在他们的应用程序代码,而不是).其他人的建议类似于担心
my $bar = "foo; unlink('/etc/password');"; my $baz = $bar;
实际上在没有eval的情况下运行unlink.
规则#1防止sql注入:清理所有来自某人/你无法信任/无法控制的内容的输入.
问题本身不在于数据库代码,而在于执行这些语句的应用程序.