magento2如何防止XSS攻击之XSS漏洞防范

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

XSS 预防策略
跨站点脚本或 XSS 是一种可以在 Web 应用程序中发现的安全漏洞。该漏洞允许攻击者将恶意代码/样式注入用户查看的网页中。 Magento 扩展开发人员应该注意这些漏洞以避免在他们的代码中引入它们。

XSS 漏洞主要有以下三种类型:

持久性 XSS – 在这种类型的漏洞中,未验证数据的来源来自数据库或后端永久存储。
反射(非持久性)XSS – 当服务器端脚本立即使用 Web 客户端提供的数据来解析并向用户显示页面而没有正确清理请求时,就会发生这种类型的漏洞。
DOM XSS – 对于此漏洞,恶意数据不会触及 Web 服务器。相反,它由 JavaScript 代码完全反映在客户端。
防止 XSS
XSS 漏洞可以通过验证和清理用户输入以及在呈现视图(HTML、移动)时清理动态值来防止。

输入处理
攻击者可以操纵任何请求数据,并且可以包含恶意值,例如:

用控制字符(“<”、“>”等)填充的表单域
标头包含虚假 ID
URI 包含虚假部分/查询参数
篡改饼干
为了解决这个问题,开发人员必须验证来自请求的任何值。

最好在尽可能接近视图上下文的情况下验证/清理值,因为只有这样您才能确定必须对动态值施加的限制,并且您不会冒着业务要求的安全要求的风险。

从商业角度来看,没有理由在用户的“关于我”部分禁止使用 < > 符号。通过在呈现 HTML 时转义控制符号,允许这些字符不会有问题。 “关于我”数据可能通过 RESTful API 传送,其中 {} 可能会导致问题。如果提前清理,用户数据将被损坏并包含 HTML 控制符号 (< >)。

输出处理
输出处理涉及在使用外部数据源渲染视图之前清理可能来自外部数据源的字符串。它是保护您的扩展程序免受 XSS 攻击的主要方法。

一般规则是:不要相信动态值。

PHTML 模板
\Magento\Framework\Escaper 类是为负责生成 HTML 的 .phtml 模板和 PHP 类提供的。它包含适用于各种上下文的 HTML 清理方法。

$escaper 局部变量在 .phtml 模板中可用。请参阅产品列表模板作为 .phtml 模板中 $escaper 用法的示例。

请参阅模板指南以阅读有关 Magento 模板的更多信息。

使用 \Magento\Framework\Escaper 或 $escaper 时:

如果某个方法指示内容被转义,则不转义:getTitleHtml()、getHtmlTitle()(标题已准备好用于HTML输出)
类型转换和 php 函数 count() 不需要转义(例如 echo (int)$var、echo (bool)$var、echo count($var))
单引号中的输出不需要转义(例如 echo ‘some text’)
没有变量的双引号输出不需要转义(例如 echo “some text”)
对于所有其他情况,使用特定于上下文的转义函数转义数据。
以下代码示例说明了模板中的 XSS 安全输出:

<?php echo $block->getTitleHtml() ?>
<?php echo $block->getHtmlTitle() ?>
<?php echo $escaper->escapeHtml($block->getTitle()) ?>
<?php echo (int)$block->getId() ?>
<?php echo count($var); ?>
<?php echo 'some text' ?>
<?php echo "some text" ?>
<a href="<?php echo $escaper->escapeUrl($block->getUrl()) ?>"><?php echo $block->getAnchorTextHtml() ?></a>

何时使用 Escaper 方法:

案例:HTML 属性中的 JSON

转义方法:escapeHtmlAttr

<div data-bind='settings: <?= $escaper->escapeHtmlAttr($myJson) ?>'></div>

案例:脚本标签内的JSON

逃生方法:无需消毒

<script>
let settings = <?= $myJson ?>
</script>

案例:不应包含 HTML 的 HTML 标签内容

转义方法:escapeHtml

传入一个可选的允许标签数组,这些标签不会被转义。

如果允许使用标签,以下属性将不会被转义:id、class、href、style 和 title。 该允许标签的任何其他属性都将被转义。

无论此数组的内容如何,都不允许嵌入、iframe、视频、源、对象、音频、脚本和 img 标签。

 <span class="label"><?php echo $escaper->escapeHtml($block->getLabel()) ?></span>
  // Escaping translation
  <div id='my-element'>
      <?php echo $escaper->escapeHtml(__('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginUrl(), $block->getCreateAccountUrl()), ['a']) ?>
  </div>

案例:某些 HTML 属性中的 URL

转义方法:escapeUrl

某些属性(如 a.href)接受各种类型的 URI,并且必须进行清理。

<a href="<?= $escaper->escapeUrl($myUrl) ?>">Click me</a>
<div attr-js-extracts="<?= $escaper->escapeHtmlAttr($myOtherUrl) ?>"></div>

案例:在escapeHtmlAttr之前,必须通过escapeJs对所有JavaScript内的属性进行转义:

转义方法:escapeJS

<div
    onclick="<?= $escaper->escapeHtmlAttr('handler("' . $escaper->escapeJs($aString) . '", ' . $escaper->escapeJs($aVar) .')') ?>">
    My DIV
</div>

案例:不得包含 JS/HTML 的 JavaScript 字符串

转义方法:escapeJS

<script>
let phrase = "Hi, my name is <?= $escaper->escapeJs($myName) ?>";
//Do not use HTMl context methods like escapeUrl
let redirectUrl = "<?= $escaper->escapeJs($myUrl) ?>";
location.href = redirectUrl;
</script>

案例:不得包含 JS/HTML 的 JavaScript 变量

转义方法:escapeJS

<script>
let <?= $escaper->escapeJs($dynamicVariable) ?> = <?= $myJson ?>;
settings.<?= $escaper->escapeJs($myProperty) ?> = true;
</script>

knockoutjs模板
在knockout模板中,您可以将 UI 组件的属性/功能绑定为元素的“内部 HTML”。 此类属性可能包含动态数据,并且必须在组件内进行清理。 请参阅 Magento 绑定语法以了解有关 UI 组件模板的更多信息。

为了通知开发人员这些属性/函数结果可能包含 HTML,Magento 要求(在静态测试的帮助下)您使用“UnsanitizedHtml”后缀命名这些属性/函数。

<div data-bind="html: propUnsanitizedHtml"></div>
<p html="returnUnsanitizedHtml()"></p>

动态创建的 DOM 元素
当使用不应该包含 HTML 的变量时,生成 DOM 元素的最安全方法是使用适当的 API 以编程方式创建它们,而不是使用 innerHtml 属性或 jQuery 的 .html() 函数。

let newDiv = document.createElement("div");
newDiv.innerText = userName;
newDiv.setAttribute("custom-attribute", myAttribute);
parentElement.appendChild(newDiv);

UI 组件数据提供程序
UI 组件数据提供程序将动态(用户生成的)数据传递给 UI 组件。 它们返回的数据被渲染以支持组件动态链接。 由于用户数据应该被视为不引用任何其他组件的文字值,因此必须禁用这些属性的呈现。 请参阅 UI 组件数据提供程序以了解有关数据提供程序和组件链接的更多信息。

$uiData = ['linkProperty' => '${ $.otherComponent.value }'];
$uiData['customer'] = $customer->getData();
//Customer data will be taken as is, linkProperty will be retrieved from otherComponent and taken as is
$uiData['__disableTmpl'] = ['customer' => true, 'linkProperty' => 1];

return $uiData;

静态测试
要检查您的 .phtml 模板是否存在 XSS 漏洞,请使用 Magento 编码标准中的 Magento2.Security.XssTemplate 嗅探。这个嗅探会发现 PHTML 模板中的所有回声调用,并确定输出是否正确转义。它涵盖以下情况:

/_ @noEscape / 输出前。输出不需要转义。测试为绿色。 / @escapeNotVerified _/ 输出前。不检查输出转义,应进行验证。测试为绿色。
名称中包含“html”的方法(例如 echo $object->{suffix}Html{postfix}())。数据已准备好用于 HTML 输出。测试为绿色。
AbstractBlock 方法escapeHtml、escapeHtmlAttr、escapeUrl、escapeJs 是允许的。测试为绿色。
允许类型转换和 php 函数 count()(例如 echo (int)$var, (bool)$var, count($var))。测试为绿色。
以单引号输出(例如 echo ‘some text’)。测试为绿色。
在没有变量的双引号中输出(例如 echo “some text”)。测试为绿色。
其他前面提到的。输出未转义。测试是红色的。

如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。