从ODP.net处理Apostrophe以发送给Oracle

时间:2013-03-20 17:25:54

标签: asp.net-mvc-4 oracle11g odp.net

我将向存储过程发送一些信息,将信息输入数据库 存储过程动态构建查询,因此我必须小心发送给它的内容。 我只是在我的前端(我正在使用asp.net MVC)或我的网络服务上从所需参数中提取任何恶意字符。这可行,但如果我需要输入像奥布莱恩这样的名字呢?还是不行?我需要能够将其输入到oracle中。我可以在动态构建时围绕这些特定参数包装q [],但我认为这不会起作用。 odp .net是否有任何特殊的方法调用可以神奇地处理这种特殊情况? 或者我必须在我自己专门编写代码?

1 个答案:

答案 0 :(得分:1)

ODP.net提供.net代码与Oracle之间的接口。如果你正在构建动态sql AF​​TER控件已经传递给proc,那么odp.net可以为你做的不多。

危险是字符串,在这种情况下是varchar。它实际上只是一个字符串或类似的东西,有人可以在你的代码中注入一些额外的sql。只要绑定变量总是一个字符串(即一组未转义的单引号),就不会有恶意用户可以做的很多。

所以我认为有一些规则可以让你认为这是安全的:

1)仅在绝对必要的地方使用varchar / clob参数。

2)在生成的sql中,varchar / clob绑定值应始终用单引号括起来:

好:

'where myval=''' || p_my_val || ''''

为:

'where myval=' || p_my_val 

3)用字符串

中的两个单引号替换任何单引号
'where myval=''' || replace(p_my_val, '''', '''''') || ''''

我认为那时你会减轻你的风险。以下是oracle方面的完整工作示例。我还在sql中包含了一个绑定变量“l_fname”,并填充了“using”,以防你有其他变量总是在查询中(vs有条件地追加)并且总是以相同的顺序。

--create the ref cursor (simulates cmd.Parameters.Add)
var c refcursor;
--vvvvvvvvv simulates your stored proc vvvvvvvvvvvv
declare 
  l_lname varchar2(200) :='O''brian';
  l_fname varchar2(200) :='Bob';
  l_sql varchar2(2000);
begin
  l_sql := 'select * from dual where dummy!=:l_fname ' || 'and dummy!=''' || replace(l_lname, '''','''''') || '''';
  dbms_output.put_line(l_sql);
  open :c for l_sql using replace(l_fname, '''', '''''');
end;
--^^^^^^^^^ ends yoru stored proc ^^^^^^^^^^^^^^^^^
/
--debugging within oracle only:
print c;

还要考虑是否需要动态sql。你在最终的sql字符串之外做的几乎任何逻辑都可以在其中完成,即:

if( p_my_var is not null ) then
  p_sql = p_sql || ' and myval = ''' || replace(p_my_val, '''', '''''') || ''''

可能是

and p_my_val is null or myval=p_my_val

我强烈推荐SQL Server中的上述内容。我还建议在Oracle中进行此操作,但它不会像在sql server中那样短路,因为在执行计划中不考虑绑定值,导致它在某些情况下不是最优的(至少在10g中) 。在这种情况下,请改用以下内容:

and myval=decode(p_my_val, null, col1, p_my_val);