最有效阻止惡意破壞的方法是在開發階段預判風險,而非事後修補。以下以簡化檔案寫入的函數為例,說明潛在隱患。
<?php
function write_text($filename, $text = "") {
static $open_files = array();
if ($filename == NULL) {
foreach ($open_files as $fr) fclose($fr);
return true;
}
$index = md5($filename);
if (!isset($open_files[$index])) {
$open_files[$index] = fopen($filename, "a+");
if (!$open_files[$index]) return false;
}
fputs($open_files[$index], $text);
return true;
}
?>
前端表單 quotes.php 允許用戶提交引言並儲存:
<form action="" method="get">
選擇類別: <select name="quote">
<option value="funny">幽默</option>
<option value="political">政治</option>
<option value="love">愛情</option>
</select><br>
內容: <input type="text" name="quote_text" size="30">
<input type="submit" value="儲存">
</form>
<?php
include_once('write_text.php');
$filename = "/home/web/quotes/{$_GET['quote']}"; // 直接帶入用戶輸入!
$quote_msg = $_GET['quote_text'];
if (write_text($filename, $quote_msg)) {
echo "引言已儲存!";
} else {
echo "寫入失敗";
}
write_text(NULL);
?>
quote=../../etc/passwd 可寫入系統敏感檔案。NULL byte(PHP < 5.3.4)可截斷副檔名限制。quote 是否為預期值(funny/political/love)。if (!in_array($_GET['quote'], array('funny','political','love'))) die('非法類別');$filename = realpath("/home/web/quotes/" . basename($_GET['quote'])); 確保在預期目錄下。display_errors = Off,記錄至日誌。htmlspecialchars() 防 XSS。安全不是功能,而是開發流程的一部分。每個變數進入系統前都要問:來源?預期格式?邊界條件?如何失敗?