SQL Injection 介紹與防範 PHP

  php   : 2022-01-01    : 森心    : 823

「Structured Query Language」(SQL)是用來操作資料庫、存取出所需資料的一套「查詢語言」,SQL的範圍包括數據插入、查詢、更新和刪除,數據庫模式建立和修改,以及數據存取控制。Injection 是一種駭客常用的攻擊概念,透過注入惡意的程式碼的方式,破壞原本程式碼的語意,來達到攻擊的效果。以下是一個SQL injection 的例子:

$UserID = $_GET["id"];
$SQL = "select id ,name, passwords from usertable where id = '$UserID'";

以上的是一句簡單的SQL 查詢Database內容的命令,可是黑客透過Injection的攻擊手法把你的變數改成另一個不同意思SQL 的命令。

https://website.com/page?id=-1 OR 1=1
那麼你的SQL就會變成以下的情況:
$SQL = "select id ,name, passwords from usertable where id = -1 OR 1=1;"

以上的 “-1 OR 1=1” 語句是利用SQL 中 “OR” 特性,把你資料庫內所有資料都顯示出來。 如果你沒有採取任何的防範措施那麼你的網站資料庫內容就會被黑客看光光了。

那我們應該要如何防範SQL Injection的攻擊呢? 坊間很多教學都會教人使用 str_replace、strpos 等函式偵測、過濾例如「 ‘ 」、「 ” 」、「 空白」等特殊字元,甚至是過濾關鍵字「SELECT」、「UNION」、「AND」。但這樣是不足以防範惡意的駭客,因為繞過空白、單引號的字元是十分容易的。甚至mysqli_real_escape_string 函式也不建議,因為只要在參數串入 SQL 語句之前,用此函式先將欲串入的參數作過濾,它會將所有 SQL 的關鍵字元全部替換成跳脫字元,使其在 SQL 查詢中成為普通的字串,而非語句的一部分。

比較建議定方法是從源頭著手,使用Prepared Statement:

$conn = new PDO("mysql:host=$servername;dbname=$myDB", $username, $password);
$SQL=$conn->prepare('select id ,name, passwords from usertable where id = :UserID');
$SQL->bindValue(':UserID',$UserID,PDO::PARM_INT);
$SQL->execute();

Prepared Statement 會代替 SQL 語句進行預先處理,再利用它提供的 bindValue 或 bindParam 函式將欲查詢的參數的值或變數綁定上去,底層查詢時,其參數會保證作為數值傳遞,不可能成為 SQL 語句的一部分,也因此就不會產生 SQL Injection 的問題。

※ 如果您喜歡我們的文章,能否請您幫忙點一下廣告,讓我們網站可以有點微薄的收入,得以維持網站的經營,感謝您的幫忙。
訂閱
通知
guest
0 Comments
在線回覆
查看所有的評論

跟隨我們: