【发布时间】:2010-03-09 21:01:53
【问题描述】:
在 PHP 中,我知道使用parameterized queries 是防止 SQL 注入的最佳方法。
但是如何清理将用于其他目的的用户输入,例如:
- 向用户显示(潜在的跨站点脚本向量)
- 发送电子邮件或填写邮件正文
htmlentities() 是清理非数据库使用的最佳方式吗?这里认为最佳做法是什么?
【问题讨论】:
标签: php security user-input sanitization
在 PHP 中,我知道使用parameterized queries 是防止 SQL 注入的最佳方法。
但是如何清理将用于其他目的的用户输入,例如:
htmlentities() 是清理非数据库使用的最佳方式吗?这里认为最佳做法是什么?
【问题讨论】:
标签: php security user-input sanitization
在 php 中最好的 xss 过滤器是:
htmlspecialchars($_POST['param'],ENT_QUOTES);
您还必须对引号进行编码的原因是因为您不需要 来利用 some xss。例如这很容易受到 xss 的攻击:
print('<A HREF="http://www.xssed.com/'.htmlspecialchars($_REQUEST[xss]).'">link</a>');
在这种情况下,您不需要 来执行 javascript,因为您可以使用 onmouseover,这里是一个示例攻击:
$_REQUEST[xss]='" onMouseOver="alert(/xss/)"';
ENT_QUOTES 负责处理双引号。
电子邮件有点不同,javascript 不应该由邮件客户端执行,如果是,那么由于同源策略,您的站点不会受到影响。但为了安全起见,我仍然会使用htmlspecialchars($var,ENT_QUOTES);。然而,PHP 的 mail() 函数可以屈服于不同类型的漏洞,即所谓的 CRLF 注入。这是针对PHP-Nuke 的示例漏洞。如果你有这样的函数调用:mail($fmail, $subject, $message, $header); 那么你必须确保用户不能将\r\n 注入到 $header 中。
漏洞代码:
$header="From: \"$_GET[name]\" <$ymail>\nX-Mailer: PHP";
修补:
$_GET[name]=str_replace(array("\r","\n"),$_GET[name]);
$header="From: \"$_GET[name]\" <$ymail>\nX-Mailer: PHP";
【讨论】:
您可能还想检查 HTML Purifier,它会去除任何危险的 HTML 并保留安全输入。您还可以针对允许/禁止的 HTML 创建自己的规则。
【讨论】:
您可以首先为某些字段创建规则,例如电子邮件,它应该包含的唯一内容是字母、数字、@(at-symbol?它的真正名称)和句点,因此您无法形成 XSS因此无需使用htmlentities() 或htmlspeicalchars() 浪费资源。
【讨论】:
不,
1) 准备好的语句不是 SQL 注入的解决方案。在大多数情况下,prepared statements 意味着变量绑定,因此透明转义是防止 SQL 注入的有效方法。
2) 你不清理输入 - 你清理 输出。无论如何都要验证输入(例如,确保开始日期早于结束日期),但数据的表示应该只在它离开你的 PHP 代码的时候改变。清理直接写入 HTML 的数据的方法不同于清理写入 URL 的数据的方式不同于清理数据以将其写入 javascript 字符串变量的方式不同于清理数据以插入 SQL 语句的方式是与在将数据发送到调制解调器之前对其进行清理的方式不同的是...
...你要做什么?创建数据的所有可能表示?创建数据的通用表示?
C.
【讨论】: