2011-10-14 64 views
3

如何基於我接收的參數構造查詢?我想添加到查詢的末尾。在過程中加入2個字符串作爲查詢

我想是這樣的,但它沒有工作:

DELIMITER $$ 
CREATE PROCEDURE `get_users`(IN sortstring TEXT) 
BEGIN 
PREPARE statement FROM 
"SELECT username, password FROM users ?"; 
SET @param = sortstring; 
EXECUTE statement USING @param; 
END$$ 

而且我會傳遞給sortstring類似:

ORDER BY username DESC 

我能做到用CONCAT或某事,這更簡單?

+1

總得跑,但看看這裏:http://forums.mysql.com/read.php?6041372,47813 – MatBailie

+0

@Dems謝謝。你能發表一篇文章嗎?我可以把它標記爲正確的答案。 – Monokh

+0

確保你知道使用這樣的代碼時「SQL注入」是什麼。 –

回答

2

您需要解構sortstring並將其所有部分與允許的術語列入白名單。

請參閱以下僞代碼。我還沒有完全測試它,但讓我們說這是重要的想法。

DELIMITER $$ 

CREATE PROCEDURE `get_users`(IN sortstring TEXT) 
BEGIN 
    //check sortstring against a whitelist of allowed sortstrings 
    DECLARE sortpart VARCHAR(255); 
    DECLARE done BOOLEAN DEFAULT false; 
    DECLARE allok BOOLEAN DEFAULT true; 
    DECLARE i INTEGER DEFAULT 1; 

    WHILE ((NOT done) AND allOK) DO 
    SET sortpart = SUBSTRING_INDEX(sortstring,',',i); 
    SET i = i + 1; 
    SET done = (sortpart IS NULL); 
    IF NOT DONE THEN 
     SELECT 1 INTO allok WHERE EXISTS 
     (SELECT 1 FROM whitelist 
     WHERE allowed_sort_claused = sortpart AND tablename = 'users'); 
    END IF 
    END WHILE; 
    IF allOK THEN  
    PREPARE statement FROM 
     CONCAT('SELECT username, passhashwithsalt FROM users ',sortstring); 
    EXECUTE statement; 
    DEALLOCATE PREPARE statement; 
    ELSE SELECT 'error' as username, 'error' as passhashwithsalt; 
    END IF; 

END$$ 

參見:How to prevent SQL injection with dynamic tablenames?

錯誤在你的代碼
不能使用COLUMNNAMES或SQL的關鍵字作爲參數。您只能使用值作爲參數。出於這個原因,你的查詢永遠不會通過準備。
?SELECT x FROM t1 ?只會被替換爲SELECT x FROM t1 'ORDER BY field1, field2'這是沒有意義的。