Nuxt3 Stabled のuseHead()を使ったらXSS脆弱性が顕在化した話
要するに
-
Nuxt3 Stabledで開発をしていたら、XSS脆弱性が顕在化したという話。
-
結論、基本的な点ではあるけど、ユーザーインプットが表出する場所ではちゃんとSanitizeしようねという話。
-
OG情報やページタイトルを動的生成するために、
useHead()
を使って<title>
タグと<meta>
タグに動的な値を入れていた。そこのSanitizeが欠落していたから反省しようねという話。
はじめに
本記事の投稿時現在、本記事で扱う事象は既にNuxt Communityにとって既知であり、対応を検討並びに実施している最中となります。
実際、どういう脆弱性が判明したの?
百聞は一見にしかず。実際に私の手元で顕在化したXSS脆弱性を、Playgroundにシンプルに書き直してみました。まずはこちらをご覧ください。
なお、モノホンはもう少し複雑なロジックで、description
やog:title
、og:description
も関与していました。その他のhead
タグの内容ならびにプロダクトの仕様によっても再現条件は異なるため、「こうすれば絶対問題ない!」とは中々言い難いものがあります。
どうやって判明してどう対応したの?
有志の方のご報告により、本脆弱性の顕在化は判明しました。とても感謝しております。誠にありがとうございます。
暫定対応としては、該当箇所に手実装のSanitize処理を入れるとともに、Nuxt2系含む過去プロダクトで同様の問題が発生しないことも確認しました。また、インフラやバックエンドのレイヤーでも、調査並びに対応のご協力をいただきました。
なお、当調査の中で、事象発覚並びに調査の11時間前にこちらのissuesが起票されていることを確認しました。私からは、こちらのissuesをDiscordとTwitterのNuxt Community内でのみクローズドにシェアしました。
恒久対応としては、上記issuesにある通り@vueuse/schema-orgを使用するか、Nuxt3で以下の通り議論されているuseHeadSafe()
を使うことになるとは思います。
ただ、あくまでもこれは「この事象についての恒久対応」でしかなく、Webフロントエンドのセキュリティ対策強化の方策としては、地道に積み重ねをしていくしかないと考えています。
注意喚起
本記事で紹介した脆弱性は 「OGPをユーザーごとに動的表示したい」というユースケースで顕在化しやすい と想定されます。例えばこんな感じに。
このユースケース自体は、決して珍しいものではないため、各位に置かれましても、ご留意頂けますと幸甚でございます。
振り返り
私は、VueならびにNuxtを扱うWebフロントエンドエンジニアとして、v-html
をはじめとした以下リンクにあるセキュリティの内容はある程度抑えていましたし、Webフロントのセキュリティについても、これまでの経験や学習の中で、最低限身につけてはいるつもりでした。
システム開発におけるセキュリティの重要性や、プロダクトを守るためには日々の積み重ねが必要なことも、頭の中では当然理解しているのですが、今思えば、心の何処かで「Twitterフィクションの中の出来事っしょ」と、他人事のように考えていたのかもしれないですね。
新規ライブラリの仕様に基づく挙動で、且つゼロデイに近いissuesではあったのですが、流石に反省しました。当事者になると意識がかわりますね...
以上、新年の禊でした。
Discussion
v-tokyo16 用にスライドを作成。 Reproductionも追加しました!ご来場いただきました各位におかれましてはご清聴ありがとうございました。