如何使用HTML/PHP防止XSS?

Tim*_*Tim 241 php xss

如何仅使用HTML和PHP来阻止XSS(跨站点脚本)?

我已经看过很多关于这个主题的帖子,但我还没有找到一篇清晰简明地说明如何实际防止XSS的文章.

Ali*_*xel 276

基本上,htmlspecialchars()只要您想要将某些内容输出到来自用户输入的浏览器,您就需要使用该功能.

使用此函数的正确方法是这样的:

echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
Run Code Online (Sandbox Code Playgroud)

Google Code University也有关于网络安全的这些非常有教育意义的视频:

  • htmlspecialchars或htmlentities?点击这里http://stackoverflow.com/questions/46483/htmlentities-vs-htmlspecialchars (9认同)
  • @TimTim:对于大多数情况,是的.但是,当你需要允许HTML输入时,事情变得有点棘手,如果是这种情况,我建议你使用像http://htmlpurifier.org/这样的东西. (7认同)
  • 大部分时间都是正确的,但并不是那么简单.您应该考虑将不受信任的字符串放入HTML,Js,Css中,并考虑将不受信任的HTML放入HTML中.看看这个:https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet (4认同)
  • 如果你需要接受HTML输入使用HTML Purifier,如果不使用`htmlspecialchars()`. (3认同)

Wah*_*nto 38

我最喜欢的OWASP引用之一是跨站点脚本解释,因为虽然有大量的XSS攻击向量,但以下几条规则可以大大防御其中的大多数!

这是PHP安全备忘单

  • 我也是..这是XSS Filter Evasion Cheat Sheet https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet (7认同)
  • 此页面不再存在 (2认同)

Jam*_*ack 15

其中一个最重要的步骤是在处理和/或渲染回浏览器之前清理任何用户输入.PHP有一些可以使用的" 过滤器 "功能.

XSS攻击通常具有的形式是插入一些链接到一些包含用户恶意意图的异地javascript.在这里阅读更多相关信息.

您还需要测试您的网站 - 我可以推荐Firefox附加XSS Me.

  • @TimTim - 没有.**所有用户输入**应该**始终被视为本身就是敌对的. (25认同)

web*_*lik 11

许多框架以各种方式帮助处理 XSS。当你自己滚动或者如果有一些 XSS 问题,我们可以利用filter_input_array(在 PHP 5 >= 5.2.0,PHP 7 中可用。)我通常会将这个片段添加到我的 SessionController,因为所有调用在任何其他控制器之前通过那里与数据进行交互。以这种方式,所有用户输入都在 1 个中心位置进行消毒。如果这是在项目开始时或在您的数据库中毒之前完成的,那么在输出时您应该不会有任何问题...停止垃圾进,垃圾出。

/* Prevent XSS input */
$_GET   = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST;
Run Code Online (Sandbox Code Playgroud)

以上将删除所有HTML 和脚本标签。如果您需要一个允许基于白名单的安全标签的解决方案,请查看HTML Purifier


如果您的数据库已经中毒或者您想在输出时处理 XSS,OWASP建议为 创建自定义包装函数echo,并在输出用户提供的值的任何地方使用它:

//xss mitigation functions
function xssafe($data,$encoding='UTF-8')
{
   return htmlspecialchars($data,ENT_QUOTES | ENT_HTML401,$encoding);
}
function xecho($data)
{
   echo xssafe($data);
}
Run Code Online (Sandbox Code Playgroud)


Sco*_*ski 9

按优先顺序排列:

  1. 如果您使用的是模板引擎(例如Twig,Smarty,Blade),请检查它是否提供了上下文相关的转义.我从Twig的经验中知道.{{ var|e('html_attr') }}
  2. 如果要允许HTML,请使用HTML Purifier.即使您认为您只接受Markdown或ReStructuredText,您仍然希望净化这些标记语言输出的HTML.
  3. 否则,请使用htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)并确保文档的其余部分使用与之相同的字符集$charset.在大多数情况下,'UTF-8'是所需的字符集.

另外,请确保在输出时退出,而不是在输入时退出.


Mat*_*t S 6

将此作为SO文档测试版中的合并参考进行交叉发布,该测试将脱机.

问题

跨站点脚本是Web客户端意外执行远程代码.如果任何Web应用程序从用户获取输入并直接在网页上输出,则可能会将自身暴露给XSS.如果输入包括HTML或JavaScript,则当Web客户端呈现此内容时,可以执行远程代码.

例如,如果第三方包含JavaScript文件:

// http://example.com/runme.js
document.write("I'm running");
Run Code Online (Sandbox Code Playgroud)

PHP应用程序直接输出传递给它的字符串:

<?php
echo '<div>' . $_GET['input'] . '</div>';
Run Code Online (Sandbox Code Playgroud)

如果未经检查的GET参数包含,<script src="http://example.com/runme.js"></script>则PHP脚本的输出将为:

<div><script src="http://example.com/runme.js"></script></div>
Run Code Online (Sandbox Code Playgroud)

第三方JavaScript将运行,用户将在网页上看到"我正在运行".

作为一般规则,永远不要相信来自客户的输入.每个GET,POST和cookie值都可以是任何值,因此应该进行验证.输出任何这些值时,请将它们转义,以便不会以意外方式对它们进行求值.

请记住,即使在最简单的应用程序中,数据也可以移动,并且很难跟踪所有来源.因此,始终逃避输出是最佳做法.

PHP根据上下文提供了一些转义输出的方法.

过滤功能

PHPs过滤器函数允许以多种方式对PHP脚本的输入数据进行清理验证.它们在保存或输出客户端输入时很有用.

HTML编码

htmlspecialchars将任何"HTML特殊字符"转换为HTML编码,这意味着它们将不会被处理为标准HTML.要使用此方法修复上一个示例:

<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';
Run Code Online (Sandbox Code Playgroud)

输出:

<div>&lt;script src=&quot;http://example.com/runme.js&quot;&gt;&lt;/script&gt;</div>
Run Code Online (Sandbox Code Playgroud)

<div>标记内的所有内容都不会被浏览器解释为JavaScript标记,而是作为简单的文本节点.用户将安全地看到:

<script src="http://example.com/runme.js"></script>
Run Code Online (Sandbox Code Playgroud)

网址编码

在输出动态生成的URL时,PHP提供了urlencode安全输出有效URL 的功能.因此,例如,如果用户能够输入成为另一个GET参数的一部分的数据:

<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';
Run Code Online (Sandbox Code Playgroud)

任何恶意输入都将转换为编码的URL参数.

使用专门的外部库或OWASP AntiSamy列表

有时您会想要发送HTML或其他类型的代码输入.您需要维护授权单词列表(白名单)和未授权单词(黑名单).

您可以下载OWASP AntiSamy网站上提供的标准列表.每个列表适合特定类型的交互(ebay api,tinyMCE等...).它是开源的.

现有的库可以过滤HTML并防止针对一般情况的XSS攻击,并且至少与AntiSamy列表一样易于使用.例如,您有HTML Purifier