4-7
讀出資料的過濾
一、避免攻擊
- 請在標題輸入框分別輸入底下內容試試(XSS攻擊),若是無法順利寫入,那就是有問題:
<img src="https://www.fairworkcenter.org/wp-content/uploads/2018/04/hacked-skull.jpg">
或
<script>alert('這就是XSS攻擊')</script>
- 當我們將讀出資料,就會出現被攻擊訊息
- 是否有方法可以避免之?有的,就是讀出變數需要過濾。
- 讀出的資料,要先考量該變數(或欄位)是否允許使用HTML
- 但內建的 htmlspecialchars($string) 預設只轉化雙引號,不對單引號做轉義,所以,這樣用
htmlspecialchars($string,ENT_QUOTES)
更好:
echo "<li>" . htmlspecialchars($row['title'], ENT_QUOTES) . "</li>";
另一個和 htmlspecialchars
很像的 htmlentities 函數並不適用中文,因為會連同中文字一起轉義。
二、過濾數字
- 一般過濾數字用
(int) $xxx
或 intval($xxx)
即可,會強制把輸入的內容變成數字。
$num = "123其他文字456";
echo (int) $num . "<br>";
echo intval($num) . "<br>";
-
用 (int) $xxx
或 intval($xxx)
會得到 123,但用filter_var()
會得到 123456
三、將所有讀出的變數進行過濾
- 例如:
foreach ($news as $row) {
echo (int) $row['id'] . "<br>";
echo htmlspecialchars($row['title']) . "<br>";
echo htmlspecialchars($row['author']) . "<br>";
echo htmlspecialchars($news['date']) . "<br>";
echo (int) $row['counter'] . "<br>";
echo htmlspecialchars($row['content']) . "<br>";
echo htmlspecialchars($row['category']) . "<br>";
}
-
這樣有點太辛苦,萬一日後欄位有異動,還得手動加,所以,我們利用 array_map()
來自動進行處理:
foreach ($news as $row) {
// 在過濾每一筆資料
$row = array_map('htmlspecialchars', $row);
echo "<li>{$row['title']}</li>";
}
-
如此,就可以看到一些 XSS 攻擊被擋掉了,只出現語法: