我在http://www.verot.net/php_class_upload.htm
的class.upload周围建了一个脚本基本上我的所有图像都存储在服务器上的/images/
我构建的脚本基本上从我的网站获取了一些参数,例如/xyzDir/tomnjerry.jpg?w=100&h=100&fill=1&color=fff
然后我有mod_rewrite从/xyzDir/
读取文件到php脚本,然后转换宽度和高度并返回图像。
最近我注意到土耳其的一些白痴试图将奇怪的字符输入参数w=
和h=
在我的脚本上,我检查确保宽度只允许整数,高度和填充可以是1或2,颜色只能是我通过数组检查的特定值。
我只是想知道是否还有其他事情要做,以免被黑客入侵。
由于
答案 0 :(得分:10)
永远记住,所有用户提供(或不受信任)输入的过滤,退出。
读取用户提供的数据时,将其过滤为已知值。 不要黑名单!始终始终始终将您期望获得的内容列入白名单。如果您期望十六进制数字,请使用正则表达式验证它:^[a-f0-9]+$
。弄清楚你的期望,并过滤掉。除了字母,数字和.
之外,你的文件名都没有吗?然后过滤到^[a-z0-9.]+$
。但是,不要开始考虑将事情列入黑名单。它不起作用。
使用用户数据时,请正确使用它以供手头使用。如果它在数据库中,则将其绑定为参数化查询,或者使用数据库的转义函数将其转义。如果您正在调用shell命令,请使用escapeshellarg()
对其进行转义。如果您以正则表达式模式使用它,请使用preg_quote()
将其转义。还有更多,但你明白了。
输出用户数据时,请将其正确格式化为您输出的格式。如果您要将其输出为HTML或XML,请使用htmlspecialchars()
。如果由于某种原因输出到原始标题,请转义任何换行符(str_replace(array("\r", "\n"), array('\r', '\n'), $string)
)。等等,等等。
但总是使用白名单进行过滤,并始终使用正确的上下文方法进行转义。否则你很有可能会错过一些东西......
答案 1 :(得分:2)
创建一个验证类来验证你的邮件参数。
class MyValidation
{
public function is_interger($val)
{
return is_int($val);
}
public function within_range($val,$min,$max)
{
if($this->is_interger($val))
{
return ($val < $max && $val > $min);
}
return false;
}
public function is_hex($val)
{
return preg_match("/^([a-f0-9]{3}){1,2}$/",$val);
}
}
用于验证您的价值观。
示例:
$Validator = new MyValidation();
if($Validator->is_hex($_POST['color']))
{
//Sweet.
}
答案 2 :(得分:1)
你应该使用intval()来确保宽度和高度是整数
$width = intval($_GET['w']);
$height = intval($_GET['h']);
你可以做到
$fill = $fill == 1 ? 1 : 2;
这是一个三元运算符,所以如果除了1之外它将被设置为2。
对于hex的验证,hex的规则规定它必须在0-9 / A-F的范围内。
$color = preg_replace('/[^0-9a-f]/i', "", $_GET['color']);
希望有所帮助。 (应该注意的是,我建议的代码将执行使其适合您的页面所需的操作,而不是事先确认它是有效的)
答案 3 :(得分:1)
确保图像名称不包含“../”之类的字符串。根据您的脚本,这可能是一种逐步退出图像目录并使脚本传递其他文件的方法。
答案 4 :(得分:1)
没有人在这里提到filter扩展,它提供了在PHP引擎中原生实现的强大过滤功能。恕我直言这是一个很好的扩展,应该始终在滚动自己的过滤代码之前使用。例如,检查整数很简单:
<?php
if (filter_var($value, FILTER_VALIDATE_INT)) {
//Valid Integer.
}
?>
验证十六进制数可以通过以下方式完成:
<?php
if (filter_var($value, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)) {
//Valid Hex number
}
?>
答案 5 :(得分:1)
然后我有mod_rewrite从/ xyzDir /读取文件到php脚本,然后转换宽度和高度并返回图像。
如果你include
文件,图像或其他类型,它将执行埋在其中的任何PHP代码。因此,如果您没有通过imagemagick或gd将其重新格式化为一个全新的文件来摆脱附加到用户上传图像的任何可能代码,那么这就是您的服务器受到攻击的一种方式。
因此,例如,如果您像这样提供用户上传的图像......
<?php
header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename="tomnjerry.jpg"');
include('xyzDir/tomnjerry.jpg');
?>
...如果用户在原始文本编辑器中打开jpg并在将<?php phpinfo(); ?>
上传到服务器之前将其附加到最后,那么他们可以浏览并下载它并提取所有phpinfo详细信息从中安装PHP。
但是既然你提到首先调整图像大小,你甚至可能不会以这种方式提供图像。所以你应该对这次攻击保持安全。