是否存在一种万能函数,可以很好地为SQL注入和XSS攻击清除用户输入,同时仍然允许某些类型的HTML标记?
当前回答
有一个技巧可以帮助您在特定情况下使用/mypage?id=53,在WHERE子句中使用id是为了确保id确实是一个整数,如下所示:
if (isset($_GET['id'])) {
$id = $_GET['id'];
settype($id, 'integer');
$result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
# now use the result
}
但当然,这只排除了一个特定的攻击,所以阅读所有其他的答案。(是的,我知道上面的代码不是很好,但它显示了具体的防御。)
其他回答
不。你不能在没有任何上下文的情况下过滤数据。有时你想把SQL查询作为输入,有时你想把HTML作为输入。
您需要筛选白名单上的输入——确保数据符合您所期望的某些规范。然后,您需要在使用它之前对它进行转义,这取决于您使用它的上下文。
为SQL转义数据(防止SQL注入)的过程与为(X)HTML转义数据(防止XSS)的过程非常不同。
避免在清理输入和转义数据时出错的最简单方法是使用Symfony、Nette等PHP框架或该框架的一部分(模板引擎、数据库层、ORM)。
像Twig或Latte这样的模板引擎默认有输出转义-如果你根据上下文(HTML或Javascript部分的网页)正确地转义了你的输出,你不必手动解决。
框架会自动清理输入,你不应该直接使用$_POST, $_GET或$_SESSION变量,而是通过路由,会话处理等机制。
对于数据库(模型)层,有像Doctrine这样的ORM框架或围绕PDO的包装器,如Nette database。
你可以在这里阅读更多关于它的内容-什么是软件框架?
要解决XSS问题,可以看看HTML Purifier。它具有相当的可配置性和良好的记录。
对于SQL注入攻击,解决方案是使用准备好的语句。PDO库和mysqli扩展支持这些功能。
有一个技巧可以帮助您在特定情况下使用/mypage?id=53,在WHERE子句中使用id是为了确保id确实是一个整数,如下所示:
if (isset($_GET['id'])) {
$id = $_GET['id'];
settype($id, 'integer');
$result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
# now use the result
}
但当然,这只排除了一个特定的攻击,所以阅读所有其他的答案。(是的,我知道上面的代码不是很好,但它显示了具体的防御。)
你所描述的是两个独立的问题:
消毒/过滤用户输入数据。 转义输出。
1)用户输入应该总是被认为是糟糕的。
使用准备语句,或/和使用mysql_real_escape_string进行过滤绝对是必须的。 PHP还内置了filter_input,这是一个很好的开始。
2)这是一个很大的主题,它取决于输出数据的上下文。对于HTML,有一些解决方案,比如htmlpurifier。 作为经验法则,总是对输出的任何内容进行转义。
这两个问题都太大了,无法在一篇文章中详细讨论,但有很多文章会更详细地介绍:
PHP输出
更安全的PHP输出
推荐文章
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 如何从关联PHP数组中获得第一项?
- PHP/MySQL插入一行然后获取id
- 我如何排序一个多维数组在PHP
- 如何在PHP中截断字符串最接近于一定数量的字符?
- PHP错误:“zip扩展名和unzip命令都没有,跳过。”
- Nginx提供下载。php文件,而不是执行它们
- Json_encode()转义正斜杠
- 如何在PHP中捕获cURL错误
- JavaScript:客户端验证与服务器端验证
- ASP。NET身份的默认密码散列器-它是如何工作的,它是安全的?
- 如何要求一个分叉与作曲家?
- 如何在php中创建可选参数?
- 在文本文件中创建或写入/追加
- 为什么PHP的json_encode函数转换UTF-8字符串为十六进制实体?