如果我传递一个where子句作为参数将阻止SQL注入?

时间:2017-05-03 18:14:37

标签: sql oracle sql-injection

我创建了一个Oracle proc,我根据提供给proc的参数创建了一个动态sql语句。

我做了一些测试,看来我无法执行sql注入。

还有什么我应该安全防范的吗?

SELECT 'UPDATE ' || p_table || ' SET MY_FIELD =  ''' || p_Value || ''' ' || p_Where
            INTO query_string
            FROM DUAL; 

编辑:

Scenarios that I've tried.
1. WHERE SOME_VAL IN ('AAA','BBB') - This works
2. WHERE SOME_VAL IN ('AAA','BBB') OR SOME_VAL2 = '123' - This works.
3. WHERE SOME_VAL IN ('AAA','BBB'); DROP TABLE TEST_TABLE; - This errors out.
4. WHERE SOME_VAL IN ('AAA','BBB') OR (DELETE FROM TEST_TABLE) - This errors out.

2 个答案:

答案 0 :(得分:1)

这取决于调用过程的方式和方式。通常,您需要担心SQL注入对于生产中对大量用户开放的内容。对于任何数据库过程都不应该这样。如果大量用户可以访问您的数据库过程,那么您可能会被某人恶意使用。

在您的情况下,您可以通过创建参数映射来隐藏实际架构对象名称和一些验证来降低此风险。

例如,将参数p_table更改为table_name作为输入参数。然后使用case语句映射到实际的表名。我在这里给你一个表名的例子,因为你应该真正限制谁可以从db访问哪个表。

CREATE OR REPLACE PROCEDURE test_proc(table_name IN VARCHAR)
  IS
  p_table varchar2(100);
BEGIN

  CASE table_name 
     WHEN 'A' THEN p_table:='db_table_a';
     WHEN 'B' THEN p_table:='db_table_b';
     ELSE RAISE 'Invalid table name parameter';
  END CASE;
  SELECT 'UPDATE ' || p_table || ' SET MY_FIELD =  ''' || p_Value || ''' ' 
         || p_Where
        INTO query_string
        FROM DUAL; 
END;

您也应该对其他参数进行类似的映射和验证。

答案 1 :(得分:1)

SQL注入始终打开Pandora的框。

您应始终假设用户可以打破动态SQL语句。通过完全SQL访问,您应该假设用户可以找到升级权限和拥有数据库的方法。 (根据您的偏执程度,可能可以安全地假设权限升级是不可能的,只要您的数据库和模式不断修补和彻底强化。实际上绝大多数Oracle数据库都是足够的补丁和硬化。)

下面是一些应该吓到你的简单例子。而且你还应该假设有许多黑客比我更聪明并且有更好的攻击。<​​/ p>

示例架构

首先,让我们创建一个包含一些数据的简单表格,以进行真实的测试。

drop table test1;

create table test1(my_field varchar2(100), some_val varchar2(100));
insert into test1 values('A', 'AAA');
commit;

明显危险的功能

所有现有功能都安全吗?

create or replace function dangerous_function return number is
    pragma autonomous_transaction;
begin
    delete from test1;
    commit;
    return 1;
end;
/

如果没有,是什么阻止用户这样调用它?

--Safe static part:
update test1
set my_field = 'b'
--Dangerous dynamic part:
where some_val IN ('AAA')
    and 1 = (select dangerous_function from dual)

幸运的是,创建一个自治函数是不寻常的,您可以检查代码。但是你可以保证应用程序将来不会创建一个吗?

SQL中的自定义函数

即使没有对象,聪明的用户也可以将您的UPDATE转换为其他DML:

--Safe static part:
update --+ WITH_PLSQL
test1
set my_field = 'b'
--Dangerous dynamic part:
where some_val IN ('AAA')
    and 1 = (
        with function dangerous_function return number is
            pragma autonomous_transaction;
        begin
            delete from test1;
            commit;
            return 1;
        end;
        select dangerous_function from dual
    );

我做了一点作弊,上面的代码仅适用于--+ WITH_PLSQL提示。如果没有该提示,代码将抛出错误ORA-32034: unsupported use of WITH clause。但这只是未来可能解除的版本限制。或者可能有一些聪明的方法来解决它,有时提示可以突破他们的查询部分并引用其他部分。

为何会冒风险?

也许有一种安全的方法可以做到这一点。但为什么要冒风险呢? IT世界中的每个人现在都了解SQL注入错误。如果你陷入困境并导致利用,那么你就不会有同情心。