簡體   English   中英

在SQL注入中,存儲過程中的預准備語句是否安全?

[英]Is a prepared statement inside a stored procedure safe from SQL injection?

在MySQL中,是一個從SQL注入安全的存儲過程中准備好的語句嗎? 見下面的例子。 get_info存儲過程傳遞一個表名(pTbl)和where子句(pWhere)。 p可以有多個AND(例如fld1 =“a”AND fld2 =“b”AND ...)。 它可能不是最好的方法,但我需要動態的SQL。

CREATE PROCEDURE get_info(pTbl VARCHAR(10), pWhere TEXT)
BEGIN
    SET @uSQL = CONCAT('SELECT info FROM ',pTbl,' WHERE ',pWhere);
    PREPARE ps FROM @uSQL;
    EXECUTE ps;
END$$

我嘗試使用MySQL查詢瀏覽器調用下面的存儲過程但只返回錯誤,說我的SQL中有語法錯誤。

CALL get_info('tbl','1=1;SELECT * FROM information_schema.TABLES;');

如果它有助於使用PDO從PHP調用任何存儲過程,如下所示。 $ tbl是$ _SESSION變量,$ whr是$ _GET變量。

$s=$c->prepare("CALL get_info(?,?)");
$s->execute(array($tbl,$whr));

這個存儲過程安全嗎? 如果沒有,我將如何注射它? 如果我從MySQL查詢瀏覽器注入到網頁,它會有所作為嗎? 謝謝...

是的,這是安全的。 (編輯:不,不是)

關鍵是要知道SQL文本何時被分析並轉換為語義樹。 准備好的語句就是:准備好的語句,只是等待參數。 它們存儲在完全編譯到內部執行計划的服務器中,缺少參數的“漏洞”。

這就是為什么你得到語法錯誤,你試圖將整個WHERE部分設置為參數; 但它是一個完整的表達樹。 准備好的語句只能有數據元素的“漏洞”,而不能用於語法文本。

傳遞參數的協議是完全二進制安全的,無論你在參數變量中有什么,它們都將作為二進制數據發送並僅用作數據,而不是作為SQL命令的一部分。

編輯 ooops! 我剛剛注意到,你做文字插值,只是沒有在PHP,但SQL。 這意味着您將在以后使用外部數據構建S​​QL命令。

絕對不安全。

由於其中一個值來自用戶,因此可以使用某些形式的SQL注入; 雖然只能運行SELECT查詢,但仍然可以通過將1=1傳遞給頁面來顯示信息。 以這種方式顯示的信息的實際有用性可能很低,但它仍然可能發生。

只要將值插入到語句中,就有可能注入。 該程序很脆弱。 SQL過程和函數中注入的唯一一般限制是PREPARE在單個語句上工作。 在這種特定情況下,注入的文本在SELECTWHERE子句之后基本上限制了對子選擇, UNION ,調用過程和函數(棘手但可能非常危險)的攻擊,並轉儲到文件(如果get_info的定義者有FILE特權)。

例如,嘗試:

CALL get_info('tbl','1=0 UNION SELECT CONCAT(user, "@", host, " ", password) FROM mysql.user;');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM