React が XSS 保護されているというのはどういう意味ですか? 質問する

React が XSS 保護されているというのはどういう意味ですか? 質問する

React チュートリアルでこれを読みました。これはどういう意味ですか?

React は安全です。HTML 文字列を生成しないため、XSS 保護がデフォルトになっています。

React が安全である場合、XSS 攻撃はどのように機能しますか? この安全性はどのようにして実現されますか?

ベストアンサー1

ReactJSは設計上非常に安全です。

  1. ビュー内の文字列変数は自動的にエスケープされます
  2. JSXでは、悪意のあるコードを含む可能性のある文字列ではなく、関数をイベントハンドラとして渡します。

したがって、このような典型的な攻撃は機能しない。

const username = "<img onerror='alert(\"Hacked!\")' src='invalid-image' />";

class UserProfilePage extends React.Component {
  render() {
    return (
      <h1> Hello {username}!</h1>
    );
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

しかし ...

❗❗❗警告❗❗❗

React では、自分で処理する必要がある XSS 攻撃ベクトルがまだいくつかあります。

1. XSS経由dangerouslySetInnerHTML

使用する場合、dangerouslySetInnerHTMLコンテンツに JavaScript が含まれていないことを確認する必要があります。React はここでは何もできません。

const aboutUserText = "<img onerror='alert(\"Hacked!\");' src='invalid-image' />";

class AboutUserComponent extends React.Component {
  render() {
    return (
      <div dangerouslySetInnerHTML={{"__html": aboutUserText}} />
    );
  }
}

ReactDOM.render(<AboutUserComponent />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

2. .href 属性による XSS

例1: javascript:codeの使用

「コードスニペットを実行」->「マイウェブサイト」をクリックして結果を確認します。

const userWebsite = "javascript:alert('Hacked!');";

class UserProfilePage extends React.Component {
  render() {
    return (
      <a href={userWebsite}>My Website</a>
    )
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

例 2: base64 でエンコードされたデータを使用する:

「コードスニペットを実行」->「マイウェブサイト」をクリックして結果を確認します。

const userWebsite = "data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGFja2VkISIpOzwvc2NyaXB0Pg==";

class UserProfilePage extends React.Component {
  render() {
    const url = userWebsite.replace(/^(javascript\:)/, "");
    return (
      <a href={url}>My Website</a>
    )
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

3. 攻撃者が制御する小道具によるXSS

const customPropsControledByAttacker = {
  dangerouslySetInnerHTML: {
    "__html": "<img onerror='alert(\"Hacked!\");' src='invalid-image' />"
  }
};

class Divider extends React.Component {
  render() {
    return (
      <div {...customPropsControledByAttacker} />
    );
  }
}

ReactDOM.render(<Divider />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

その他のリソースはこちら

おすすめ記事