如何在Perl中从含用户名密码的URI提取主机名并修复SSRF漏洞?
解决方案:修复LinkedIn URL校验的SSRF漏洞
不要用正则直接匹配URL开头,因为URL的用户信息(username:password@)部分会干扰主机名判断,应该用Perl标准库中的URI模块来正确解析URL结构,这样能准确提取并验证主机名。
修复后的代码
#!/usr/bin/perl package External; use warnings; use URI; # 引入URL解析模块 sub isValidLinkedinProfileUrl { my $linkedin_url = $_[0]; my $uri = URI->new($linkedin_url); # 验证三个关键条件: # 1. URL解析成功(避免无效URL) # 2. 协议是HTTPS # 3. 主机名严格等于www.linkedin.com return unless $uri; return $uri->scheme eq 'https' && $uri->host eq 'www.linkedin.com'; } 1;
为什么这能解决问题?
URI->new()会自动解析URL的各个组成部分,不管是否包含username:password@这类用户信息,都能准确提取出实际的主机名(比如你提到的恶意URLhttps://www.linkedin.com:password@hacker-site.notld,解析后$uri->host会返回hacker-site.notld,直接被校验拒绝)。- 相比正则,这种方式能处理所有合法的LinkedIn URL格式(比如带路径、查询参数的个人主页URL,如
https://www.linkedin.com/in/john-doe),不会像/^https:\/\/www\.linkedin\.com$/那样因为存在路径就误判为无效。
额外注意事项
URI是Perl核心模块,通常默认已安装,无需额外配置。- 如果需要允许LinkedIn的其他子域名(比如
linkedin.com不带www),可以调整主机名校验逻辑,比如用/^(\w+\.)?linkedin\.com$/匹配,但要根据业务需求严格控制范围,避免再次引入SSRF风险。
内容的提问来源于stack exchange,提问作者amfranks
相关产品推荐
相关产品推荐

