什么是在PHP中验证URL最安全的方法?

4

我正在处理一个代码片段,需要验证URL以确保数据发送到正确的URL。为此,我使用filter_var()函数。

在测试时,我开始遇到问题,这是我的代码;

<?php

function post($webLink){

    $url = filter_var($webLink, FILTER_SANITIZE_URL);

    if (filter_var($url, FILTER_VALIDATE_URL)) {

        echo 'Correct';
    }

    else {

        echo 'Please check your url.';
    }

}

    post('h://www.google.com');
?>

很多无效的链接被验证为正确的URL,包括当前链接。
得到验证的链接有:
    ht1tp://www.google.com
    h://ww.google.com
    http://www.google.
    http://www.google.343

我不相信这是函数验证这些链接是否正确,我认为我的if (filter_var($url, FILTER_VALIDATE_URL))代码行存在问题。请告诉我如何正确使用它。谢谢。


4
你看过FILTER_VALIDATE_URL的说明吗?http://php.net/manual/en/filter.filters.validate.php - u_mulder
如果您想检查一个URL是否有效而不仅仅是看起来有效,您可能需要使用类似于checkdnsrr()的东西。http://php.net/manual/en/function.checkdnsrr.php - 即使如此,我认为它也无法处理新的UTF-8域名。 - CD001
1
你可能还需要加入 parse_url()。它可以解析出协议/方案,以便您确保它是 http 或 https。 - gen_Eric
1
@Ifeoluwa:http://com.google 是一个有效的URL,只是这么说。 - gen_Eric
1
如果FILTER_VALIDATE_URL不是你要找的,那么“valid”是什么意思?不是一个4XX的响应吗? - HPierce
显示剩余3条评论
1个回答

9
首先,仅验证输入。永远不要净化输入。在准备输出之前不要进行净化。这是处理数据的通用规则,对于安全显示URL以及防止XSS攻击、SQL注入等同样重要。
其次,FILTER_VALIDATE_URL基于RFC 2396验证URL。该RFC没有指定任何特定的方案,但给出了几个示例(即HTTP:,GOPHER:,MAILTO:等)。PHP手册中validate filters明确指出:
“请注意,有效的URL可能不指定HTTP协议http://,因此可能需要进一步验证以确定URL使用预期的协议,例如ssh://或mailto:。”
此外,RFC未定义域名的结构,也不需要任何特定的顶级域名。因此,验证过滤器不会检查它们。域名是由注册机构按照ICANN规则正式分配的,但您可以自由配置自己的本地DNS服务器以创建任何条目,包括创建仅TLD条目,因此任何域名都是有效的,无论是否通过验证过滤器。
验证某些定义良好的数据最安全的方法是将其列入白名单。如果您真的想确保没有人传递“ht&nbsp;tp:com.google.xssHackHere”,那么您需要自行进行进一步检查。请注意,现在有数百个有效的TLD,并且并非所有TLD都易于用ASCII字符表示,如果您想验证域名以及方案。

2
澄清:目前有超过一千个有效的顶级域名(TLDs):http://stats.research.icann.org/dns/tld_report/ (截至今日为止有1080个)。 - Ghedipunk
1
嗯,好的。换句话说:“没有办法使用PHP函数验证URL,除非自己解决。”我明白了,谢谢大家。 - Ifeoluwa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接