【问题标题】:PHP Input validation for a single input for a url用于 url 的单个输入的 PHP 输入验证
【发布时间】:2009-02-23 07:15:18
【问题描述】:

我有一个非常简单的脚本,它允许用户指定任何站点的 url。该脚本替换了对象标记上的“数据”属性的 url,以在 HTML 页面上的对象内显示用户选择的站点。

我如何验证输入,以便用户无法从我的网站在对象内加载任何页面,因为我注意到它会显示我的代码。

代码:

 <?php
 $url = 'http://www.google.com';
 if (array_key_exists('_check', $_POST)) {
    $url = $_POST['url'];
 }
 //gets the title from the selected page
 $file = @ fopen(($url),"r") or die ("Can't read input stream");
 $text = fread($file,16384);
 if (preg_match('/<title>(.*?)<\/title>/is',$text,$found)) {
         $title = $found[1];
 } else {
         $title = "Untitled Document";
 }
 ?>

编辑:(更多细节) 这并不意味着成为代理。我让用户决定将哪个网站加载到对象标签中(类似于 iframe)。 php 唯一要读取的是来自输入 url 的标题标签,因此它可以加载到我网站的标题中。 (别担心它不会欺骗用户)虽然它可以显示任何网站的标题,但它不会以任何其他方式绕过任何过滤器。

我也知道我正在做的事情涉及的漏洞,这就是我研究验证的原因。

【问题讨论】:

    标签: php html validation object-tag


    【解决方案1】:

    正如 gahooa 所说,我认为你在这里所做的事情需要非常小心,因为你在玩火。可以安全地进行操作,但要非常谨慎地处理用户提供给您的 URL 中的数据。

    对于您遇到的特定问题,我假设如果您输入文件名,例如有人在框中键入“index.php”,就会发生这种情况。您需要做的就是确保他们的 URL 以“http://”开头,以便 fopen 使用网络方法,而不是打开本地文件。在 fopen 行之前这样的事情应该可以解决问题:

    if (!preg_match('/^http:\/\//', $url))
        $url = 'http://'.$url;
    

    【讨论】:

    • 为什么 preg_match 比 parse_url 更可取?
    【解决方案2】:

    parse_url:http://us3.php.net/parse_url

    您可以检查方案和主机。

    如果方案是 http,则确保主机不是您的网站。我建议使用 preg_match 来抓取点之间的部分。与在 www.google.com 或 google.com 中一样,使用 preg_match 来获取 google 一词。

    如果主机是 ip,我不确定在这种情况下你想做什么。默认情况下,preg 匹配只会得到中间 2 个数字和点(假设你尝试使用 preg_match 来获取 .com 之前的站点名)

    【讨论】:

      【解决方案3】:

      您是否知道您正在创建一个开放的 HTTP 代理,这可能是一个非常糟糕的主意?

      您甚至需要获取 URL 的内容吗?为什么不让用户的浏览器通过提供 URL 来做到这一点?

      假设您确实需要获取网址,请考虑根据已知的网址“白名单”进行验证。如果您无法将其限制为已知列表,那么您将再次回到开放代理...

      使用正则表达式 (preg) 确保它是一个好的 HTTP url,然后使用 CURL 扩展来做实际的请求。

      将 fopen() 系列函数与用户提供的参数混合使用会导致潜在的灾难。

      【讨论】:

      • 这不是代理。我让用户决定将哪个网站加载到对象标签中(类似于 iframe)。 php 唯一要读取的是输入 url 中的标题标签,因此可以将其加载到我网站的标题中。 (别担心它不会欺骗用户)
      【解决方案4】:

      你可以使用 PHP 过滤器。

      filter_var($url, FILTER_VALIDATE_URL) 或 filter_input(INPUT_POST, 'url', FILTER_VALIDATE_URL);

      http://php.net/manual/en/function.filter-input.php

      也可以试试这个 PHP wiki 文章引用的这些文档,这些文档与过滤器相关 https://wiki.php.net/rfc/add_validate_functions_to_filter?s[]=filter 作者 大垣康夫

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-25
        • 2014-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-22
        • 1970-01-01
        • 2014-03-25
        相关资源
        最近更新 更多