清理用户提交内容的最佳方法? [复制]

Posted

技术标签:

【中文标题】清理用户提交内容的最佳方法? [复制]【英文标题】:Best ways to sanitize user submitted content? [duplicate] 【发布时间】:2011-08-16 05:54:21 【问题描述】:

可能重复:php: the ultimate clean/secure function

我正在开发一个使用 PHP 的实验性社交网站。所以,会有很多用户提交的数据发送到数据库中。

不久前我编写了一个自定义块脚本,它只会阻止某些字符或关键字被提交。这行得通,但它有一系列问题。

我听说 addlashes 和 mysql_real_escape_string 会这样做,但我不想做任何事情,直到我得到一些可靠的建议。

我尝试了添加斜杠,它会在 can't、don't 等处添加斜杠。我不想要那个。

我只想让我的数据库免受 xss、html、php 和 javascript 攻击。有什么建议吗?

【问题讨论】:

【参考方案1】: 来自PDO 的准备语句 filter_var() 函数 htmlspecialchars()

对于不了解 PHP 或查找有关函数的文档的人:

prepared statements - 将提供针对 SQL 注入的保护(但不针对极端愚蠢) filter_var() - 让您确保数据确实是我们的 URL 或电子邮件地址等。 htmlspecialchars() - 将 <>& 等字符转换为 html 实体,从而防止 XSS。

我真的看不出这里需要解释。

【讨论】:

如果不解释一下何时需要什么,IMO 就没有多大意义。 谢谢,对我有意义。感谢您的建议。【参考方案2】:

您应该在将任何内容输出回用户之前对其进行 HTML 转义。然后,当它输出回来时,它将是安全的。对 PHP 使用 htmlspecialchars。请参阅What are the best practices for avoiding xss attacks in a PHP site 了解更多信息并阅读OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet。

【讨论】:

谢谢,我会继续阅读的。 -1 建议在存储前转义。这有很多缺点:好的模板引擎会为您转义。如果您的数据库包含已转义的数据,这将中断。此外,如果您想在非 html 环境中显示数据,例如,您将遇到问题。 (纯文本)电子邮件。 @ThiefMaster:好点子,在进入数据库之前删除了关于转义的行。 您仍然暗示存储转义输入。仅在输出时转义/编码。并且不要使用htmlentities,而是使用htmlspecialchars SGML-Encoding 在存储到数据库之前当然不是最专业的方法。但考虑到 OP 的专业知识水平和对每个任务使用正确功能的概述,业余解决方案可能顺便说一句是更好的建议。【参考方案3】:
    对于 HTML 类型的输入,使用 HTMLPurifier 或类似工具来过滤掉不需要的标记。 在存储数据之前验证表单域 在写入数据库时​​,使用 PDO 或 MySQLi 准备好的语句。如果您正确绑定参数,这将为您处理 SQL 转义。 除非认为它是安全的,否则在显示之前转义来自 DB 的输出。

【讨论】:

【参考方案4】:

到目前为止所有好的答案,我只想补充一点,您应该确保输入数据采用所需的编码 - 您还应该规范化不同类型的换行符或完全去除控制字符,我最终经常使用以下函数:

function Filter($string, $control = true)

    $string = iconv('UTF-8', 'UTF-8//IGNORE', $string);

    if ($control === true)
    
        return preg_replace('~\pC+~u', '', $string);
    

    return preg_replace(array('~\r[\n]?~', '~[^\PC\t\n]+~u'), array("\n", ''), $string);

它将从字符串中删除所有无效的 UTF-8 数据并规范化新行。所有控制字符(制表符 (\t) 和新行 (\n) 除外)都是条带化的,如果 $control == true 这些也被剥离。


PS:从安全角度来看,这不是很有用,但有助于避免GIGO。

【讨论】:

以上是关于清理用户提交内容的最佳方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

何时最好清理用户输入?

在firebase中区分普通用户和管理员的最佳方法是啥? [复制]

是否将用户输入转换为足以清理它的整数?

PHP PDO 清理用户输入

为 C 读取用户输入字符串的最佳方法? [复制]

清除URL主题标签的最佳方法