目录
php.ini 全局安全配置(服务器层面,第一道防线)
safe_mode 安全模式(废弃,仅历史了解)
open_basedir 目录访问限制(防目录遍历 / 跨目录文件读取)
disable_functions 禁用危险函数(最实用安全配置)
magic_quotes_gpc 魔术引号(已废弃,仅理解原理)
allow_url_fopen /allow_url_include 远程文件包含防御
allow_url_fopen
allow_url_include
max_connections 数据库最大连接数
Session 安全配置(防 XSS 窃取 Cookie、中间人劫持)
session.cookie_httponly = On
session.cookie_secure = On
代码层内置函数:数据检测、漏洞过滤(业务代码第二层防御)
变量类型检测函数:强制校验输入数据,弱化漏洞风险
filter_var 过滤器(PHP 官方标准化过滤工具)
SQL 注入防御函数 & 预编译(数据库漏洞核心防御)
转义类函数(传统字符串转义,治标不治本)
最优方案:PDO/Mysqli 预编译(参数化查询)
XSS 跨站脚本防御函数
命令执行漏洞过滤函数
全局流量防护:WAF / 流量检测(第三层前置防护)
三层请求处理架构对比
架构 1:无防护裸服务器
架构 2:规则型 WAF 防护(主流商用 / 开源 WAF)
架构 3:AI 大模型智能流量检测(进阶方案)
WAF 黑白名单 & 关键检测内容
黑名单(拦截)
白名单(放行)
演示链路:Python Flask 模拟 WAF + PHP Curl 模拟客户端
防护分层总结(由外到内完整安全体系)
php.ini 全局安全配置(服务器层面,第一道防线)
php.ini 是 PHP 运行全局配置文件,所有 PHP 脚本共享生效,属于底层强制安全限制,无需改业务代码。
safe_mode 安全模式(废弃,仅历史了解)
1、作用:早期 PHP 内置安全隔离机制,开启后会限制文件跨目录访问、禁止执行系统命令、限制外部文件读取。
2、现状:PHP5.3 起废弃,PHP5.6 彻底移除,不再使用,替代方案:open_basedir+disable_functions。
open_basedir 目录访问限制(防目录遍历 / 跨目录文件读取)
核心防护:限定 PHP 脚本只能操作指定目录内的文件,超出目录无法读写、包含、读取文件。
1、攻击场景:无限制时,攻击者通过file_get_contents("/etc/passwd")、../路径穿越读取服务器敏感配置、源码、密钥。
2、配置示例:
open_basedir = /home/wwwroot:/tmp仅允许脚本操作网站根目录和临时目录,/etc/、/root等系统目录直接拦截。
3、优势:全局生效,所有文件操作函数(include/file_get_contents/fopen)全部受限制。
disable_functions 禁用危险函数(最实用安全配置)
替代废弃 safe_mode,直接禁用高危 PHP 内置函数,从根源杜绝漏洞利用。
- 系统命令执行:
exec、system、shell_exec、passthru、popen - 文件高危操作:
file_put_contents、chmod、rmdir、unlink(按需) - 代码执行:
eval、assert、create_function(一句话木马核心) - 远程读取:
file_get_contents(搭配 allow_url_fopen 使用)
配置示例:
disable_functions = eval,assert,exec,system,shell_exec,passthrumagic_quotes_gpc 魔术引号(已废弃,仅理解原理)
功能:自动对 GET/POST/COOKIE 传入的用户输入,单引号'、双引号"、反斜杠\、NULL 自动加反斜杠转义,初衷简易防 SQL 注入。
缺陷:
- PHP5.4 后彻底移除,新版本不存在该配置;
- 仅转义 4 个字符,无法防御宽字节注入、二阶注入;
- 会造成数据双重转义,页面展示多出反斜杠。
替代方案:手动过滤函数 + MySQL 预编译(PDO 预处理)。
allow_url_fopen /allow_url_include 远程文件包含防御
allow_url_fopen
控制file_get_contents()、fopen()能否读取远程 HTTP/HTTPS 文件。
关闭后:file_get_contents('http://xxx.com/木马.txt')直接报错,防止远程读取恶意文件。
allow_url_include
控制include/require能否引入远程 URL 文件,高危开关,必须关闭。
漏洞场景:远程文件包含漏洞 (RFI)
<?php include($_GET['page']); ?>攻击者传入?page=http://恶意网站/木马.txt,服务器会下载远程木马并执行。
安全配置:两个参数统一关闭
allow_url_fopen = Off allow_url_include = Offmax_connections 数据库最大连接数
限制 MySQL 同时连接数量,防御数据库 CC 爆破、大量并发拖垮数据库。 配置过小会导致正常业务报错,根据服务器性能调整。
Session 安全配置(防 XSS 窃取 Cookie、中间人劫持)
session.cookie_httponly = On
Cookie 禁止 JS 脚本读取,防御 XSS 跨站攻击:攻击者无法通过document.cookie盗取用户会话 Cookie,就算页面存在 XSS,也拿不到登录凭证。
session.cookie_secure = On
仅 HTTPS 加密请求才会携带 Cookie,HTTP 明文请求不会发送 Cookie,防御中间人抓包劫持会话(MITM 中间人攻击)。
代码层内置函数:数据检测、漏洞过滤(业务代码第二层防御)
分为三类:变量类型检测函数、SQL 注入专用过滤、XSS 跨站过滤、系统命令执行过滤。
变量类型检测函数:强制校验输入数据,弱化漏洞风险
核心思路:用户可控输入优先判断数据类型,不满足类型直接拦截,从源头过滤非法输入。
| 函数 | 作用 | 安全使用场景 |
|---|---|---|
| gettype($var) | 返回变量原始类型字符串(string/int/array 等) | 通用类型判断 |
| is_int() | 判断是否纯整数(数字字符串不算) | ID、页码、金额等纯数字参数校验 |
| is_numeric() | 判断是否数字 / 数字字符串("123" 返回 true) | 兼容前端传入数字字符串场景 |
| is_string() | 判断变量是否字符串 | 文本输入校验 |
| is_array() | 判断是否数组 | 批量提交参数校验 |
| is_bool()/is_float()/is_null() | 判断布尔、浮点、空值 | 开关、小数参数校验 |
| is_scalar() | 判断是否标量(字符串 / 数字 / 布尔,排除数组对象) | 过滤数组注入、对象异常输入 |
| is_object/is_resource | 判断对象 / 资源句柄 | 过滤异常非法数据 |
filter_var 过滤器(PHP 官方标准化过滤工具)
内置多种过滤规则,统一处理邮箱、URL、数字、HTML 特殊字符,比手写替换更规范。
1、FILTER_SANITIZE_STRING:过滤 HTML 标签、特殊符号,简易防XSS
2、FILTER_SANITIZE_NUMBER_INT:只保留数字,剔除所有非数字字符,防数字类参数注入
3、FILTER_SANITIZE_URL:清除 URL 非法特殊字符,防御 URL 畸形注入
4、FILTER_VALIDATE_EMAIL:严格校验邮箱格式,拦截非法邮箱提交
示例:
// 校验邮箱 $email = filter_var($_GET['email'], FILTER_VALIDATE_EMAIL); // 清理输入,去除HTML标签 $content = filter_var($_POST['text'], FILTER_SANITIZE_STRING);SQL 注入防御函数 & 预编译(数据库漏洞核心防御)
SQL 注入原理:用户输入拼接 SQL 语句,篡改查询逻辑(查询、删除、脱库数据)。
转义类函数(传统字符串转义,治标不治本)
1、addslashes($str)自动转义' " \ NULL4 种字符,和废弃魔术引号逻辑完全一致。
缺陷:无法防御宽字节注入、堆叠注入,仅临时过滤。
2、stripslashes($str)反转义,去掉 addslashes 添加的反斜杠,用于页面展示数据。
3、addcslashes($str, $charlist)自定义指定字符转义,灵活性更高,可批量转义特殊符号。4、stripcslashes()解析反转义字符串,支持\n、十六进制转义字符还原。
5、mysql_real_escape_string()/mysql_escape_string () MySQL 原生转义函数,转义\x00 \n \r \ \x1a等数据库敏感字符;
区别:mysql_real_escape_string会读取当前连接字符集,防宽字节;废弃 mysql 扩展,现代项目禁用。
最优方案:PDO/Mysqli 预编译(参数化查询)
转义函数存在大量绕过漏洞,预编译是根治 SQL 注入的标准方案。
原理:SQL 模板和用户输入完全分离,数据库先编译 SQL 结构,再传入参数,输入永远不会被解析为 SQL 语法。
示例:
$stmt = $pdo->prepare("SELECT * FROM user WHERE id = ?"); $stmt->execute([$_GET['id']]);无论用户传入什么恶意字符,只会被当作普通字符串处理,无法篡改 SQL 逻辑。
XSS 跨站脚本防御函数
XSS 原理:攻击者提交<script>恶意JS</script>,页面原样输出,JS 在访客浏览器执行盗取 Cookie、钓鱼。
1、strip_tags($str)直接剥离所有 HTML、XML、PHP 标签,只保留纯文本;适合纯文本展示场景(评论、简介)。
2、htmlspecialchars($str)将 HTML 特殊字符转为 HTML 实体,浏览器会原样显示标签,不会执行 JS:
<→<>→>"→"'→'&→&
业务首选,支持保留部分标签,富文本场景必备。
命令执行漏洞过滤函数
漏洞场景:PHP 调用系统命令时拼接用户输入,攻击者注入分号、管道符执行多条系统命令。
1、escapeshellcmd()转义整条命令中的特殊分隔符(; | & \等),禁止拆分多条命令;仅保护命令主体,参数可控时仍有风险。
2、escapeshellarg()将用户输入完整包裹为单个独立参数,用户无法新增、拼接第二个参数,防御效果更强,推荐优先使用。
示例对比:
// 危险写法 system("ping ".$_GET['ip']); // 安全写法 $ip = escapeshellarg($_GET['ip']); system("ping ".$ip);全局流量防护:WAF / 流量检测(第三层前置防护)
php.ini 和代码防护仅在 PHP 程序内部生效,流量检测是请求到达服务器之前的前置拦截,分为规则检测、AI 智能检测。
三层请求处理架构对比
架构 1:无防护裸服务器
客户端请求 → Web 中间件 (Nginx/Apache) → PHP 代码处理 缺陷:所有恶意请求直接进入 PHP,依赖代码过滤,一旦代码疏漏直接被攻击。
架构 2:规则型 WAF 防护(主流商用 / 开源 WAF)
客户端请求 → WAF 流量监控(规则匹配)
- 正常流量:放行 → 中间件 → PHP 业务代码
- 异常恶意流量:直接拦截,断开请求
架构 3:AI 大模型智能流量检测(进阶方案)
基于机器学习 / 大模型训练流量样本,不再只靠固定规则:
- 采集海量恶意流量(SQL 注入、XSS、木马上传、CC 攻击样本)训练模型;
- 请求进入后模型自动识别异常特征、变形绕过攻击;
- 未知新型 0day 攻击(规则库无特征)也能识别拦截。
WAF 黑白名单 & 关键检测内容
黑名单(拦截)
匹配攻击特征直接阻断:
- URL/GET 参数:union select、script、eval、../ 路径穿越等注入特征;
- POST 上传文件:php、phtml 后缀木马文件、图片马;
- Cookie / 请求头:恶意脚本、数据库注入语句;
- 请求行为:高频 CC 扫描、批量爆破接口。
白名单(放行)
可信 IP、内部接口、合法正常参数格式,绕过检测不拦截。
演示链路:Python Flask 模拟 WAF + PHP Curl 模拟客户端
逻辑流程:
- Python Flask 搭建独立 WAF 检测平台,接收所有前端请求;
- PHP 业务使用 curl 把客户端原始请求转发给 Flask WAF;
- WAF 通过规则 / AI 模型判定是否恶意;
- 返回拦截 / 放行结果,放行则转发至真实 PHP 业务接口。
防护分层总结(由外到内完整安全体系)
1、流量层:WAF/AI 流量检测(第一道,拦截绝大多数攻击)
2、Web 服务层:Nginx/Apache 限制上传大小、禁止访问脚本目录
3、PHP 全局配置:php.ini open_basedir、disable_functions、关闭远程包含
4、代码层:类型校验、filter_var、XSS 转义、命令过滤、PDO 预编译防 SQL 注入 五层防护层层兜底,单一防御失效时其他层可拦截攻击。