将用户输入清理为URL的一部分

时间:2011-09-14 11:35:53

标签: php user-input sanitization

我从外部客户端脚本中获取一个字符串,该脚本稍后必须作为URL的一部分附加。现在我想知道这些数据的最佳方法是什么?

我得到的字符串将具有如下结构:
dynamicVal#staticVal:dynamicVal

然后将该值添加到网址:
http://the-page.com/dynamicVal#staticVal:dynamicVal

然后使用URL如下:

$link = htmlspecialchars("http://external-page.com/dynamicVal#staticVal:dynamicVal", ENT_QUOTES);
$var = "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";

问题是,htmlspecialchars无助于阻止执行随机JavaScript代码,例如通过将此警报添加到值:

dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'

使用rawurlencode也不会有任何帮助,因为它不是参数的值,而是网址的真实部分。
那么在连接到url时清理传递的字符串的最佳方法是什么?

提前致谢。

修改 仅在动态部分上使用rawurlencode实际上也没有解决问题,javascript仍然被执行 测试片段:

$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode($tmpArr[0]), rawurlencode($tmpArr[1])), ENT_QUOTES);
echo "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";

EDIT2: 在将字符串作为javascript参数传递时使用json_encode也无济于事。 改编的测试片段:

$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal\"+alert('breakout')+\"");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode($tmpArr[0]), rawurlencode($tmpArr[1])), ENT_QUOTES);
echo  "<a href=\"javascript: window.open(".htmlspecialchars(json_encode($link), ENT_QUOTES).")\">'Open URL'</a>";

完成改编:
在苹果JS中切换引号。
htmlspecialchars左右移动json_encode,因为返回了双引号字符串,否则会破坏html。

2 个答案:

答案 0 :(得分:3)

您应该使用urlencode()。不是在整个字符串上,而是仅在动态部分上。

$link = sprintf('http://external-page.com/%s#staticVal:%s', urlencode('dynamicVal'), urlencode('dynamicVal'));
$var  = "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";

修改

好的 - 我看到了你的问题。我没有意识到你将代码插入到JavaScript函数调用中。您必须确保JavaScript解释器将您的链接视为window.open()的字符串参数:

$link = sprintf('http://external-page.com/%s#staticVal:%s', urlencode('dynamicVal'), urlencode('dynamicVal'));
$var  = "<a href=\"javascript: window.open(".json_encode($link).")\">'Open URL'</a>";

答案 1 :(得分:0)

对于completenes,我能够在使用addslashes之前简单地将rawurlencode放在动态部分上来解决该问题。
需要两个函数调用来防止爆发。使用addslashes会阻止正常引号('")和rawurlencode阻止已编码的引号(%29%22)造成伤害。< / p>

所以最终解决方案如下:

$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode(addslashes($tmpArr[0])), rawurlencode(addslashes($tmpArr[1]))), ENT_QUOTES);
echo "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";