web-dev-qa-db-ja.com

彼らがReactはXSSで保護されていますか?

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

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

Reactが安全ですか?この安全性はどのように達成されますか?

63
user1210233

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. dangerouslySetInnerHTMLを介したXSS

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. a.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>

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

67

Reactは自動的に変数をエスケープします...悪意のあるJavascriptを使用した文字列HTMLを介したXSSインジェクションを防ぎます。当然、入力はこれとともにサニタイズされます。

たとえば、この文字列があるとしましょう

_var htmlString = '<img src="javascript:alert('XSS!')" />';
_

この文字列をreactでレンダリングしようとすると

_render() {
    return (
        <div>{htmlString}</div>
    );
}
_

_<span>_要素タグを含む文字列全体がページ上に文字通り表示されます。別名ブラウザでは、<img src="javascript:alert('XSS!')" />が表示されます

ソースhtmlを表示すると表示されます

_<span>"<img src="javascript:alert('XSS!')" />"</span>
_

XSS攻撃とは何かを詳しく説明します

Reactは基本的にそれを行うので、レンダリング関数で自分で要素を作成しない限り、マークアップを挿入できません...そのようなレンダリングを可能にする関数があると言われているので、dangerouslySetInnerHTML... ここでそれについてもう少し詳しく説明します


編集:

注意すべき点はほとんどありません。Reactエスケープ。

49
John Ruddell