我一直在考虑网页上的任何类型的验证(PHP或ASP,无所谓),但从未找到一个好的和准确的答案。
例如,我有一些GET
- 参数,它定义了一个像DESC或ASC这样的SQL查询。 (SQL-Injection
?)
或者我有一个用户评论功能,其中数据也保存在数据库中。
是否应该检查数据中的HTML标签?是否应该在将其添加到数据库或在页面上显示之前完成验证?
我正在搜索ToDo,它应始终使用“outside”提供的任何数据执行。
感谢。
答案 0 :(得分:1)
如果您正在使用PDO,请务必使用预准备语句 - 这些语句会自动清理传入数据。
如果使用mysql_ *函数,请先通过mysql_real_escape_string
运行每个变量。
您还可以进行验证,例如确保变量是可接受范围之一:
$allowed_values = array('name', 'date', 'last_login')
if(in_array($v, $allowed_values)) {
// now we can use the variable
}
答案 1 :(得分:1)
很好地了解您对用户的要求。
您希望他们指定升序/降序吗?这是一个枚举(或布尔值),不是SQL查询的一部分:
$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong
无论您逃脱多少并清理其字符串,这都是错误的,因为这不是验证枚举的方法。比较:
if ($_GET['sortOrder'] == 'desc') {
$ascending = false;
} else {
$ascending = true;
}
if ($ascending) {
...
} else {
...
}
...这不保证讨论字符串转义或SQL注入,因为用户只需要是/否(或升序/降序)答案。
您希望他们输入评论吗?为什么禁止使用HTML标签?如果用户想要输入HTML代码怎么办?
同样,你想要的是“文本......任何文本,最大长度为1024个字符*”。这与SQL或注入有什么关系?没什么:
$text = $_POST['commentText'];
if (mb_strlen($text, ENCODING) <= 1024) {
//valid!
}
数据库中的值应反映用户逐字输入的内容;没有翻译,没有逃脱。假设您正在剥离所有HTML&lt; tags&gt;来自评论。当您决定以JSON格式在某处发送评论时会发生什么?你也剥离了JSON控制字符吗?其他一些格式怎么样?如果HTML引入了一个名为“:)”的标签,会发生什么?你是否在你的数据库中绕过所有评论的笑脸?
答案是否定的,因为您不希望用户使用HTML安全,JSON安全,某些奇怪的格式与表情符号安全的输入。您希望文本最多1024个字符。检查一下。存储它。
现在,显示部分比较棘手。为了显示:
<b>I like HTML "tags"
在HTML中,您需要编写如下内容:
<b>I like HTML "tags"
在JSON中,您可以这样做:
{ "I like HTML \"tags\" }
这就是为什么你应该使用语言工具来逃避使用它时的数据。
SQL当然也是如此,这就是为什么在PHP中使用mysql_query()
这样的简单查询函数时应该转义数据的原因。 (另一方面,参数化查询,你应该真正使用它,不需要转义。)
非常清楚你想要什么作为输入,记住你几乎从不需要,比如“HTML安全文本”。对此进行验证。在需要时转义,意味着在发送到浏览器时转义HTML,在发送到数据库时转移SQL,等等。
*:您还应该定义“字符”在这里的含义。例如,UTF-8可以使用多个字节来编码代码点。 “字符”是指“字节”还是“Unicode代码点”?
答案 2 :(得分:0)
您正在谈论两种数据卫生。一种是将用户生成的数据放入数据库,另一种是将用户生成的数据放在网页上。对于前者,您应该遵循亚当的建议。对于后者,您应该查看htmlspecialchars。
不要将这两者混合在一起,因为它们完全不同。为此目的,卫生应该只在最后一刻进行。在更新数据库之前使用adam的建议。在回显数据之前使用htmlspecialchars。在将数据添加到数据库之前,不对数据使用htmlspecialchars。
您可能还想查看Stackoverflow,因为过去曾多次询问和回答过这类问题。