Vue公式ガイド読解メモ-セキュリティ
本日2本目は「セキュリティ」を読みます。
「セキュリティ」は大事ですね。Vueを使った開発をする場合に、特化した観点があるのかな?その点を意識して読みたいと思います。
脆弱性の報告
- 脆弱性が報告された場合、直ちに最大の課題になりフルタイムのコントリビューターがその解決に取り組む。(おお、優先度最高ってこうとか)
- 常にVueとその公式ライブラリの最新バージョンを使用しアプリのセキュリティを可能な限り維持することをおすすめ
ルールNo.1:信頼できないテンプレートを絶対に使わない
- Vueを使うときの基本的なセキュリティルール
これダメ
new Vue({ el: 'app', template: '<div>' + userProvidedString + '</div>' })
userProvidedString をtemplate内で文字列結合しているのが悪いんだろうな。 {{}}で展開したらよいのかしら。
SQLインジェクションとか、クロスサイトスクリプティングとかと同じだよな。ユーザー入力を直接利用しない、エスケープして使う、みたいな。
Vueが行っているセキュリティ対策
HTMLコンテンツ
お、正しくエスケープ処理の話。
- テンプレートでも描画関数でもコンテンツは自動的にエスケープされる
- エスケープ処理は
textContent等のネイティブブラウザAPIを利用して行われるため、ブラウザ自体が脆弱な場合のみ脆弱性が存在する
<h1> {{ userProvidedString }}</h1>
textContentってなんぞ。こいつか
Element.innerHTML は、その名が示すとおり HTML を返します。時に、 innerHTML を使用して要素内のテキストを受け取ったり書き込んだりすることがありますが、 textContent は値が HTML として解析されないので性能が良くなります。 さらに、textContent を使用することで XSS 攻撃を防ぐことができます
ふむふむ
属性のバインディング
<h1 v-bind:title="userProvidedString">hello</h1>
setAttributeで属性をセットすると同様にエスケープされるんだろうな。
潜在的な危険
無害化(サニタイズ)なのか。サニタイズってそんな意味だったのね。(もしかしたら、エスケープ処理と同じ意味かもだが、無害化の方がイメージつけやすいな)
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というライブラリがある
スタイルの挿入
<a v-bind:href="sanitizedUrl" v-bind:sytle="userProvidedStyle" > click me </a>
userProvidedStyleを利用すると、クリックジャンクのためのCSSを設置できる- 別ページに遷移する透明なボタンをログインボタンなどに被せることができる
- テンプレート内でスタイルのレンダリングは辞めるべき
こんなん
<style> {{ userProvidedStyles }}</style>
防止するには
- iframe内のサンドボックスされた場所でのみ行う
- オブジェクト構文を利用子、特定の値だけを設定できるようにする
javascriptの挿入
「このような場合は脆弱性とみなしません」とあるが、どういうことなのかよく理解できなかった。
ベストプラクティス
- 無害化(サニタイズ)されてないユーザー入力のコンテンツを実行することは、攻撃にさらされる可能性があるということ
- 以下のリソースに熟知しておくことをおすすめ
セキュリティのキャッチアップとして、これ見るの良さげね。 ちらっとみたけど、めっちゃ量がある。。むずー
バックエンドとの調整
- CSRF/CXSRFやXSSIなどのHTTPの脆弱性はバックエンド側で対処されるためVueで気にする必要はない
- バックエンドチームと連携をとり、APIとの最適な対話方法(例えばフォーム送信時にCSRFトークンを送信するなど)を学ぶことをおすすめ
SSR
本日2本目はここまで!
やっぱりセキュリティはむずいな、でも必須要素だから、熟知できるようにしたい。
次は「リアクティブの探求」です! これは興味ある。めっちゃ長そうだけど笑