PHP输入验证一个URL的单个输入

问题描述:

我有这个非常简单的脚本,允许用户指定任何网站的网址。该脚本将替换对象标记上的“data”属性的url,以在HTML页面上的对象内显示用户选择的网站。PHP输入验证一个URL的单个输入

我怎么能验证输入,使用户无法从我的对象据点内加载任何页面,因为我已经注意到,它会显示我的代码。

代码:

<?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的标题标签,因此它可以加载到我的网站的标题中。 (别担心它不欺骗用户)虽然它可能会显示任何网站的标题,但它不会以任何其他方式绕过任何过滤器。

我也知道我正在做什么的漏洞,这就是为什么我正在寻找验证。

正如gahooa说,我认为你必须非常小心你在做什么这里,因为你是在玩火。可以安全地做,但要谨慎对待用户提供的URL中的数据。

对于您遇到虽然具体的问题,我想如果你得到一个文件名的输入它发生,因此,例如,如果有人类型“的index.php”入箱。您只需确保其URL以“http://”开头,以便fopen使用网络方法,而不是打开本地文件。像这样的东西则fopen前行应该做的伎俩:

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

为什么preg_match比parse_url更可取? – Tech4Wilco 2011-09-12 12:52:33

你知道你正在创建一个开放的HTTP代理服务器,它可以是一个非常糟糕的主意?

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

假设您确实需要获取URL,请考虑针对已知的URL“白名单”进行验证。如果你不能限制它到一个已知的列表,然后你又回到开放代理...

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

混合的与用户提供的参数的函数的fopen()函数族是潜在灾难。

+0

这不是代理。我让用户决定将哪个网站加载到对象标记中(类似于iframe)。 PHP将要读取的唯一东西是来自输入url的标题标签,因此它可以加载到我的网站的标题中。 (别担心它不会欺骗用户) – 2009-02-23 07:28:27

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

您可以检查方案和主机。

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

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

您可以使用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维基引用后通过康夫Ohgaki