2014-06-26 45 views
0

我用流動閱讀大量的論壇和答案對堆棧關於SQL注入如何Mysqli_escape_string或預處理語句可以從SQL注入

救我,我才知道這是SQL注入的非常基本的水平

$_POST['name'] = 'xyz;DROP Table users'; 
    mysqli_query ('select * from abc where name='."$_POST['name']") 

爲了防止對來自用戶可以把我從SQL注入任何輸入這個

  1. 使用mysqli_escape_stirng
  2. 使用PDO和準備語句也可以幫助我從SQL注入中解脫出來

Q1。我想了解的內容如何將數據傳遞到Mysqli_escape_string能救我從SQL注入

$safe_variable = mysqli_escape_String($connection ,$_POST['name']; 

如何mysqli_escape_string只會從POST數據保存「XYZ」,離開了剩下的部分(如果是這樣的話) Q2302。如何PDO將

$stmt = $dbh->prepare("select * from ABC where name = :name"); 
    $stmt->bindParam(':name',$name); 
    $name = $_POST['name']; 
    $stmt->execute(); 

任何幫助挽救我的SQL注入他在這方面的高度讚賞

回答

1

Q1:

MySQL的(我)_real_escape_string()調用MySQL的庫函數 MySQL的(我)_real_escape_string,其中前添加反斜槓以下 字符:\x00\n\r\'"\x1a

http://php.net/mysqli_real_escape_string

注意,這依賴於字符編碼(在這種情況下幹活是SET NAMES ...(安全風險!),$mysqli->set_charset('utf8');應使用!)。 (您可以在我的帖子Mastering UTF-8 encoding in PHP and MySQL中閱讀關於編碼的內容。)

它如何防止SQL注入? - 那麼它可以防止通過轉義'等破變量情況下,事情是,mysql_querymysqli_query只執行每一個查詢查詢,這意味着,它只是忽略;DROP Table users

mysqli_real_escape_string是不是防止插入像DROP DATABASE這樣的代碼。

在這種情況下,只有PDO和/或mysqli_multi_query易受攻擊。

Q2:

聲明不被髮送到服務器,然後再綁定變量將被髮送分隔,然後將聲明得到執行,在這種情況下,安全性是由數據庫庫提供,客戶端庫。你應該優先考慮這一點。

也就是說,你先送$dbh->prepare("select * from ABC where name = :name");到服務器和數據庫知道您綁定PARAM會被插入到:name佔位符,它會自動妥善包裹,不會打破其所謂的上下文的。數據庫將嘗試查找的name值,並且它不會執行任何命令,只需填充該變量空間即可。

+0

謝謝DAN,完全覆蓋的第一部分與你說的綁定變量有關的第二個問題的問題在我的情況下分開發送,如果變量具有這個值「xyz; DROP Table ABC」,PDO將如何防止這種情況? – ahmad05

+0

@ ahmad05我加了一段希望解釋的話。 – DanFromGermany

+0

在非專業術語中,它只會填充:名稱與「XYZ」並保留其餘部分並執行查詢...或者根本不會執行查詢? – ahmad05

1

我想這是大多數SQL轉義功能的情況下:

他們逃脫控制字符像;'",...

所以你的字符串

xyz;DROP Table users 

將由函數逃到

xyz\;DROP Table users 

所以您的字符串,現在是不是一個有效的SQL命令了。

但要注意存儲在數據庫中的數據中的HTML標籤。

如果我插入例如

<script>alert('foobar');</script> 

這將被存儲在數據庫,而不是由SQL轉義處理功能。如果您再次打印該字段,則JS將由訪問者瀏覽器執行。

因此用於添加htmlspecialchars()htmlentities()用於消毒用戶輸入。準備好的陳述也是如此。

+0

這個回答他的問題的方式是什麼? – Gumbo

+0

因爲他在詢問SQL轉義函數和perepared語句如何處理他的樣本值'xyz; DROP Table users' – TiMESPLiNTER

+1

它回答Q1。第二季度的答案是,該聲明和值將以不同的數據包發送到數據庫並分開解析/執行。 – DanFromGermany

3

將用戶輸入合併到SQL中的問題是,在生成的SQL中,您無法確定哪些部分是由開發人員提供的,哪些由用戶提供。這就是爲什麼開發人員必須確保用戶輸入按照預期進行解釋。

這是串逸出功能參數進來:

字符串逸出功能mysqli_real_escape_string過程,以便它可以在一個string literal被安全地使用而不必擔心其可被解釋爲值除了字符串數據以外的其他東

但是,重要的是要注意,該值實際上放置在字符串文字和其他地方,因爲它僅用於特定目的,即i。即,它確保傳遞的數據僅在放置在字符串文字中時才被解釋爲字符串數據。不幸的是,PHP手冊沒有提到字符串文字部分。

參數化由預處理語句實現,將SQL和數據參數分開。所以不能混淆SQL代碼和提供的數據。使用服務器端預處理語句首先準備好的語句只有參數佔位符,然後傳遞參數值以執行。只要遇到參數,DBMS就會使用相應的參數值。


至於你具體的例子:

我想在這裏知道如何將數據傳遞到Mysqli_escape_string能救我從SQL注入什麼

$safe_variable = mysqli_escape_String($connection ,$_POST['name']; 

如何mysqli_escape_string只保存「 XYZ「,並留下該部分的其餘部分(如果是這種情況)

它並不是因爲您沒有將值放入字符串文字中。但是,以下將工作:

mysqli_query("select * from abc where name='$safe_variable'") 


如何PDO會來救我從SQL注入

$stmt = $dbh->prepare("select * from ABC where name = :name"); 
    $stmt->bindParam(':name',$name); 
    $name = $_POST['name']; 
    $stmt->execute(); 

前面已經說過,您明確指出哪些SQL外觀比如通過準備聲明。然後你傳遞參數執行。由於參數化的SQL及其參數是分開的,它們不會混合,並且傳遞的參數值不能被誤認爲是SQL。