PHP输入验证网址的单个输入

时间:2009-02-23 07:15:18

标签: php html validation object-tag

我有这个非常简单的脚本,允许用户指定任何网站的网址。该脚本替换对象标记上“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 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:3)

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

您可以检查方案和主持人。

如果scheme是http,那么请确保主机不是您的网站。我建议使用preg_match来抓住点之间的部分。与在www.google.com或google.com中一样,使用preg_match来获取谷歌这个词。

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

答案 2 :(得分:2)

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

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

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

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

将fopen()系列函数与用户提供的参数混合是潜在灾难的一种方法。

答案 3 :(得分:0)

您可以使用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 通过 Yasuo Ohgaki