這次要筆記的是我自己覺得跟 XSS 原理超級像的 SQL Injection,就直接奉上它的原理以及預防方式:
SQL Injection 原理
它的原理就是在輸入字元中夾帶 SQL 指令,舉一個最經典例子,當網頁的 SQL 是使用字串拼接的方式撰寫,並且在帳號密碼驗證時使用以下指令:
// php 語法中的字串拼接
sql = printf(
"SELECT * FROM users WHERE username = '%s' AND password = '%s'",
$username,
$password);
將接收到的變數接在 SQL 指令中,當我們以為一切沒有問題的時候,如果使用者輸入惡意的指令例如在 $username 中輸入:name'#
,就會讓 SQL 指令在拼湊後變成:
sql = "SELECT * FROM users WHERE username = 'name'#' AND password = 'password'";
其中 #
在 SQL 語法中代表註解的意思,也就是在判斷資料的時候,只會判斷帳號,密碼的判斷將會直接被省略,所以儘管自己在撰寫密碼驗證做得多嚴謹,只要惡意使用者知道他人的帳號都可以隨意冒充。
防範方式
要防範這樣子的攻擊,其實就是換一種字串拼接的方法,可以使用 prepared statement,
利用以上的程式進行改寫如下:
$sql = "SELECT * FROM users WHERE username=? AND password=?";
// 先把原先的指令準備好
$stmt = $conn->prepare($sql);
// 帶入輸入值
$stmt->bind_param("ss", $username, $password);
// 只看有沒有執行成功
$result = $stmt->execute();
if(!$result) {
die($conn->error);
}
// 拿到執行結果
$result = $stmt->get_result();