首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP allow_url_include 深度解析:為何禁用它不夠,真正的防禦在哪裡?

     編輯:PHP 相關知識

背景:遠程文件包含(RFI)攻擊的核心入口

allow_url_include 與 allow_url_fopen 是 PHP 遠程文件包含漏洞的「雙子星」。早期安全建議禁用 allow_url_fopen,但這會破壞大量合法業務(如 API 調用、遠程配置拉取)。PHP 5.2.0 引入 allow_url_include 專門控制 include/require 的遠程協議支持,成為更精準的防護開關。

關鍵認知:禁用這兩個開關 ≠ 徹底安全

1. 本地文件包含(LFI)依然猖獗

攻擊者可通過 Session 文件、上傳文件、日誌注入、/proc/self/environ 等途徑將惡意代碼寫入本地文件,再利用 include $userInput 執行。遠程協議禁用不影響本地包含。

2. 特殊協議繞過:php://input、data://

即使 allow_url_include=Off、allow_url_fopen=Off,以下協議仍可被 include 使用:

<?php
// 攻擊向量 1:直接包含 POST 原始數據
include "php://input";  // 攻擊者 POST 

// 攻擊向量 2:data 協議嵌入 Base64 Payload
include "data:;base64,PD9waHAgc3lzdGVtKCdscycpOz8+"; // 解碼後為 
?>

這些協議不屬於「URL 協議」,不受上述兩個 INI 選項限制。

真正的解決方案:多層次防禦體系

第一層:代碼層面 - 消除動態包含

// ❌ 極度危險
include $_GET['page'] . '.php';

// ✅ 白名單機制
$allowed = ['home', 'about', 'contact', 'dashboard'];
$page = $_GET['page'] ?? 'home';
if (in_array($page, $allowed, true)) {
    include __DIR__ . "/pages/{$page}.php";
} else {
    include __DIR__ . '/pages/404.php';
}

第二層:配置層面 - 禁用危險協議封裝器

; php.ini
disable_functions = "exec,system,passthru,shell_exec,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source"
; 關鍵:禁用 stream_wrapper 註冊(需 Suhosin 或 PHP 7.4+ 特定補丁)
; suhosin.executor.include.whitelist = "phar"  // 僅允許 phar 協議

第三層:擴展層面 - 部署 Suhosin / Snuffleupagus

  • Suhosin:PHP 5 時代的安全擴展,可精細控制 include 白名單、加密 Cookie、限制請求參數等。
  • Snuffleupagus:現代 PHP 7+ 安全模塊,繼承並強化 Suhosin 功能,提供虛擬補丁、函數調用鏈分析、RCE 阻斷等企業級能力。

第四層:系統層面 - open_basedir + 容器化隔離

; php.ini
open_basedir = /var/www/html:/tmp:/usr/share/php

結合 Docker/K8s 容器化部署,掛載只讀代碼卷,臨時目錄掛載 noexec、nosuid,徹底切斷寫入執行鏈。

總結:安全無銀彈,纵深防御才是王道

allow_url_include=Off 是必要的基線配置,但絕非充分條件。真正的防禦體系需覆蓋:代碼審計消除動態包含 → 禁用危險函數/協議 → 部署安全擴展 → 系統級隔離。每一層都能獨立攔截攻擊,組合起來才能構建韌性防線。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved