Vue公式ガイド読解メモ-セキュリティ

本日2本目は「セキュリティ」を読みます。

jp.vuejs.org

「セキュリティ」は大事ですね。Vueを使った開発をする場合に、特化した観点があるのかな?その点を意識して読みたいと思います。

脆弱性の報告

  • 脆弱性が報告された場合、直ちに最大の課題になりフルタイムのコントリビューターがその解決に取り組む。(おお、優先度最高ってこうとか)
  • 常にVueとその公式ライブラリの最新バージョンを使用しアプリのセキュリティを可能な限り維持することをおすすめ

ルールNo.1:信頼できないテンプレートを絶対に使わない

  • Vueを使うときの基本的なセキュリティルール

これダメ

new Vue({
  el: 'app',
  template: '<div>' + userProvidedString + '</div>'
})

userProvidedString をtemplate内で文字列結合しているのが悪いんだろうな。 {{}}で展開したらよいのかしら。

SQLインジェクションとか、クロスサイトスクリプティングとかと同じだよな。ユーザー入力を直接利用しない、エスケープして使う、みたいな。

Vueが行っているセキュリティ対策

HTMLコンテンツ

お、正しくエスケープ処理の話。

  • テンプレートでも描画関数でもコンテンツは自動的にエスケープされる
  • エスケープ処理はtextContent等のネイティブブラウザAPIを利用して行われるため、ブラウザ自体が脆弱な場合のみ脆弱性が存在する
<h1> {{ userProvidedString }}</h1>

textContentってなんぞ。こいつか

developer.mozilla.org

Element.innerHTML は、その名が示すとおり HTML を返します。時に、 innerHTML を使用して要素内のテキストを受け取ったり書き込んだりすることがありますが、 textContent は値が HTML として解析されないので性能が良くなります。 さらに、textContent を使用することで XSS 攻撃を防ぐことができます

ふむふむ

属性のバインディング

  • 動的な属性のバインディングも自動でエスケープ処理される
  • setAttribute等のネイティブブラウザAPIを使用して行われる。
<h1 v-bind:title="userProvidedString">hello</h1>

setAttributeで属性をセットすると同様にエスケープされるんだろうな。

潜在的な危険

  • どのようなwebアプリでも、ユーザーの入力による無害化(サニタイズ)されていないコンテンツをHTML,CSS,JSとして実行できるようにすることは潜在的な危険がある
  • 可能な限り避ける必要がある

無害化(サニタイズ)なのか。サニタイズってそんな意味だったのね。(もしかしたら、エスケープ処理と同じ意味かもだが、無害化の方がイメージつけやすいな)

HTMLの挿入

  • htmlが安全なことが事前にわかっている場合は、明示的にレンダリングできる
<div v-html="userProvidedHtml"></div>
h('div', {
   domProps: {
      innerHTML: this.userProvidedHtml
   }
})

URLの挿入

<a v-bind:href="userProvidedUrl">click me</a>
  • URLを無害化して、javascript:の利用による、JS実行を防ぐ必要がある。
  • sanitize-urlというライブラリがある

www.npmjs.com

スタイルの挿入

<a
  v-bind:href="sanitizedUrl"
  v-bind:sytle="userProvidedStyle"
>
  click me
</a>
  • userProvidedStyleを利用すると、クリックジャンクのためのCSSを設置できる
  • 別ページに遷移する透明なボタンをログインボタンなどに被せることができる
  • テンプレート内でスタイルのレンダリングは辞めるべき

こんなん

<style> {{ userProvidedStyles }}</style>

防止するには

  • iframe内のサンドボックスされた場所でのみ行う
  • オブジェクト構文を利用子、特定の値だけを設定できるようにする

javascriptの挿入

  • テンプレートと描画関数は副作用をもつべきではない
  • xssを実行する方法について脆弱性レポートを受け取ることがある

「このような場合は脆弱性とみなしません」とあるが、どういうことなのかよく理解できなかった。

ベストプラクティス

  • 無害化(サニタイズ)されてないユーザー入力のコンテンツを実行することは、攻撃にさらされる可能性があるということ
  • 以下のリソースに熟知しておくことをおすすめ

html5sec.org

cheatsheetseries.owasp.org

セキュリティのキャッチアップとして、これ見るの良さげね。 ちらっとみたけど、めっちゃ量がある。。むずー

バックエンドとの調整

  • CSRF/CXSRFやXSSIなどのHTTPの脆弱性はバックエンド側で対処されるためVueで気にする必要はない
  • バックエンドチームと連携をとり、APIとの最適な対話方法(例えばフォーム送信時にCSRFトークンを送信するなど)を学ぶことをおすすめ

SSR

  • SSRを利用する場合は、上記の推奨事項に加えてセキュリティ上の懸念がある
  • SSRガイドのベストプラクティスを参照

vuejs.org

本日2本目はここまで!

やっぱりセキュリティはむずいな、でも必須要素だから、熟知できるようにしたい。

次は「リアクティブの探求」です! これは興味ある。めっちゃ長そうだけど笑