我总是想在网页上进行任何形式的验证(PHP或ASP,这都无关紧要),但从来没有找到一个好的和准确的答案。
例如,我有一些GET-Parameter,它定义了一个类似于DESC或ASC的SQL查询。(SQL-Injection?)
或者我有一个用户的评论功能,其中的数据也保存在一个数据库中。
检查数据中的HTML标记是否足够?是否应该在将其添加到数据库或在页面上显示它之前完成验证?
我正在寻找的待办事项,这应该总是执行任何数据从“外部”。
谢谢。
发布于 2010-10-21 17:15:42
有一个很好的想法,你想从用户那里得到什么。
你想让他们指定升序/降序吗?这是一个枚举(或布尔值),不是SQL查询的一部分:
$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong无论您如何转义和清理字符串,这都是错误的,因为这不是验证枚举的方法。比较:
if ($_GET['sortOrder'] == 'desc') {
$ascending = false;
} else {
$ascending = true;
}
if ($ascending) {
...
} else {
...
}...which不保证讨论字符串转义或SQL注入,因为您希望从用户那里得到的只是一个是/否(或升序/降序)的答案。
你想让他们输入评论吗?为什么不允许使用HTML标记?如果用户想要输入HTML代码怎么办?
同样,您希望从它们获得的是"a text...任何最大长度为1024个字符的文本*“。这与SQL或注入有什么关系?什么都没有:
$text = $_POST['commentText'];
if (mb_strlen($text, ENCODING) <= 1024) {
//valid!
}数据库中的值应该反映用户逐字输入的内容;不是翻译的,不是转义的。假设您正在剥离注释中的所有HTML。当您决定以JSON格式发送评论时会发生什么?您是否也剥离了JSON控制字符?其他的格式呢?如果HTML引入了一个名为":)“的标记,会发生什么?你会在你的数据库中去掉所有评论中的笑脸吗?
答案是否定的,因为您不希望用户输入HTML安全的、JSON安全的、带有笑脸的奇怪格式的输入。您需要最多1024个字符的文本。看看这个。把它存起来。
现在,显示部分更复杂了。为了显示:
<b>I like HTML "tags"在HTML中,您需要编写如下代码:
<b>I like HTML "tags"在JSON中,您将执行以下操作:
{ "I like HTML \"tags\" }这就是为什么当你使用数据时,你应该使用你的语言工具来转义数据。
当然,SQL也是如此,这就是为什么在使用简单的查询函数(如mysql_query() )时应该对数据进行转义。(另一方面,您真正应该使用的参数化查询不需要转义。)
摘要
对您希望作为输入的内容有一个非常好的想法,请记住,您几乎永远不需要“HTML安全文本”。根据这一点进行验证。需要时转义,表示在发送到浏览器时转义HTML,在发送到数据库时转义SQL,依此类推。
*:您还应该定义“字符”在这里的含义。例如,UTF-8可以使用多个字节来编码码点。"character“是指"byte”还是"Unicode code point"?
发布于 2010-10-21 16:15:51
如果您使用的是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
}发布于 2010-10-21 17:11:08
您正在谈论两种数据卫生。一个是将用户生成的数据放入数据库,另一个是将用户生成的数据放到您的网页上。对于前者,您应该遵循adam的建议。对于后者,您应该研究一下htmlspecialchars。
请不要将这两者混为一谈,因为它们做的是两件完全不同的事情。为此,卫生设施应该只在最后一刻进行。在更新数据库之前使用adam的建议。在回显数据之前使用htmlspecialchars。在将数据添加到数据库之前,不要对数据使用htmlspecialchars。
你可能还想看看Stackoverflow,因为这类问题在过去已经被问过无数次了。
https://stackoverflow.com/questions/3985448
复制相似问题