2015-04-21 31 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注入任何地方」,演示注入奇怪的地方 - 包括函數調用。