2013-04-29 109 views
30

我已經構建了一個即將上線的網站,只是有一些關於防止SQL注入的問題,我知道如何使用mysqli_real_escape_string,但我只是想知道是否必須使用它所有變量,我得到我的SQL語句,我必須使用它,當我做選擇語句也只是在插入更新和刪除?還有什麼其他安全性,你會建議我實施之前,我把網站的生活,預先感謝任何幫助!PHP MySQLI阻止SQL注入

+2

我的問題是與'mysqli_real_escape_string'有關你提到的問題是關於SQL注入的一般... – user2201765 2013-04-29 15:28:08

+1

這個問題不應該被關閉。這是mysqli特有的,並且在審查員提供的鏈接中沒有回答。 – 2015-07-21 06:16:12

+1

@JG Estiot - 說得太多肛門編碼器 - 傢伙需要幫助 - 所以幫助他,有時會花費更少的努力來回答,而不是解釋爲什麼你不想回答!我同意你 – kerry 2016-09-17 01:47:06

回答

35

無論是讀取還是寫入,持久性還是瞬態,都可以注入任何查詢。可以通過結束一個查詢並單獨運行一個查詢(可能與mysqli)來執行注入,這會使預期的查詢不相關。

對來自外部源的查詢的任何輸入(無論是來自用戶還是來自內部的)都應該被視爲查詢的參數,以及查詢上下文中的參數。查詢中的任何參數都需要參數化。這導致了一個正確的參數化查詢,您可以創建一個準備好的語句並使用參數執行。例如:

SELECT col1 FROM t1 WHERE col2 = ? 

?是參數的佔位符。使用mysqli,可以使用prepare創建預準備語句,使用bind_param將變量(參數)綁定到參數,然後使用execute運行查詢。根本沒有必要清理論證(實際上這樣做是不利的)。 mysqli是爲你做的。全過程是:

$stmt = mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?"); 
$stmt->bind_param("s", $col2_arg); 
$stmt->execute(); 

還有參數化查詢事先準備好的聲明之間的一個重要區別。這種說法,而準備的,是不是參數,因此容易注入:

$stmt = mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])"); 

總結:

  • 所有查詢應適當參數(除非他們有沒有參數)
  • 全部查詢的參數應該被視爲敵對,無論它們的來源如何
+0

這將是很好的展示如何使用這些神奇的語句與IN或SET子句與任意數量的元素。否則,它將更像電視廣告 - 易於在屏幕上顯示,但在家中無法使用。 – 2013-04-29 15:19:59

+0

@YourCommonSense我認爲這有點超出了這個問題的範圍,但我傾向於做這樣的答案:http://stackoverflow.com/a/10698906/454533 – 2013-04-29 15:22:14

+0

謝謝你的非常詳細的答案!這似乎是一個比使用'mysqli_real_escape_string'更好的解決方案,我會對此稍加考慮,然後實現它,非常感謝! – user2201765 2013-04-29 15:23:10

4

它會在幾秒鐘內關閉,而只是爲了讓事情直

我知道如何使用mysqli_real_escape_string

恐怕你不是。

,如果我不得不使用上我得到了我的SQL語句

絕對不是所有的變量。
此功能,必須使用格式化SQL字符串只有

我不得不使用它,當我在做選擇語句也或者只是在插入更新和刪除?

ANY SQL語句。但同樣,沒有「使用mysqli_real_escape_string」,但完全格式化你的文字和正確

還什麼其他的安全,你會推薦

關於SQL安全 - 你必須正確地格式化不僅串但文字任何種。並且每個都需要不同的一組格式化規則

+2

這不是一個答案,請刪除它。至於它的自我功能,我知道如何使用它,我只是不需要使用它的所有東西。 – user2201765 2013-04-29 15:11:57

+0

請改善這個答案。什麼意思是「你必須正確格式化...」。給出的例子或規則或什麼... – Chiwda 2018-03-09 03:37:11

+0

@Chiwda它在這裏:https://phpdelusions.net/sql_injection#formatting – 2018-03-09 05:10:47