2017-01-01 70 views
-1

我不理解有關SQL注入以及它如何工作的內容。當用戶輸入信息時,我首先開始閱讀它,然後從數據庫中選擇輸入信息與數據庫中輸入信息相匹配的數據。例如:防止選擇X語句中的SQL注入

SELECT email FROM users WHERE username=? 

現在,我明白了,你設置的參數,我是能夠成功地做到這一點,但是,我不知道是否有可能獲得SQL從「選擇電子郵件」部分注入,想象電子郵件是一個可以破壞數據庫的字符串,不應該也是一個問題?如果是這樣,是否有修復?

我希望我能很好地解釋,我的英語不是最好的,但如果你有一些我可以提供你的問題。此外,我確實試圖尋找這個問題,但不太清楚如何將其表達出來,所以我沒有找到與此類似的問題。

+0

*「我不明白,如果它有可能獲得SQL從注入的‘選擇電子郵件’部分」 * - 不,不是,除非有一個'WHERE'條款(或任何其他類型的條款)使用輸入與用戶交互沒有準備。 –

+0

理想情況下_whole_ select語句應該被參數化,所以這不應該發生。 –

+2

*「想象電子郵件是可以破壞數據庫的字符串」* - 您需要用示例編輯您的問題。現在,「email」是「你」選擇的列,而不是用戶/輸入選擇的列。如果你完成了'SELECT $ email'並且用一個GET/POST數組定義了它並且沒有轉義它(注意:你不能綁定一個表/列),但是你可以用'real_escape_string()'來轉義它,或者使用安全列表,只是沒有準備好的聲明;那麼是的,如果你沒有,那可能(可能)擊中你。我會說我回答了這個問題;恕我直言。 –

回答

0

SQL注入是一種風險,不受控制的值可能成爲查詢的一部分。在這個特定的例子中,查詢的'SELECT email'部分沒有風險,因爲email列中的值不是查詢的一部分。

這裏的一個可怕可怕例如:

var query = "SELECT email FROM users WHERE username = '" + userInput + "'" 

在該示例userInput的值變得查詢的一部分 - 用戶可以輸入「嗒嗒'; DROP TABLE用戶」,它是不會成爲好日子。但是,電子郵件列中的值不是查詢的一部分。

+0

這是一個可怕的例子,因爲它似乎是用JavaScript編寫的? – Martin

+0

請查看標籤下的問題(: – num8er

+0

是的,這些我知道這是危險的,我已經學會了如何正確使用準備好的語句,謝謝你的回答:) – Syvered

0

考慮MySQL的列名只是一個very limited subset of characters(但請看到這個答案底部的編輯),你可以很容易地連接成的SQL字符串,而是先正則表達式刪除無效字符,如:

//use single quotes due to dollar sign 
$column = preg_replace('/[a-z_-0-9$]/i','',$_POST['column']); 

然後確保它裝在一個報價:

$column = ' `'.$column.'` '; 

所以,你可以再做:

$sql = 'SELECT '.$column.' FROM users WHERE username=?'; 

然後把這個字符串放到你的綁定查詢中,這應該是完全安全的。


另外,在聲明的SELECT一部分,你只需要刪除任何東西,是一個特殊字符,也就是*.,空格和反引號operartor。

所以,你可以很容易地做到:

$column = preg_replace("/[*`.\s]/","",$_POST['column']); 

這將意味着該查詢的SELECT部分​​只能有兩個WHERE關鍵字等SELECT和濫用,這將導致查詢失敗(例如。)


順便說一句,給人以哪些列他們想打電話有很多潛力的陷阱,我沒有帶發現了它在野外很常見的一種選擇。爲什麼開發人員不清楚在選擇選項時要選擇哪些列?


編輯:您還可以使用擴展列名稱字符,這應該不會影響這種方法,但值得注意。但是,正如我上面所說的那樣,我認爲在99.999%的情況下,用戶不應該有能力命名列。

2

儘量公平地回答(真正的)問題,我不是爲了獲取代表性收益而這樣做,而是回答這個問題。

As per a comment I left:

「想象的電子郵件是可以破壞數據庫中的字符串」

眼下,電子郵件是列「你」選擇,而不是一個用戶/輸入選擇,應有任何。如果沒有用戶干預,那麼你可以使用SELECT email FROM table而沒有問題。

如果您使用了SELECT $email並使用GET/POST數組定義它並且沒有轉義它(注意:您無法綁定表/列,請參閱腳註),那麼可能會對其執行一些操作,但你可以使用MySQLi的real_escape_string()函數或使用安全列表來逃避它,但你不能用準備好的語句,句點來完成它。

SELECT ? FROM ? // is not allowed/not supported in any prepared statement API 

但是,如果查詢不涉及某種形式的WHERE where子句中變量並沒有逃脫的,那麼它就是站在被操縱,但認爲可能是最小的只是一個簡單的SELECT some_other_column_other_than_EMAIL FROM table但仍然將不足以造成任何傷害。


腳註:

相對鏈接,爲什麼你不能在一個表/列,我覺得結合是你真正想實現:

關於SQL注入: