代码之家  ›  专栏  ›  技术社区  ›  teh_noob

针对URL的单个输入的PHP输入验证

  •  0
  • teh_noob  · 技术社区  · 16 年前

    我有一个非常简单的脚本,允许用户指定任何站点的URL。该脚本将替换对象标记上“data”属性的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中的标题标记,以便可以将其加载到我的站点的标题中。(不用担心它不会欺骗用户)尽管它可以显示任何站点的标题,但它不会以任何其他方式绕过任何过滤器。

    我也知道我所做的工作中涉及到的漏洞,这就是我调查验证的原因。

    4 回复  |  直到 7 年前
        1
  •  3
  •   Chad Birch    16 年前

    正如加胡亚所说,我认为你需要非常小心你在这里做的事情,因为你在玩火。可以安全地进行,但是要非常谨慎地使用用户提供的URL中的数据。

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

    if (!preg_match('/^http:\/\//', $url))
        $url = 'http://'.$url;
    
        2
  •  3
  •   user58670    16 年前

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

    您可以检查方案和主机。

    如果方案是HTTP,那么确保主机不是您的网站。我建议使用preg_匹配,来抓住点之间的部分。与www.google.com或google.com一样,使用preg_match获取google一词。

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

        3
  •  2
  •   gahooa    16 年前

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

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

    假设您确实需要获取URL,考虑根据已知的URL“白名单”进行验证。如果不能将其限制在已知列表中,那么您将再次返回到打开的代理服务器…

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

    将fopen()函数系列与用户提供的参数混合在一起是潜在灾难的一个秘诀。

        4
  •  0
  •   malaimo2900    7 年前