11

需要采取哪些措施来防止或阻止 PHP Web 应用程序中发生 JavaScript 注入,以免泄露敏感信息(PHP、HTML/XHTML 和 JavaScript 中的最佳实践)?

4

5 回答 5

12

一个好的第一步是应用问题 Gert G 链接中列出的方法。这详细介绍了可在不同情况下用于清理输入的各种功能,包括mysql_real_escape_stringhtmlentities()、和htmlspecialchars()strip_tags()addslashes()

更好的方法是尽可能避免将用户输入直接插入数据库。使用白名单输入验证:在您只有有限范围的选项的任何情况下,从硬编码值中进行选择以进行插入,而不是从任何面向客户端的表单中获取输入。基本上,这意味着只有您接受的某些值,而不是试图消除/对抗邪恶/格式错误/恶意的输入。

例如:如果您有一个带有项目下拉列表的表单,请不要使用此下拉列表中的输入进行插入。请记住,恶意客户端可以编辑随表单提交发送的信息,即使您认为他们只有有限的选项。相反,让下拉列表引用服务器端代码中数组中的索引。然后使用该数组来选择要插入的内容。这样,即使攻击者试图向您发送恶意代码,它也不会真正命中您的数据库。

显然,这不适用于论坛或博客等自由格式的应用程序。对于那些,您必须依靠“第一步”技术。尽管如此,仍有许多选项可以通过白名单输入验证进行改进。

您还可以尽可能为您的 sql 交互使用参数化查询(也就是带有绑定变量的准备好的语句)。这将告诉您的数据库服务器所有输入都只是一个值,因此它减轻了注入攻击的许多潜在问题。在许多情况下,这甚至可以涵盖自由形式的应用程序。

于 2010-07-21T00:00:02.637 回答
6

默认情况下,使用htmlspecialchars()处理您输出到 html 的任何值。

不使用 htmlspecialchars() 的唯一借口是当您需要输出到本身包含 html 的 html 字符串时。在这种情况下,您必须确保该字符串来自完全安全的来源。如果您没有这样的信心,那么您必须通过白名单 html 过滤器来传递它,该过滤器只允许仔细限制一组标签、属性和属性值。您应该特别注意属性值。你永远不应该让所有的东西都作为属性值传递,尤其是像 src、hef、style 这样的属性。

您应该知道您的 web 应用程序中您在不使用 htmspeciachars() 的情况下将任何内容输出到 html 的所有地方,请确保您确实需要这些地方,并注意尽管您有信心这些地方是潜在的漏洞。

如果您认为这太谨慎了:“为什么我需要 htmlspecialchar() 这个我知道它只包含整数的变量并释放所有宝贵的 CPU 周期?”

记住这一点:你不知道,你只是认为你知道,CPU 周期是世界上最便宜的东西,几乎所有的周期都会被等待数据库或文件系统甚至内存访问所浪费。

也永远不要使用黑名单 html 过滤器。Youtube 犯了这个错误,有人突然发现只有第一个<script>被删除,如果你在评论中输入第二个,你可以将任何 Javascript 注入访问者浏览器。

类似地,为了避免 SQL 注入,使用 mysql_real_escape_string() 处理所有粘合到 SQL 查询的值,或者更好地使用 PDO 准备语句。

于 2010-07-21T00:38:39.193 回答
4

如果您没有传递任何需要格式化为 html 的内容,请使用:

strip_tags() <- Eliminates any suspicious html

然后在保存到数据库之前运行以下命令进行清理

mysql_real_escape_string() 

如果您的 ajax 正在保存用户通过文本框或所见即所得输入的 html,那么请考虑使用HTMLPurifier 去除javascript 但允许 html 标签。

于 2010-07-21T00:15:41.100 回答
2

我不完全同意提供的其他答案,因此我将发布我的建议。

推荐阅读 XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

Html 注入:每当显示任何用户提交的内容时,如果在单引号内使用指定 ENT_QUOTES,则应使用htmlspecialcharshtmlentities 适当地清理它。我建议永远不要用单引号封装,而总是用双引号封装你的属性(不要省略它们)。这适用于以下情况:

<input value="<?php echo htmlspecialchars($var); ?>" />
<textarea><?php echo htmlspecialchars($var); ?></textarea>
<p><?php echo htmlspecialchars($var); ?></p>
<img width="<?php echo htmlspecialchars($var); ?>" />

Javascript 注入: 最佳实践(但并不总是实用)永远不要将用户内容回显到事件和 javascript 中。但是,如果您这样做,可以采取一些措施来降低风险。只传递整数 id。如果您需要诸如类型说明符之类的内容,请在输出前提前使用白名单和/或条件检查。可能仅在适当时强制用户内容为字母数字;preg_replace("/[^A-Za-z0-9]/", '', $string);但要非常小心你在这里允许的东西。仅包含用引号封装的内容,并注意 htmlspecialchars/htmlentities 不会在此处保护您。即使它已被翻译成 html 实体,它也会在运行时被解释。这适用于以下情况:

<a href="www.stackoverlow.com/?id=<?php echo (int)$id; ?>">Click</a>
href, src, style, onClick, etc.

不要将任何用户内容回显到其他区域,例如脚本标签的正文等,除非它已被强制为 int 或其他一些非常有限的字符集(如果您知道自己在做什么)。

SQL注入: 使用Prepared statements,将用户内容绑定到它们,并且从不直接将用户内容插入到查询中。我建议为准备好的语句创建一个类,并为您的不同基本语句类型提供帮助函数(并且在主题上,对所有数据库语句进行功能化)。如果您选择不使用准备好的语句,则使用mysql_real_escape_string()或类似的(不是 addlashes())。在存储到数据库之前尽可能验证内容,例如强制/检查整数数据类型,对类型进行条件检查等。使用正确的数据库列类型和长度。请记住,这里的主要目标是防止 sql 注入,但您也可以选择在此处进行 html/javascript 注入保护。

其他资源 我在网上做了一些研究,希望能找到一个已经公开可用的简单解决方案。我找到了 OWASP ESAPI,但它看起来已经过时了。php 版本的链接在几个地方被破坏。我相信我在这里找到了它;ESAPI PHP但同样它已经过时并且不像我希望的那么简单。但是,您可能会发现它很有用。

总而言之,永远不要假设您受到保护,例如在 onClick 属性中使用 htmlentities。您必须在正确的位置使用正确的工具,避免在错误的位置做事。

于 2017-03-30T18:39:48.733 回答
-1

这个问题已经有一些被用户接受和评价的答案。

相反,我也发布了一个答案,希望这会正常工作。

这是我测试的。

1) Use strip_tags()  //Prevent html injection

2) mysqli_real_escape_string //suspicious element

3) preg_replace("/[\'\")(;|`,<>]/", "", $value); //This will replace match

你可以试试你喜欢的。

于 2018-12-04T10:53:02.417 回答