parse_url() 在 php 8.5.7 中未被修复,行为依旧宽松;真正修复 cve-2026-44927/44928 的是新增的 uri\rfc3986\uri 类,它通过抛出 invaliduriexception 实现强校验、语义化 equals() 比较和规范化路径处理,但需主动启用并替代 parse_url() 使用。

parse_url() 在 PHP 8.5.7 中**没有被修复**——它依然存在,且行为未变。真正被修复的是底层依赖的 uriparser 库(1.0.2+),而修复效果**只在新 URI 扩展中生效**。你不能靠升级到 8.5.7 就让 parse_url() 突然变安全。
为什么 parse_url() 本身没改
parse_url() 是 PHP 的历史函数,设计目标是“尽力解析”,不是“严格校验”。PHP 官方明确不修改其宽松行为,否则会破坏大量旧代码。8.5.7 的修复聚焦于新机制,而非兼容层。
parse_url() 在 8.5.7 下仍存在的三大缺陷
- 对非法 URI 静默容忍:比如
parse_url("https:///evil.com")返回['scheme'=>'https', 'host'=>'', 'path'=>'/evil.com'],host为空但不报错 - 查询参数顺序敏感:
parse_url("a?x=1&y=2")和parse_url("a?y=2&x=1")返回结构不同,无法直接用于语义比较 - 不处理 Unicode 双向控制符(如
%u202E):解析时可能截断或跳过校验,导致白名单绕过
真正修复 CVE-2026-44927 / CVE-2026-44928 的地方在哪
漏洞修复落地在新增的 Uri\Rfc3986\Uri 类里,不是 parse_url():
-
Uri::createFromString($url)会在构造时抛出InvalidUriException,而不是返回残缺数组 -
$uri->equals($other)严格区分编码与语义,https://a/?x=1&y=2和https://a/?y=2&x=1判定为不等(除非显式调用normalize()) -
$uri->getPath()返回已折叠路径(/a/../b→/b),且保留末尾斜杠语义,避免路由歧义
升级后该怎么用才真正受益
别再把 parse_url() 当校验工具。以下才是 8.5.7 提供的安全路径:
- 用户输入 URL?先
filter_var($input, FILTER_VALIDATE_URL)快速过滤,再交由Uri\Rfc3986\Uri::createFromString() - 做重定向白名单?用
$whitelistUri->equals($userUri),不是parse_url($a) === parse_url($b) - 生成缓存键?必须用
$uri->normalize()->toString(),原始字符串或parse_url()拼接结果都不可靠 - 检查是否启用 URI 扩展:
extension_loaded('uri'),没启用就等于没修复——它不是默认开启的
parse_url() 返回数组上做字符串拼接或松散比较。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











