Nuxt.jsでv-html
を使用したら,xss 脆弱性を招くのでご遠慮くださいと怒られました。
WARN Compiled with 1 warnings
WARN ESLintError
/Users/noreen/xxx/microcms-nuxt-jamstack-blog/pages/index.vue
6:14 warning 'v-html' directive can lead to XSS attack vue/no-v-html
8:14 warning 'v-html' directive can lead to XSS attack vue/no-v-html
というわけでサニタイズします。
apiも自社開発な時などにはそこまで気にしなくてもいいですし、今回はmicroCMSからの値が返ってきていることもわかっている(ユーザからの入力が含まれる可能性はない)のですが、ライブラリがあったので試しにそちらを使おうと思います。
v-html通すまでにxssを防ぐサニタイズ
やり方全部こちらに書いてあります。
v-sanitize
vue公式が出してるのはこちら(Nuxtでは使えないかも…?エラーが消えませんでした。)
## @braintree/sanitize-url
v-sanitizeを使用した手順
インストール
npm install --save v-sanitize
pluginsに追記
グローバルで使えるよう、プラグインに追記します。
plugins/v-sanitize.js
import Vue from 'vue'
import VSanitize from 'v-sanitize'
Vue.use(VSanitize)
nuxt.config.jsに追記
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: '@/plugins/v-sanitize' },
],
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/style-resources',
[
'v-sanitize/nuxt',
{
/* options */
},
],
],
sanitize: {
/* options */
},
コンポーネントで使用
<h2>サニタイズなし</h2>
<div v-html="test"></div>
<h2>サニタイズあり</h2>
<div v-html="$sanitize(test)"></div>
<script>
export default {
data() {
return {
test: `
<p class="script" style="color: red;"><a onclick=alert("aaa")>alert</a></p>
<p><img src="http://placekitten.com/200/300"></p>
<iframe width="350" height="200" src="https://www.youtube.com/embed/SB-qEYVdvXA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`,
}
},
}
</script>
余談
sanitize-htmlはエラーが消えず断念しました。
Nuxt.jsでsanitize-htmlを使ってみる
エラー
in ./node_modules/sanitize-html/node_modules/htmlparser2/lib/esm/index.js 59:9 Module parse failed: Unexpected token (59:9) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | return getFeed(parseDOM(feed, options)); | } > export * as DomUtils from “domutils”; | // Old name for DomHandler | export { DomHandler as DefaultHandler };