從 PHP 學習權限管理的重要性

資訊安全不可疏忽。

簡述

這裡想強調「看不到不代表摸不到」的概念。在實作編輯與刪除留言時,為了管理權限,我們在渲染畫面的時候多加一個判斷是只有自己的留言才會顯示編輯跟刪除的按鈕,像這樣:

demo

火山矽肺病只有在自己登入後才可以編輯或刪除自己的留言。

雖然畫面上表面上看起來沒什麼問題,但其實這背後存在一個漏洞,等等讓我們繼續看下去。

你想不到的神展開

這裡就不賣關子了,直接讓你看有什麼漏洞。

  1. 刪除別人的留言:

delete

  1. 修改別人的留言:

update

發現問題

為什麼會這樣?這得看一下我們是怎麼實作編輯與刪除功能的。

編輯留言:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// handle_update_comment.php
<?php
require_once('./conn.php');
// 拿到要修改的留言 id
$id= $_POST['id'];
// 留言的內容
$content = $_POST['content'];
// 下指令更新 id=? 的留言內容
$sql = "UPDATE comments SET content=? WHERE id=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('si', $content, $id);
$stmt->execute();
header('Location: ./index.php');
?>

刪除留言:

1
2
3
4
5
6
7
8
9
10
11
12
// hande_delete_comment.php
<?php
require_once('./conn.php');
// 拿到要刪除的留言 id
$id= $_GET['id'];
// 下指令把 id=? 的留言刪掉
$sql = "UPDATE comments SET is_deleted=1 WHERE id=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
header('Location: ./index.php');
?>

注意到問題了嗎?這兩段程式完全沒有做權限檢查

為什麼一開始要強調「看不到不代表摸不到」?因為這就是問題所在,就算我讓前端畫面看起來不能動別人的留言,但我還是可以用「網址」發一個 GET 請求到後端,讓後端執行對應指令。

解決問題

所以正確的作法應該是後端也要做權限檢查,既然已經有登入機制,那在做編輯、刪除或新增等等的資料時都應該要像登入一樣用 session 機制確保是使用者本人,才可以執行對應行為。

所以把剛剛的程式碼修改一下。

刪除留言:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// hande_delete_comment.php
<?php
require_once('./conn.php');
// 加上 session 機制
session_start();
$id= $_GET['id'];
$username = $_SESSION['username'];
// 加上 AND 來判斷 username 是否正確
$sql = "UPDATE comments SET is_deleted=1 WHERE id=? AND username=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('is', $id, $username);
$stmt->execute();

header('Location: ./index.php');
?>

fix-delete

編輯留言:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
require_once('./conn.php');
// 加上 session 機制
session_start();
$id= $_POST['id'];
$content = $_POST['content'];
$username = $_SESSION['username'];

// 加上 AND 來判斷 username 是否正確
$sql = "UPDATE comments SET content=? WHERE id=? AND username=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('sis', $content, $id, $username);
$stmt->execute();

header('Location: ./index.php');
?>

fix-update

後記

在做完這個 case 後體會到原來有些事情不是「單靠前端」就能解決的。像是表單驗證,即便前端先檢查過後端也要再檢查一次。為什麼?因為使用者很多時候可以繞過前端的檢查,直接向後端發 request,如果這時候後端沒有做檢查呢?那就挫咧但了。所以比起前端,後端更需要具備資訊安全的知識,這一點真的很重要,很重要。

用 PHP 做一個最基本的 API 用 PHP 實作分頁功能
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×