Reactチュートリアルでこれを読みました。これは何を意味するのでしょうか?
反応は安全です。HTML文字列は生成しないため、XSS保護がデフォルトです。
Reactが安全な場合、XSS攻撃はどのように機能しますか?この安全はどのようにして達成されますか?
Reactチュートリアルでこれを読みました。これは何を意味するのでしょうか?
反応は安全です。HTML文字列は生成しないため、XSS保護がデフォルトです。
Reactが安全な場合、XSS攻撃はどのように機能しますか?この安全はどのようにして達成されますか?
回答:
ReactJSは設計上非常に安全です
このような典型的な攻撃は機能しません
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>
だが ...
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>
例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>
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>
その他のリソースはこちら
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>
Reactは基本的にそれを作成するので、レンダー関数で自分で要素を作成しない限り、マークアップを挿入できません...そのようなレンダリングを可能にする関数を持っていると言われていますdangerouslySetInnerHTML
... ここにそれについての詳細があります
注意すべきことはほとんどありませんが、Reactがエスケープするものを回避する方法があります。より一般的な方法の1つは、ユーザーがコンポーネントに小道具を定義する場合です。小道具としてユーザー入力からのデータを拡張しないでください!