ReactはXSS保護されていると彼らが言うとき、それはどういう意味ですか?


108

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

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

Reactが安全な場合、XSS攻撃はどのように機能しますか?この安全はどのようにして達成されますか?

回答:


176

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

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


13
この答えは素晴らしいです!最後にコードスニペットと参照を使用して...!ありがとうございました!
イオアナ

この回答が書かれてから、上記の例のいずれかがReactによって処理されていますか?私は、次のslideshreに読んので、私は、聞いてるのよ:slideshare.net/kseniadmitrieva/...のスライド#20で修正されたユーザ制御小道具は11月15'日に0.14を反応する
オマール

@omer no、reactはReactレベルでこの攻撃ベクトルを処理しないことにしました。ここで彼らが処理していない理由を説明する、いくつかの良いコメントしているレベルリアクトgithub.com/facebook/react/issues/3473をgithub.com/facebook/react/issues/3473#issuecomment-91349525github.com/facebook/react / issues / 3473#issuecomment-90594748
Cyber​​Panda Consulting

1
@omerあなたが参照している問題はセキュリティのバグであり、修正されましたが、私がリストしたポイント3はその問題に関連していません。反応バージョンでコードを実行することで、3番目のポイントが機能することを確認できます。
Cyber​​Panda Consulting

59

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

たとえば、次の文字列があるとします

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

この文字列を反応させようとした場合

render() {
    return (
        <div>{htmlString}</div>
    );
}

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

ソースhtmlを表示すると、

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

XSS攻撃とは何かについて、もう少し詳しく説明します。

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


編集:

注意すべきことはほとんどありませんが、Reactがエスケープするものを回避する方法があります。より一般的な方法の1つは、ユーザーがコンポーネントに小道具を定義する場合です。小道具としてユーザー入力からのデータを拡張しないでください!


13
すべてを脱出?本当に?Reactはデフォルトでは安全ではありません。手動で実行しなければならないことが多く、理解しなければならない攻撃ベクトルがあります。Reactが行うのは、{html}で挿入しようとしたときにHTMLを文字列にエスケープすることだけです。しかし、XSSを許可する方法は他にも100万ありますが、Reactはこれを保護していません。<a href="{...}" />、<img src = {...} />、<iframe src = "{...} />、および実行可能なJavaScriptを注入できる他の多数の小道具。そして、CSSスクリプトインジェクションがスタイル= {...}小道具てあり@Marty Aghajanyanことにより、以下の回答が実際に可能性のあるリスクの概要を示しています。。
アンドレ

@andree私のタイプミスを指摘してくれてありがとう。3年前の投稿です。明らかに、Reactがエスケープするものを回避する方法があり、各開発者はそれにうんざりする必要があります。
John Ruddell、2018年

@John Ruddellの回答を編集していただきありがとうございます。問題はありませんが、あなたの答えはReactを実際よりも安全に見せました。あなたの答えはトピックで最初に浮上したものの1つなので、私はそれを指摘したかっただけです。残念ながら、これは私が全体的なフロントエンド(Reactだけでなく)のセキュリティで見かける共通のテーマです-物事は表面上は安全または簡単に保護できるように見えますが、掘り下げると大きな穴があることがわかります。基本的なセキュリティの質問には、どこかで要約された見つけやすい答えが含まれている必要があります。残念ながら、最近の私の経験ではありません。
andree

ええと..セキュリティがテストされるにつれて、時間の経過とともにドキュメントが出てきます。かつて役に立った回答はそれほど役に立ちません。難しい部分は、変化するテクノロジーですべての答えを最新に保つことです
John Ruddell
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.