隐藏 PHP
隐藏 PHP 的存在可以减少攻击面,使攻击者难以识别服务器技术栈。虽然隐藏 PHP 不能替代真正的安全措施,但作为纵深防御的一部分,可以有效降低自动化扫描工具的识别率。本节讲解隐藏 PHP 版本信息、文件扩展名伪装和 Web 服务器配置等技巧。
基础概念
为什么要隐藏 PHP
| 原因 | 说明 |
|---|---|
| 减少攻击面 | 攻击者不知道使用 PHP,就不会尝试 PHP 特定的攻击 |
| 防止自动化扫描 | 扫描工具通常基于已知签名识别技术栈 |
| 增加攻击难度 | 攻击者需要额外时间识别目标 |
| 信息泄露防护 | 版本信息可能暴露已知漏洞 |
重要提醒
隐藏 PHP 只是辅助手段,不能替代真正的安全措施。即使完全隐藏了 PHP,如果代码存在漏洞,攻击者仍然可以利用。安全来自好的编码实践,而非隐藏技术。
隐藏 PHP 版本信息
expose_php 配置
ini
; php.ini
expose_php = Offphp
<?php
// 运行时设置
ini_set('expose_php', '0');
// 移除已设置的 X-Powered-By 头
header_remove('X-Powered-By');Web 服务器隐藏
apache
# Apache httpd.conf 或 .htaccess
# 隐藏 Apache 版本
ServerTokens Prod
ServerSignature Off
# 移除 PHP 签名
<IfModule mod_php5.c>
php_value expose_php Off
</IfModule>nginx
# nginx.conf
# 隐藏 Nginx 版本
server_tokens off;
# 移除 PHP 签名
fastcgi_hide_header X-Powered-By;移除其他信息泄露头
php
<?php
declare(strict_types=1);
/**
* 移除所有信息泄露头
*/
function removeInformationHeaders(): void
{
// PHP 签名
header_remove('X-Powered-By');
// 服务器签名(可能由 Web 服务器设置)
// header_remove('Server'); // 通常无法移除,需在 Web 服务器配置
// 其他可能的签名
header_remove('X-AspNet-Version');
header_remove('X-AspNetMvc-Version');
// 确保不在代码中添加自定义签名头
}文件扩展名伪装
使用 .html 扩展名解析 PHP
apache
# Apache 配置
<FilesMatch "\.html$">
SetHandler application/x-httpd-php
</FilesMatch>
# 或在 .htaccess
AddHandler application/x-httpd-php .html .htmnginx
# Nginx 配置
location ~ \.html$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}使用自定义扩展名
apache
# 将 .phtml 解析为 PHP
<FilesMatch "\.phtml$">
SetHandler application/x-httpd-php
</FilesMatch>
# 将 .api 解析为 PHP
<FilesMatch "\.api$">
SetHandler application/x-httpd-php
</FilesMatch>PHP-FPM 配置
ini
; php-fpm pool 配置
; security.limit_extensions 控制允许的 PHP 文件扩展名
security.limit_extensions = .php .html .phtml隐藏源代码
禁止访问 .phps 和源文件
apache
# 禁止访问 .phps(高亮源代码文件)
<FilesMatch "\.phps$">
Order allow,deny
Deny from all
</FilesMatch>
# 禁止访问 .bak, .inc, .old 等备份文件
<FilesMatch "\.(bak|inc|old|orig|save|swp|sql|log|ini|env|yml|yaml)$">
Order allow,deny
Deny from all
</FilesMatch>
# 禁止访问 .git 目录
<DirectoryMatch "^\.git">
Order allow,deny
Deny from all
</DirectoryMatch>
# 禁止访问隐藏文件
<DirectoryMatch "^\.">
Order allow,deny
Deny from all
</DirectoryMatch>nginx
# Nginx 配置
location ~ /\.(env|log|ini|sh|sql|bak|swp|git|svn|hg) {
deny all;
return 404;
}
location ~ \.phps$ {
deny all;
return 404;
}
location ~* \.(bak|inc|old|orig|save|swp|sql|log|ini|env|yml|yaml)$ {
deny all;
return 404;
}自定义错误页面
避免暴露 PHP 路径
php
<?php
declare(strict_types=1);
// 错误页面不暴露 PHP 信息
// php.ini
// display_errors = Off
// 自定义 404 页面
if (!file_exists($requestedFile)) {
http_response_code(404);
include __DIR__ . '/errors/404.html'; // 自定义 HTML 页面
exit;
}
// 自定义 500 页面
set_exception_handler(function (Throwable $e): void {
error_log("{$e->getMessage()} in {$e->getFile()}:{$e->getLine()}");
http_response_code(500);
include __DIR__ . '/errors/500.html';
exit;
});apache
# Apache 自定义错误页面
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 403 /errors/403.html
# 确保错误页面本身是静态 HTML入口文件隐藏
统一入口(Front Controller Pattern)
apache
# Apache URL 重写,所有请求通过 index.php 处理
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
# 禁止直接访问其他 PHP 文件
<FilesMatch "^(?!index\.php$).+\.php$">
Order allow,deny
Deny from all
</FilesMatch>nginx
# Nginx 配置
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 禁止直接访问除 index.php 外的 PHP 文件
location ~ ^/(?!index\.php$).*\.php$ {
deny all;
return 404;
}注意事项
1. 安全通过隐匿
php
<?php
// "Security through obscurity" 不是真正的安全
// 攻击者可以通过以下方式识别 PHP:
// - Cookie 格式(PHPSESSID)
// - HTTP 头特征
// - 错误页面特征
// - 文件扩展名
// - 目录结构特征(/vendor/, /public/)
// - 响应时间特征
// 因此,隐藏 PHP 是辅助措施,核心安全靠编码实践2. 反向代理安全
nginx
# 使用 Nginx 反向代理 PHP-FPM 时
# 确保移除 PHP 添加的头部
fastcgi_hide_header 'X-Powered-By';
fastcgi_hide_header 'X-Accel-Redirect';
fastcgi_hide_header 'X-Accel-Buffering';
fastcgi_hide_header 'X-Accel-Charset';
fastcgi_hide_header 'X-Accel-Expires';
fastcgi_hide_header 'X-Accel-Limit-Rate';最佳实践
1. 信息泄露防护清单
- [x] expose_php = Off
- [x] ServerTokens Prod (Apache)
- [x] server_tokens off (Nginx)
- [x] 移除 X-Powered-By 头
- [x] display_errors = Off
- [x] 自定义错误页面
- [x] 禁止访问敏感文件类型
- [x] 禁止访问 .git 等版本控制目录
- [x] 禁止目录列表(Options -Indexes)下一节
继续学习:保持更新