引言:为什么你的PHP网站现在可能被黑客入侵?
\n想象一下这个场景:你写了一个很棒的PHP网站,有反馈表单、评论区和个人账户。一切运行正常。但有一天你登录后台,发现里面空空如也。或者更糟:网站上出现了赌场广告,而谷歌已经屏蔽了你的资源。熟悉吗?问题的根源在于对用户输入的错误处理。
\n问题"How can I sanitize user input with PHP?"是Stack Overflow上最热门的问题之一。成千上万的开发者都在同一个坑里跌倒。在本文中,我们将分析即使是经验丰富的程序员也会犯的常见错误,并展示如何避免它们。你将了解如何防御XSS、SQL注入和其他攻击。开始吧!
\n\n错误#1:对所有内容使用mysql_real_escape_string()
\n老派做法:许多开发者仍然认为,只要将所有数据用mysql_real_escape_string()包裹起来,问题就解决了。这是一个严重的错误。这个函数仅用于在SQL查询中转义字符串,而且仅适用于早已在PHP 7中被移除的过时mysql_*扩展。
错误代码示例:
\n<?php\n$name = mysql_real_escape_string($_POST['name']);\n$query = "INSERT INTO users (name) VALUES ('$name')";\n$result = mysql_query($query);\n?>\n为什么这很糟糕:
\n- \n
- 该函数无法防御XSS攻击(例如插入JavaScript)。 \n
mysql_*扩展已过时且不安全。 \n - 你将转义逻辑与业务逻辑混为一谈。 \n
如何修复:通过PDO或MySQLi使用预处理语句(prepared statements)。而在输出数据到屏幕时,则使用单独的清理方法。
\n\n错误#2:输出数据时忽略XSS攻击
\n最常见的错误。你接收了数据,保存到数据库,然后直接通过echo或print输出。瞧——攻击者可以插入一个脚本,窃取Cookie、重定向用户或破坏页面布局。
存在漏洞的代码示例:
\n<?php\necho "<p>你好," . $_GET['name'] . "!</p>";\n?>\n如果在URL中传入?name=<script>alert('XSS')</script>,脚本就会执行。
解决方案:使用带有ENT_QUOTES参数的htmlspecialchars()函数:
<?php\n$name = htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');\necho "<p>你好," . $name . "!</p>";\n?>\n重要:清理操作应在输出时进行,而不是在保存时。如果你在数据库中替换了字符,就会丢失原始数据。
\n\n错误#3:盲目使用strip_tags()进行过滤
\n许多人认为:"哦,只要删除所有HTML标签就万事大吉了。"但strip_tags()并非万能药。首先,它只删除标签,但会保留属性(例如onclick)。其次,如果你需要允许部分标签(例如<b>或<i>),使用strip_tags()会变得很不方便。
示例:
\n<?php\n$comment = strip_tags($_POST['comment']);\necho $comment; // 会删除<script>,但会保留<a onclick="...">\n?>\n解决方案:对于普通文本使用htmlspecialchars(),或者如果需要允许特定标签,则使用像HTML Purifier这样的库。HTML Purifier不仅检查标签,还检查属性、样式甚至CSS。
错误#4:缺乏对电子邮件、URL和数字的验证
\n清理不仅仅是关于XSS。如果你期望一个电子邮件地址,却收到字符串"123",这可能会导致错误。或者,如果你在未验证的情况下保存URL,攻击者可能会插入javascript:alert(1)。