2014-03-30 112 views
2

所以,你必須爲什麼不使用CONCAT()作爲靜態字符串文字?

$sql = "SELECT * FROM `table` WHERE `some_text_field` LIKE CONCAT('%', ?, '%')"; 
$stmt = $dbh->prepare($sql); 
$stmt->execute(array($_POST['badies_code'])); 

而且看着另一個問題,我發現,這會導致安全問題,但爲什麼呢?

我發現這個問題,一個downvoted回答和upvoted評論這就是爲什麼我問

的評論稱

這不是做到這一點的正確方法。你不應該爲三個靜態字符串文字使用CONCAT(),因爲它會打開你一個特定類型的SQL注入(我忘了名字)。 - 西奧多·R·史密斯

PHP PDO prepared statement -- mysql LIKE query

回答

1

我覺得@ TheodoreR.Smith可能意味着是所謂橫向SQL注入在Oracle數據庫[1][2]

它的工作原理,通過改變環境變量保持格式的信息,例如NLS_DATE_FORMAT,或NLS_NUMERIC_CHARACTERS,然後將其在建立並動態地執行一個語句的存儲過程中使用(這是字符串連接時,由||運營商表示) :

CREATE OR REPLACE PROCEDURE date_proc IS 
    stmt VARCHAR2(200); 
    v_date DATE := SYSDATE; 
BEGIN 
    stmt := 'select object_name from all_objects where created = ''' || v_date || ''''; 
    EXECUTE IMMEDIATE stmt; 
END; 

這裏SYSDATE返回在NLS_DATE_FORMAT指定格式的當前日期。雖然過程沒有參數,更改日期格式類似' or 1=1--

ALTER SESSION SET NLS_DATE_FORMAT = ''' or 1=1--' 

得到的說法是:

select object_name from all_objects where created = '' or 1=1--' 

此環境變量的操作是針對Oracle數據庫。再次,它可以通過使用預準備語句來緩解:

CREATE OR REPLACE PROCEDURE date_proc IS 
    stmt VARCHAR2(200); 
    v_date DATE := SYSDATE; 
BEGIN 
    stmt := 'select object_name from all_objects where created = :date'; 
    EXEC SQL PREPARE prepared_stmt FROM :stmt; 
    EXEC SQL EXECUTE prepared_stmt USING :v_date; 
end; 

我不知道MySQL是否傾向於這種環境變量操作。

但是,如果沒有正確處理,動態構建語句就會傾向於SQL注入,無論它是在應用程序還是在數據庫中發生。因此,在存儲過程中使用prepared statements也是必需的。

2

這將是一個相當複雜的任務,要記住注入不存在的名稱。

使用concat()和準備好的語句沒有什麼不對。

+0

當您使用術語「故意」和「嚴格」時,您可以擴展您的意思嗎?謝謝 – Victory

+0

嚴格意味着嚴格,當你需要確切的價值來匹配給定的。故意意味着故意的部分匹配。無論如何,這只是我的猜測,試圖解釋這種不存在的「注射」的想法。 –

+0

你對Gumbo的反應有什麼看法? – Victory

相關問題