PHP如何禁用外部实体加载来防御XXE libxml_disable_entity_loader函数
发布时间 - 2026-02-02 00:00:00 点击率:次libxml_disable_entity_loader在PHP 7.4+已移除且完全失效;正确方式是针对SimpleXML、DOMDocument分别显式配置禁用外部实体,或PHP 8.0+统一使用libxml_set_external_entity_loader(null)。
libxml_disable_entity_loader 在 PHP 7.4+ 已被移除
直接调用 libxml_disable_entity_loader(true) 在 PHP 7.4 及更新版本会触发 Deprecated: libxml_disable_entity_loader(): This function is deprecated 警告,且**完全失效**。它只在 PHP 5.6–7.3 有效,但即便在这些版本中,也仅影响部分 libxml API(如 simplexml_load_string),对 DOMDocument::loadXML() 等默认行为无效——因为后者不自动继承该全局开关。
正确禁用外部实体的三种可靠方式
必须针对具体 XML 解析器显式配置,不能依赖全局函数:
-
SimpleXML 场景:使用
LIBXML_NOENT | LIBXML_DTDLOAD以外的选项,并确保不传入LIBXML_NOENT(它会加载外部实体);更安全的是显式禁用 DTD:$xml = simplexml_load_string($raw, 'SimpleXMLElement', LIBXML_NONET | LIBXML_NOCDATA);
-
DOMDocument 场景:必须在实例化后、调用
loadXM或
L()
load()前设置属性:$dom = new DOMDocument(); $dom->resolveExternals = false; $dom->substituteEntities = false; $dom->setEntityLoader(function () { return false; }); // PHP 8.0+ $dom->loadXML($raw); -
PHP 8.0+ 统一方案:使用
libxml_set_external_entity_loader(null)替代已废弃函数,它作用于当前请求上下文,对所有后续 libxml 调用生效(包括 SimpleXML 和 DOM):libxml_set_external_entity_loader(null); $xml = simplexml_load_string($raw); // 安全 $dom = new DOMDocument(); $dom->loadXML($raw); // 安全
为什么只设 LIBXML_NONET 不够
LIBXML_NONET 阻止网络请求,但无法阻止本地 DTD 文件或内联实体定义(如 &xxe; 指向 file:///etc/passwd)。真实 XXE 利用常通过如下方式绕过:
]>此时若未禁用 DTD 解析或实体替换,仍会泄露文件内容。必须组合使用:&xxe; ]]>
resolveExternals = false + substituteEntities = false + libxml_set_external_entity_loader(null)。
遗留系统兼容 PHP 7.2–7.3 的折中写法
若无法升级 PHP 版本,需同时处理全局开关和实例配置,避免遗漏:
if (function_exists('libxml_disable_entity_loader')) {
libxml_disable_entity_loader(true);
}
$dom = new DOMDocument();
$dom->resolveExternals = false;
$dom->substituteEntities = false;
$dom->loadXML($raw);注意:此写法在 PHP 8.0+ 会报弃用警告,上线前务必确认 PHP 版本并清理该调用。
实际防御 XXE 的关键不在“关一个开关”,而在于每个 XML 解析入口都显式关闭实体加载能力——尤其是当代码路径涉及多个解析器(如先用 SimpleXML 再转 DOM),容易漏掉某一处。
# php
# 为什么
# NULL
# xml
# Libxml
# simpleXML
# 继承
# function
# dom
# this
# 会报
# 移除
# 的是
# 加载
# 尤其是
# 多个
# 已被
# 三种
# 只在
# 在这些
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251811 】
【
AI营销90571 】
相关推荐:
Laravel如何使用Blade组件和插槽?(Component代码示例)
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel distinct去重查询_Laravel Eloquent去重方法
如何快速生成ASP一键建站模板并优化安全性?
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
如何快速上传自定义模板至建站之星?
Laravel模型事件有哪些_Laravel Model Event生命周期详解
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
如何在阿里云域名上完成建站全流程?
JavaScript常见的五种数组去重的方式
Laravel如何升级到最新版本?(升级指南和步骤)
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
在centOS 7安装mysql 5.7的详细教程
详解jQuery中的事件
Python数据仓库与ETL构建实战_Airflow调度流程详解
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
Java类加载基本过程详细介绍
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
如何在IIS管理器中快速创建并配置网站?
BootStrap整体框架之基础布局组件
用yum安装MySQLdb模块的步骤方法
如何快速搭建个人网站并优化SEO?
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
zabbix利用python脚本发送报警邮件的方法
高防服务器如何保障网站安全无虞?
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
Internet Explorer官网直接进入 IE浏览器在线体验版网址
Laravel如何配置任务调度?(Cron Job示例)
青岛网站建设如何选择本地服务器?
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
详解Huffman编码算法之Java实现
如何在新浪SAE免费搭建个人博客?
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
教你用AI润色文章,让你的文字表达更专业
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
网站制作企业,网站的banner和导航栏是指什么?
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
如何正确下载安装西数主机建站助手?
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
如何在自有机房高效搭建专业网站?
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
如何登录建站主机?访问步骤全解析


