2015-04-21 85 views
2

下面的查询在我的程序中被执行,其中“a”是参数值,我将其作为输入&在查询中传递它。带有函数调用的SQL注入

select * from emp where name LIKE LOWER('%a%') 

有人可以告诉我,我可以对上面的查询执行SQL注入攻击还是安全?

我看到SQL注入与条款&类似的运算符,但我们也可以通过函数调用来实现。我可以通过什么来代替SQL注入的'a'。

我正在使用PL/SQL编辑器& Oracle DB。

+1

你是如何“通过查询”?用你的参数替换“a”并将结果字符串传递给Oracle?还有别的吗? – Mat

回答

1

一个可以

1') or 1 = 1 or LIKE LOWER('1 

你应该确保作为传递的值是干净的,也许在剥离斜线。

+0

我收到上述语句的语法错误。 ORA-01756:引用的字符串未正确终止 –

+0

对不起,在最后1 = 1之后,应该有LIKE LOWER('1'之前“使a =”1“)或1 = 1或LIKE LOWER('1”; – Chuksy

+0

仍然可以没有得到它,请你给我完整的SQL语句,以便有一些SQL越过内部函数 –

3

当您的应用程序与环境(其他程序或用户)交互并使用字符串连接组装来自零件的SQL查询时,SQL注入的风险就会出现。例如,您可以编写PL/SQL过程:

create or replace procedure myproc(a varchar2) is 
    sql_str varchar2(4000); 
    sql_result number; 
begin 
    execute immediate 'select count(*) from mytable where mycolumn = ' || a into sql_result; 
end; 

此过程易受攻击。你可以传递字符串''abc''' or 1 = 1或类似的东西,它会扭曲结果(或使事情变得更糟)。
或者你可以写这样的:

create or replace procedure myproc(a varchar2) is 
    sql_str varchar2(4000); 
    sql_result number; 
begin 
    execute immediate 'select count(*) from mytable where mycolumn = :A' using a into sql_result; 
end; 

而且这个过程是不容易。
你也可以写

create or replace procedure myproc(a varchar2) is 
    sql_str varchar2(4000); 
    sql_result number; 
begin 
    select count(*) 
    into sql_result 
    from mytable 
    where mycolumn = a; 
end; 

这是没有问题的话,那是最安全的方式(这是“静态SQL”),但有时我们需要动态SQL(像前两个例子)。
为什么第一种方式不好,第二种方式很好?这是因为SQL引擎编译查询几乎和其他编译器编译它们的代码一样,例如C++。 SQL引擎将查询编译为“程序”并在此“程序”中定义可能的“变量”。第二个程序中的“变量”是参数:A。如果查询包含“变量”,引擎会询问它们的值(USING子句)并将它们传递到编译查询中。在第一种情况下的发动机被连接字符串:

select count(*) from mytable where mycolumn = 'abc' or 1 = 1 

认为它像一个整体“方案”,并执行“原样”。在第二种情况下发动机获取字符串

select count(*) from mytable where mycolumn = :A 

编译它,定义1“可变的” A并询问它的值,然后将其传递给一个“节目”,而“节目”只是搜索在mycolumn列值'abc' or 1 = 1。这不仅适用于PL/SQL代码中的动态SQL。它在任何语言中的工作方式都是一样的,所有流行的框架(对于java,c#,delphi等)和所有流行的DBMS都提供了安全工作的工具,如第二个示例。
当然,这是简化的例子,有时后果可能会更糟糕。

1

您几乎可以在任何地方利用SQL注入。 结帐我的白皮书,谷歌“SQL注入任何地方”,演示注入奇怪的地方 - 包括函数调用。