<?php
$js = explode(',', $_GET['js']);
foreach ($js as $file) {
echo file_get_contents('./public/js/' . $file . '.js') . "\n";
}
風險:攻擊者可傳入 js=../../etc/passwd%00(舊版 PHP null byte 攻擊)或 js=../../config.php 嘗試讀取任意檔案。即使強制附加 .js,若系統允許 phar://、data:// 等封裝協定,仍可能繞過。
<?php
$js_param = $_GET['js'] ?? '';
$allowed_files = ['jquery', 'bootstrap', 'vue', 'axios', 'lodash']; // 白名單
$js_list = array_map('trim', explode(',', $js_param));
$output = '';
foreach ($js_list as $file) {
// 1. 僅允許英數字、底線、連字號
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $file)) {
continue; // 或記錄日誌、回傳 400
}
// 2. 白名單二次確認
if (!in_array($file, $allowed_files, true)) {
continue;
}
$path = __DIR__ . '/public/js/' . $file . '.js';
// 3. 確認檔案存在且在允許目錄內(防目錄穿越)
$real_base = realpath(__DIR__ . '/public/js');
$real_file = realpath($path);
if ($real_file && str_starts_with($real_file, $real_base) && is_file($real_file)) {
$output .= file_get_contents($real_file) . "\n";
}
}
header('Content-Type: application/javascript; charset=UTF-8');
echo $output;
| 層面 | 措施 |
|---|---|
| 輸入驗證 | 正則限制字元、白名單機制 |
| 路徑解析 | realpath() 取得真實路徑,str_starts_with() 確認在基底目錄內 |
| 錯誤處理 | 靜默忽略非法檔案,不洩露路徑資訊 |
| 效能優化 | 生產環境應預先合併壓縮(Webpack/Vite),動態讀檔僅供開發/特殊場景 |
| 快取 | 輸出 ETag、Cache-Control、Content-Type: application/javascript |
動態讀取並輸出 JS 檔案極高風險,務必實施「白名單 + 路徑真實性驗證」。長遠來看,導入前端建構工具徹底移除此類伺服端邏輯,才是安全與效能的最佳解。