0

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

4

1 回答 1

1

ODP.net 在您的 .net 代码和 Oracle 之间提供了一个接口。如果您在将控制权传递给 proc 之后构建动态 sql,那么 odp.net 可以为您做的事情不多。

危险是字符串,在这种情况下是 varchar。它实际上只是一个字符串或类似的东西,有人可以将一些额外的 sql 注入到您的代码中。只要绑定变量始终是单个字符串(即一组未转义的单引号),恶意用户就无能为力了。

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

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

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

好的:

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

坏的:

'where myval=' || p_my_val 

3)用字符串中的两个单引号替换任何单引号

'where myval=''' || replace(p_my_val, '''', '''''') || ''''

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

--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);
于 2013-03-21T21:38:56.723 回答