
本文介绍一种基于PHP parse_url() 的健壮URL域名校验方法,替代易被绕过的字符串匹配逻辑,确保仅允许指定域名(如 myydomain.com)的合法URL通过验证,有效拦截拼接式、伪装式或格式错误的恶意输入。
本文介绍一种基于php `parse_url()` 的健壮url域名校验方法,替代易被绕过的字符串匹配逻辑,确保仅允许指定域名(如 myydomain.com)的合法url通过验证,有效拦截拼接式、伪装式或格式错误的恶意输入。
在构建短链接服务时,仅允许用户提交来自可信域名(例如 myydomain.com)的目标URL,是防范垃圾链接注入的关键防线。然而,若采用简单的字符串查找(如 strpos($url, 'myydomain.com')),攻击者极易绕过校验——例如在真实URL前插入 @ryui:、空格、换行符,或在末尾追加干扰参数(如 ?utm_source=copy-link),甚至构造形如 http://evil.com@myydomain.com/path 的混淆URL。原函数 denyNonSite() 正因依赖脆弱的子串匹配而失效。
✅ 推荐方案:使用 parse_url() 提取并比对主机名
PHP 内置的 parse_url() 函数可安全解析URL结构,即使输入含前置/后置干扰内容或格式异常,也能准确提取协议、主机、路径等组件。关键在于:只信任解析后的 PHP_URL_HOST,而非原始字符串。
以下是优化后的校验函数:
function denyNonSite(string $url): bool
{
$host = parse_url($url, PHP_URL_HOST);
// 若解析失败(返回 false)或主机名不匹配,一律拒绝
return $host !== 'myydomain.com';
}✅ 优势说明:
- parse_url(' @ryui:https://myydomain.com/page/2r8jmcWVy7N0wM8eoX4CPJ', PHP_URL_HOST) → 返回 'myydomain.com'(自动忽略前导乱码)
- parse_url('http://evil.com@myydomain.com/path', PHP_URL_HOST) → 返回 'evil.com@myydomain.com'(正确识别认证部分,不匹配)
- parse_url('javascript:alert(1)', PHP_URL_HOST) → 返回 false(非法协议,直接拒绝)
- parse_url('', PHP_URL_HOST) → 返回 false(空输入,安全拦截)
⚠️ 注意事项与增强建议
- 强制类型声明:函数参数声明为 string $url,避免传入数组或对象导致未定义行为。
-
大小写敏感:parse_url() 返回的主机名小写,域名比对默认区分大小写。若需兼容大写域名(如 MYDOMAIN.COM),可统一转小写:
return strtolower($host) !== 'myydomain.com';
- 支持子域名(可选):若需允许 sub.myydomain.com,可用 str_ends_with($host, '.myydomain.com') || $host === 'myydomain.com'。
- 结合其他校验:生产环境建议叠加 HTTPS 强制(parse_url($url, PHP_URL_SCHEME) === 'https')和路径白名单,形成多层防护。
- 数据库写入前调用:务必在插入短链接记录前执行该函数,并配合事务回滚机制,确保无效URL零入库。
通过将校验逻辑从“字符串是否包含”升级为“结构化解析后精准匹配”,可彻底堵住拼接注入漏洞,显著提升短链服务的安全水位。










