Nuxt.js でsanitize(サニタイズ)

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 };

[Nuxt.js]2.9以上 Google material icon(マテリアルアイコン)を使う

久しぶりにみんな大好きGoogle fonts.のmaterial icon(マテリアルアイコン) をNuxt(@nuxt/cli v2.15.8)で使おうと思ったら、変なところでハマりました。
やり方は全部こちらに書いてありますが、インストールするパッケージを間違えたので備忘録としてまとめておきます。

https://google-fonts.nuxtjs.org/setup

2.9以下はこちらを参照ください。

パッケージをインストール

https://www.npmjs.com/package/nuxt-material-design-icons-iconfont

yarn add nuxt-material-design-icons-iconfont
// Or npm:
npm install nuxt-material-design-icons-iconfont

nuxt.config.jsに追記

modules: [
  'nuxt-material-design-icons-iconfont',
],

head内linkへの設定は適用されませんでした。何でだろう。

    {
        rel: 'stylesheet',
        href: 'https://fonts.googleapis.com/icon?family=Material+Icons',
    },

vueファイルに書く

 <span class="material-icons">chevron_right</span>

参考
How to use material design icons in nuxt | stack overflow

スタイルの変更などはこちらで詳しく解説されています。
Material Icons(Google Font Icons)の使い方を解説!表示されない時に確認すべきポイントも

NuxtにSass-loaderを導入する

NuxtだってScssを使いたい。というわけで入れます。

Webpack確認

今回Nuxt2系(v2.15.8)を入れたのですが、Webpackはデフォルトでv4が入るのでしょうか。sass-loaderのv11.0.0以降はwebpackのバージョン5以上しか対応していないようなので、v10をインストールします。

webpackの確認は

npm list webpack

これでwebpackが5以上なら普通にインストールすればいいのですが、

npm install sass-loader node-sass --save-dev

あてくしのバージョンは4だったので10をインストールしました。

npm install --save-dev sass sass-loader@10

使い方

<style lang="scss">とすればOKです。

<style lang="scss">
.main {
  .title {
    font-size: 32px;
  }
}
</style>

共通化はassets/scss/common.scss作成して、nuxt.config.jsで読み込めばOKです。
common.scss

.wrapper {
  width: 1200px;
  margin: 0 auto;
}
a {
  text-decoration: none;
  transition: 0.3s;
  color: inherit;
  &:hover {
    opacity: 0.7;
  }
}

nuxt.config.js

// Global CSS: https://go.nuxtjs.dev/config-css
css: ['ant-design-vue/dist/antd.css', '~/static/assets/scss/common.scss'],

変数を定義

先ほど作成したscssフォルダに_variable.scssを作成し変数を定義した後,npm実行。

npm i @nuxtjs/style-resources

nuxt.config.jsに追記します。

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios',
    '@nuxtjs/style-resources', // ココ!
  ],
  styleResources: {
    scss: ['~/assets/scss/_variable.scss'], // ココ!
  },