web安全代码基础-PHP(防护过滤操作)

📅 2026/7/5 1:38:44 👁️ 阅读次数 📝 编程学习
web安全代码基础-PHP(防护过滤操作)

目录

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,passthru
magic_quotes_gpc 魔术引号(已废弃,仅理解原理)

功能:自动对 GET/POST/COOKIE 传入的用户输入,单引号'、双引号"、反斜杠\、NULL 自动加反斜杠转义,初衷简易防 SQL 注入。

缺陷:

  1. PHP5.4 后彻底移除,新版本不存在该配置;
  2. 仅转义 4 个字符,无法防御宽字节注入、二阶注入;
  3. 会造成数据双重转义,页面展示多出反斜杠。

替代方案:手动过滤函数 + 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 = Off
max_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:

  • <&lt;
  • >&gt;
  • "&quot;
  • '&#039;
  • &&amp;

业务首选,支持保留部分标签,富文本场景必备。

命令执行漏洞过滤函数

漏洞场景: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 大模型智能流量检测(进阶方案)

基于机器学习 / 大模型训练流量样本,不再只靠固定规则:

  1. 采集海量恶意流量(SQL 注入、XSS、木马上传、CC 攻击样本)训练模型;
  2. 请求进入后模型自动识别异常特征、变形绕过攻击;
  3. 未知新型 0day 攻击(规则库无特征)也能识别拦截。
WAF 黑白名单 & 关键检测内容
黑名单(拦截)

匹配攻击特征直接阻断:

  • URL/GET 参数:union select、script、eval、../ 路径穿越等注入特征;
  • POST 上传文件:php、phtml 后缀木马文件、图片马;
  • Cookie / 请求头:恶意脚本、数据库注入语句;
  • 请求行为:高频 CC 扫描、批量爆破接口。
白名单(放行)

可信 IP、内部接口、合法正常参数格式,绕过检测不拦截。

演示链路:Python Flask 模拟 WAF + PHP Curl 模拟客户端

逻辑流程:

  1. Python Flask 搭建独立 WAF 检测平台,接收所有前端请求;
  2. PHP 业务使用 curl 把客户端原始请求转发给 Flask WAF;
  3. WAF 通过规则 / AI 模型判定是否恶意;
  4. 返回拦截 / 放行结果,放行则转发至真实 PHP 业务接口。
防护分层总结(由外到内完整安全体系)

1、流量层:WAF/AI 流量检测(第一道,拦截绝大多数攻击)

2、Web 服务层:Nginx/Apache 限制上传大小、禁止访问脚本目录

3、PHP 全局配置:php.ini open_basedir、disable_functions、关闭远程包含

4、代码层:类型校验、filter_var、XSS 转义、命令过滤、PDO 预编译防 SQL 注入 五层防护层层兜底,单一防御失效时其他层可拦截攻击。