在论坛中逃避输入的正确/最安全的方法是什么?

时间:2009-08-06 21:23:03

标签: php javascript mysql security

我正在使用php和mysql后端创建一个论坛软件,并想知道哪些是最安全的方式来逃避论坛帖子的用户输入。

我知道htmlentities()和strip_tags()以及htmlspecialchars()和mysql_real_escape_string(),甚至是javascript的escape(),但我不知道使用哪个以及在哪里。

处理这三种不同类型输入的最安全方法是什么(通过流程,我的意思是获取,保存在数据库中,并显示):

  1. 帖子的标题(也将是URL永久链接的基础)。
  2. 论坛帖子的内容仅限于基本文字输入。
  3. 允许使用html的论坛帖子的内容。
  4. 我希望得到一个答案,告诉我我需要组合使用多少这些逃逸函数以及为什么。 谢谢!

7 个答案:

答案 0 :(得分:8)

生成HTLM输出时(就像有人在尝试编辑帖子时将数据输入到表单的字段中,或者由于用户忘记了一个字段而需要重新显示表单时)实例),您可能会使用htmlspecialchars():它将转义<>"'和{{1} } - 取决于您提供的选项。

如果用户输入了一些标签,

&将删除标签 - 而且您通常不希望用户键入的内容只是消失;-)
至少,不是“内容”字段: - )


一旦您获得了用户在表单中输入的内容(即表单已提交时),您需要在将其发送到数据库之前将其转义。
这就是像strip_tags这样的函数变得有用的地方:它们逃避SQL的数据

您可能还想查看准备好的语句,这可能对您有所帮助;-)
with mysqli - 和with PDO

你不应该使用像mysqli_real_escape_string这样的东西:它的转义不依赖于数据库引擎;使用适合您正在使用的引擎(MySQL,PostGreSQL,...)的函数更好/更安全:它将准确知道要逃脱的内容以及如何逃避。


最后,要在页面内显示数据:

  • 对于不得包含HTML的字段,您应该使用htmlspecialchars():如果用户确实输入了HTML标记,那么这些标记将按原样显示,而不是作为HTML注入。
  • 对于可以包含HTML的字段...这有点棘手:您可能只想要允许一些标记,而strip_tags(可以做到这一点)并不是真正完成任务(它将允许标签的属性)
    • 您可能想看看一个名为HTMLPUrifier的工具:它将允许您指定应该允许哪些标记和属性 - 并且它生成有效的HTML,这总是很好^^
    • 这可能需要一些时间来计算,并且您可能不希望每次都必须重新生成该HTML;所以你可以考虑将它存储在数据库中(或者只保留干净的HTML,或者将它和非干净的HTML保存在两个单独的字段中 - 可能对于允许人们编辑帖子有用吗?)< / em>的


这些只是一些指示......希望他们帮助你: - )
不要犹豫,问你是否有更准确的问题!

答案 1 :(得分:4)

mysql_real_escape_string()可以逃避放入mysql数据库所需的一切。但是你应该使用预备语句(在mysqli中),因为它们更干净并且可以自动转义。

可以使用htmlspecialchars()从输入中删除HTML,并使用urlencode()将内容放入URL的格式中。

答案 2 :(得分:3)

你必须防御两种完全不同类型的攻击:

  • SQL注入:尝试操作数据库的输入。 mysql_real_escape_string()addslashes()旨在防范这一点。前者更好,但参数化查询仍然更好
  • 跨站点脚本(XSS):当您在页面上显示时,尝试在访问者的浏览器中执行JavaScript以执行各种操作(例如窃取用户的帐户数据)的输入。 htmlspecialchars()是防范这种情况的明确方法。

在避免XSS攻击的同时允许“一些HTML”是非常非常困难的。这是因为将JavaScript走私到HTML中的可能性很大。如果您决定这样做,安全的方法是使用BBCode或Markdown,即一组有限的非HTML标记,然后转换为HTML,同时删除所有真实的HTML htmlspecialchars()。即使这样,您也必须小心不要在链接中允许javascript:个网址。实际上允许用户输入HTML是你应该只做的absolutely crucial for your site。然后你应该花费很多的时间来确保你完全理解HTML和JavaScript和CSS。

答案 3 :(得分:1)

this post的答案是一个很好的答案

基本上,使用pdo界面来参数化查询比手动转移输入更安全,更不容易出错。

答案 4 :(得分:0)

我倾向于逃避所有在页面显示,Javascript和SQL同时存在问题的角色。它使它在Web和HTML电子邮件中可读,同时消除了代码的任何问题。 一个vb.NET代码行将是:

SafeComment = Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
                HttpUtility.HtmlEncode(Trim(strInput)), _
                  ":", "&#x3A;"), "-", "&#x2D;"), "|", "&#x7C;"), _
                  "`", "&#x60;"), "(", "&#x28;"), ")", "&#x29;"), _
                  "%", "&#x25;"), "^", "&#x5E;"), """", "&#x22;"), _
                  "/", "&#x2F;"), "*", "&#x2A;"), "\", "&#x5C;"), _
                  "'", "&#x27;")

答案 5 :(得分:0)

首先,一般建议:在数据库中插入时,不要按字面意思转义变量。有许多解决方案可以让您使用带有变量绑定的预准备语句。不明确这样做的原因是因为在你忘记它之前只是一个时间问题。

如果要在数据库中插入纯文本,请不要尝试在插入时清除它,而是在显示时清除它。也就是说,使用htmlentities将其编码为HTML(并传递正确的charset参数)。您希望在显示器上进行编码,因为您不再相信数据库内容是正确的,这不一定是给定的。

如果您正在处理富文本(html),事情会变得更复杂。从HTML中删除“邪恶”位而不破坏消息是一个难题。实际上,您必须采用标准化解决方案,例如HTMLPurifier。但是,这通常太慢而无法在每个页面视图上运行,因此在写入数据库时​​您将被迫执行此操作。您还必须确保用户可以看到他们的“已清理”的HTML并更正已清理的版本。

绝对尽量避免在任何步骤“滚动自己的”过滤器或编码解决方案。这些问题非常棘手,而且您可能会忽略一些具有重大安全隐患的小细节。

答案 6 :(得分:0)

我是第二个Joeri,不要自己动手,去这里看看一些可能的XSS攻击

http://ha.ckers.org/xss.html

htmlentities() - &gt;将文本转换为html,将字符转换为实体。如果使用UTF-8编码,则使用htmlspecialchars()代替,因为不需要其他实体。这是对XSS的最佳防御。我在输出的每个变量上使用它,无论类型或原点如何,除非我打算将它作为html。只有很小的性能成本,它比试图找出需要转义的东西和不需要的东西更容易。

strip_tags() - 通过删除所有html标记将html转换为文本。使用此选项可确保输入中没有任何令人讨厌的东西作为转义输出的附件。

mysql_real_escape_string() - 为mysql转义一个字符串,可以防止来自小Bobby表的SQL注入(最好使用mysqli和prepare / bind,因为为你做了逃避,你可以避免大量乱码串联)< / p>

给出的建议主要是避免HTML输入,除非它是必不可少的并且选择BBCode或类似的(如果需要的话,自己动起来)确实非常合理。