2013-02-01 66 views
1

我想对我的用户好,但不想错误地获取恶意代码。 寻找很多问题我决定去白名单,所以我只得到我批准的字符。PHP安全地接收用户输入

怎么样才能对用户好一点,所以我让他们输入很多字符,并且仍然保证我的输入不受恶意代码的影响?
我使用Apache与PHP 5.3.8,我没有纳入PDO,因为我听说它的时间,我深入该项目,并担心它可能太大的变化。

任何想法都有帮助!

+2

你在说sql注入吗? – KennyPowers

+2

看看这个http://stackoverflow.com/a/60496/1878073 – Vainglory07

+1

这真的取决于你在用户输入中做什么。在sql中存储,在浏览器中输出... –

回答

2

如果可以输出给用户,则必须防止潜在恶意用户在其代码中包含HTML标记。例如,如果在该帖子中,我可以包含script标签,这对任何阅读我帖子的用户都是非常危险的。为了防止这种情况,要使用htmlentities

$clean_data = htmlentities($_POST['data']); 

这样一来,我的<script>标签将被翻译为&lt;script&gt;所以当通过其浏览器中显示它不会伤害用户。

现在,如果您想将我的文章保存到数据库中,您必须注意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引擎或其他许多事物)时,您应该清除该数据,最好的方法是使用专用函数与您正在使用的图书馆一起来。

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号,就是因为犯罪嫌疑人,只是开放恶意摆弄作为一个文本或文本输入的条目。当你知道它应该是一个整数(数字)时,你可以像这样投射它。如果它不是数字,那么(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注入实际上很有趣!请记住,从现在起一年后,此页面上的所有内容都可能完全过时并且无关紧要。安全是一个过程,而不是一个步骤,所以请保持在最重要的位置。