iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
自我挑戰組

大學 50 萬貸款的交代系列 第 22

Day 22 怕啦.SQL Injection -2 Σ( ° △ °)

  • 分享至 

  • xImage
  •  

在 Day 21 我們提到 SQL Injection 的概念,在 Day 22 我們來挖一個洞吧,畢竟知道怎麼挖洞才會意識到洞長什麼樣子嘛

首先,先做出一個超簡易的表單

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <form method="post" action="test.php">
    <label for="ID">帳號</label>
    <input type="text" name="ID"><br>
    <input type="submit" name="submit">
  </form>
</body>
</html>

再來做出一個接收表單的 PHP

<?php

$UserID = $_POST["ID"];

$sql = "SELECT * FROM account WHERE UserID ='$UserID' ";

$mysqli = mysqli_connect("localhost","root","","foo");

$result = mysqli_query( $mysqli,$sql );
if($result)
	echo "哈囉!";
else
	echo "這裡不歡迎你";
?>

這樣一個漏洞就做好囉

我們來試一下,先看一下資料庫有哪些資料

試著輸入其中一個 UserID 進表單中

會得到這樣的結果

如果今天的輸入是這樣呢

這樣也是可以通過檢查的喔

如果套到程式碼中會比較容易理解發生什麼事情,我們程式中的 SQL 語法長這樣
SELECT * FROM account WHERE UserID ='$UserID'
把輸入的句子套到$UserID變這樣
SELECT * FROM account WHERE UserID ='1' OR '1' ='1'
WHERE 後面的條件恆成立,所以等於這樣
SELECT * FROM account
如果這部分的查詢是可以撈出一些資料的話,那所有資料都被看光光囉

應該怎麼防

只要是使用者輸入的內容都應該額外檢查與防護,因此使用者輸入的值要藉由 binding 的方式填入比較安全。

<?php

$UserID = $_POST["ID"];

$sql = "SELECT * FROM account WHERE UserID =? ";

$db = new mysqli('127.0.0.1', 'root', '', 'foo');
$stmt = $db->prepare($sql);
$stmt->bind_param('s',$UserID,);
$stmt->execute();

if($stmt->affected_rows === 1)
	echo "哈囉!$UserID";
else
	echo "這裡不歡迎你";

?>

一樣輸入攻擊語句,這次就沒有效果了,因為 bind_param 不會把單引號和雙引號當成指令的一部份,而是要查詢的內容。


上一篇
Day 21 怕啦.SQL Injection Σ( ° △ °)
下一篇
Day 23 怕啦.Command Injection Σ( ° △ °)
系列文
大學 50 萬貸款的交代30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言