上傳目錄、靜態資源目錄 (images、attachments、uploads、static) 絕對不應允許 PHP 腳本執行,防止駭客上傳木馬後執行。Nginx 以 location 正則匹配攔截,配置簡單高效。
# nginx.conf 或 site-conf (server 區塊內)
# 禁止 attachments、images 目錄下所有 .php、.php5、.phtml 等執行
location ~* ^/(attachments|images)/.*\.(php|php5|phtml|phps)$ {
deny all;
# 可選:回傳 404 而非 403,隱藏目錄結構
# return 404;
}
# 若網站部署在子目錄 (如 /bbs/、/discuz/),需包含前綴
location ~* ^(/discuz|/bbs)/(attachments|images)/.*\.(php|php5|phtml|phps)$ {
deny all;
}
| 指令 | 說明 |
|---|---|
location ~* | 大小寫不敏感正則匹配 (支援 .PHP、.Php 等變體) |
^/(attachments|images)/ | 匹配網站根目錄下的 attachments 或 images 目錄 |
.*\.(php|php5|phtml|phps)$ | 匹配以常見 PHP 副檔名結尾的檔案 |
deny all; | 拒絕所有存取,Nginx 直接回傳 403 Forbidden |
# 定義通用上傳目錄變數 (方便維護)
# 建議在 http 區塊定義 map 或直接寫死
location ~* ^/(uploads|data|static|cache|templates|avatar)/.*\.(php|php[3-7]|phtml|phar|inc|module)$ {
deny all;
access_log off; # 不記錄存取日誌,減少噪音
}
# 針對特定框架常見上傳目錄 (Discuz, WordPress, ThinkPHP, Laravel)
location ~* ^/(wp-content/uploads|wp-includes|data/attachment|public/uploads|storage/app/public)/.*\.(php|phtml|phar)$ {
deny all;
}
echo '<?php phpinfo(); ?>' > /var/www/html/uploads/test.phphttps://yourdomain.com/uploads/test.phpreturn 404),不會顯示 phpinfo 頁面。| 誤區/風險 | 正確做法 |
|---|---|
| 只禁止 .php,駭客上傳 .php5、.phtml、.phar 繞過 | 正則包含所有常見 PHP 副檔名:php|php[3-7]|phtml|phar|pht|phps |
配置在 location ~ \.php$ 之前,導致先進入 FastCGI 處理 | 順序至關重要:禁止執行的 location 必須放在 location ~ \.php$ { fastcgi_pass ... } 之前,Nginx 依序匹配,先匹配先生效。 |
| 駭客利用解析漏洞 (如 test.jpg/.php) | Nginx fastcgi_split_path_info 配合 try_files 防禦;或升級 PHP 開啟 cgi.fix_pathinfo=0 (php.ini)。 |
| Windows IIS 環境 | IIS 請在「請求篩選」→「隱藏區段」添加上傳目錄,或設定「處理程式對應」移除該目錄的 PHP 模組對應。 |
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;
# 1. 靜態檔案直接服務
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 2. 【優先】禁止上傳/靜態目錄執行 PHP (必須在 PHP 處理塊之前)
location ~* ^/(uploads|attachments|images|data|static)/.*\.(php|php[3-7]|phtml|phar)$ {
deny all;
return 404;
}
# 3. PHP 處理
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300s;
}
# 4. 拒絕存取隱藏檔案、版本控制目錄
location ~ /\.(git|svn|env|htaccess|htpasswd) {
deny all;
}
}
# 檢查所有上傳目錄是否存在可執行 PHP 檔案
find /var/www/html -type f -name "*.php" -path "*/uploads/*" -o -path "*/attachments/*" -o -path "*/images/*" | head -20
若有輸出,表示有 PHP 檔案滲入上傳目錄,需立即刪除並排查上傳驗證邏輯。