我想对我的用户好,但不想错误地获取恶意代码。 看了很多问题,我决定将其列入白名单,所以我只收到我认可的字符。
如何才能对用户友好,所以我让他们输入许多字符并保持输入不受恶意代码的影响?
我在PHP 5.3.8中使用Apache,我没有合并PDO,因为我听说它的时候我深入到项目中并且担心它可能会有太大的变化。
任何想法都会有所帮助!
答案 0 :(得分:2)
如果可以将其输出给用户,则必须防止潜在恶意用户在其代码中包含HTML标记。例如,如果在该帖子中,我可以包含script
标记,那对于阅读我帖子的任何用户来说都是非常危险的。为防止出现这种情况,您需要使用htmlentities
:
$clean_data = htmlentities($_POST['data']);
这样,我的<script>
代码会被翻译为<script>
,因此在浏览器显示时不会损害用户。
现在,如果您想将我的帖子保存在数据库中,您必须注意SQL注入。假设您正在使用该查询保存我的帖子(是的,您不应该使用mysql_*
函数,因为它们已被弃用,但这只是为了解释这个想法):
mysql_query($db, "INSERT INTO posts(data) values('$clean_data');");
听起来不错?好吧,如果我讨厌,我会尝试包括那篇文章:
test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '
然后你的MySQL得到了什么
INSERT INTO posts(data) values('test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '');
哎哟。所以,你必须基本上阻止你的用户在他的帖子中包含引号和双引号,或者更准确地说,你应该逃避它们。这实际上取决于您使用的库,但在我使用的过时库中,将写入:
$really_clean_data = mysql_real_escape_string($db, $clean_data);
mysql_query($db, "INSERT INTO posts(data) values('$really_clean_data');");
因此,有了上述恶意帖子,MySQL现在会收到
INSERT INTO posts(data) values('test\'); DELETE FROM posts; SELECT * FROM posts WHERE data = \'');
现在,对MySQL来说,整个INSERT INTO posts(data) values('test'); DELETE FROM posts; SELECT * FROM posts WHERE data = '');
部分是一个正确的字符串,所以会发生什么事情。
基本上,几乎在所有情况下都需要这些。请记住,当您将用户数据提供给解释器(它可以是Web浏览器,SQL引擎或许多其他东西)时,您应该清理该数据,最好的方法是使用应该使用的专用函数来自你正在使用的图书馆。
答案 1 :(得分:2)
只是为了补充Fabien已经提供的答案,文本数据类型并不是您需要关注的唯一项目。数字同样重要。类型转换变量是处理它的一种方法。例如,
$really_clean_data = mysql_real_escape_string($db, $clean_data);
$query = "UPDATE posts SET post = '".$really_clean_data."' WHERE id = '".(int)$_POST['id']."'";
提交的所有数据,包括您要更新的帖子的ID号,都是可疑的,同样可以像textarea或文本输入条目一样开放。如果你知道它应该是一个整数(数字),你可以这样投射它。如果它不是数字,则(int)将其强制转换为0.您无法更新第0行,因此SQL查询将失败。
要在执行查询之前检查该失败,您可以使用is_numeric()函数检查发布的数据以查看它是否为数字。
if(!is_numeric($_POST['id'])){
die("Post id is not a number.");
}
对于输入字段,尤其是用户名和密码字段,您可以设置最大长度并进行检查。例如,
if(strlen($_POST['username']) > 24){
$error = "username is too long";
}
如果您能够获得创意,那么防止SQl注射实际上很有趣!请记住,从现在起一年后,此页面上的所有内容都可能完全过时且无关紧要。安全是一个过程,而不是一个步骤,所以要掌握它。