JavaScript Obfuscatorを導入したら正体不明の¥x20が出現した…(Nuxt.js)

シェアする:

この記事をおすすめしたい人

  • JavaScript Obfuscatorを導入したら「¥x20」がたくさん表示された人
  • 「¥x20」表示だけでなくサイトの機能もなんかおかしくなった人
  • つまりオレ

JavaScript難読化モジュール「JavaScript Obfuscator」を導入したら画面にたくさんの「¥x20」が表示されるようになってしまいました。

ピンとこない人は後で画像でお見せします。

ネットで調べていても同じ症状の人を全く見かけなかったので、僕の導入手順に問題がある可能性大です。

ですが起きてしまっているものはしょうがないので、現象の確認と原因、解決策を探していきます。

WordPressの上でな!

※ このブログはまだWordPress製です

まずはブラウザ上で起きたことを確認

こんな↓風に稼動していたページが、

JavaScript ObfuscatorのWebPack版、webpack-obfuscatorを導入するとこんな↓感じになってしまいました。

「¥x20」「¥x0a」というのがそこら中に挿入されています。

webpack-obfuscatorはオプションなしで実行。 開発モード(npm run dev)での話です。

nuxt.config.jsに追加したコードはこんな感じ(公式通り)です。


const WebpackObfuscator = require("webpack-obfuscator");

export default {
  build: {
    plugins: [
      new WebpackObfuscator({})
    ],
  },
}

ページ移動が遅く、失敗する場合もある

表示がおかしいだけではなく、ページの移動がやったら遅くなりました。

中にはタイムアウト?したのか、ページ移動に失敗してエラーを吐いたり、ブラウザのタブがフリーズしてしまうケースも。

画像の表示が遅い

ページ移動をすると移動先での新規画像のロードがめちゃくちゃ遅くなりました。

数十秒かかって表示しているような画像もあります。

こんな↓ページが、

こんな↓感じに。

ロゴ部分は数十秒遅れて表示。 キャラクタの方は表示されなくなりました。

読み込まれていないCSSがある

上の例もそうなのですが、ロゴとキャラクタが表示される部分はCSSで高さをpx単位で指定していますが反映されていません。

他にも子ページ用のヘッダ↓。

CSSで指定している画像サイズが制御できていません。

これらはコンポーネントで指定しているCSSなので、コンポーネントのCSSが読み込まれないことがあるようです。

ページ移動がほんとにおっくうなので、詳細は調査できず。

難読化したいのはやまやまですが、これだけ大きなデメリットがあると導入を諦めざるをえません。

Nuxt.jsでは使えないのか…?

ソースレベルで起きていることを確認

先ほどのトップページに起きていること↓をソースを見ながら確認してみます。

僕が書いたコード

index.vueに僕が書いたコードです。


<h2 class="title">当サイトについて</h2>
<p>
これまで色々なゲームの検証、データ整理、ツール制作などを行ってきました。
</p>
<p>
目的は「自分が効率的にプレイする」だったため、基本非公開。<br>
</p>
<p>
たまにどこかで公開もしていましたが、名義はバラバラ。<br>
無名でWiki系も多いです。
</p>
<p>
提供していたサイトが閉鎖して今は失われているものもあったので、<br>
それらをできる範囲で公開していきます。<br>
</p>
<p>
ラインナップからすぐ分かりますが、アトラスが大好きです。<br>
ペルソナが入ってない辺りに頑固さを感じるでしょ。
</p>

内容はこのサイトとは関係ないので無視してください。

ちょっと恥ずかしいですが、検証のために一切修正していません。

Nuxt.jsがコンパイルしたHTMLソース

表示されたページをChrome上で右クリック「ページのソースを表示」で確認できるソースです。


<h2 class="title">当サイトについて</h2> <p>
これまで色々なゲームの検証、データ整理、ツール制作などを行ってきました。
</p> <p>
目的は「自分が効率的にプレイする」だったため、基本非公開。<br></p> <p>
たまにどこかで公開もしていましたが、名義はバラバラ。<br>
無名でWiki系も多いです。
</p> <p>
提供していたサイトが閉鎖して今は失われているものもあったので、<br>
それらをできる範囲で公開していきます。<br></p> <p>
ラインナップからすぐ分かりますが、アトラスが大好きです。<br>
ペルソナが入ってない辺りに頑固さを感じるでしょ。
</p>

HTMLタグ内の改行は維持されて、それ以外の改行が半角スペースに置き換えられています。

webpack-obfuscatorで難読化済みですが、この段階ではx20は確認できません。

ブラウザが表示しているソース

上記ソースではなくて、Chromeのデベロッパーツールで確認できるソースです。


<h2 class="title">当サイトについて</h2>\x20<p>
これまで色々なゲームの検証、データ整理、ツール制作などを行ってきました。
</p>\x20<p>
目的は「自分が効率的にプレイする」だったため、基本非公開。<br></p>\x20<p>
たまにどこかで公開もしていましたが、名義はバラバラ。<br>\x0a無名でWiki系も多いです。\x0a</p>\x20<p>
提供していたサイトが閉鎖して今は失われているものもあったので、<br>
それらをできる範囲で公開していきます。<br></p>\x20<p>
ラインナップからすぐ分かりますが、アトラスが大好きです。<br>\x0aペルソナが入ってない辺りに頑固さを感じるでしょ。\x0a</p>

「¥x20」と「¥x0a」が追加されています。

半角スペースが「¥x20」(=半角スペースのASCIIコード)へ置換。

「¥x0a」(=改行[LF]のASCIIコード)はどういうルールですかね…。 <br>を含むパラグラフで、なおかつ行末に<br>がない場所…?

ソースにはなくて、表示上は確認できるので、ブラウザがレンダリング時にJavaScriptで追加しているんだと思います。

「¥x20」が追加される原因

すいません、分からなかったです。

原因は分かりませんでしたが、解決策は調べてきたので許してください。

「¥x20」追加への対処法

これまた理由は分からないんですが、静的HTMLにビルドするとこれらの問題が全て解決しました。
(SSRでは試していません)

何故だ…。

つまり、開発時には難読化せず、出力時には難読化する、みたいな処理ができればいいことになります。

手動で対処

非常に不細工なやり方ですが、しばらくこれでやっていました。

開発時に該当部分をコメントアウトします。


const WebpackObfuscator = require("webpack-obfuscator");

export default {
  build: {
    plugins: [
      //new WebpackObfuscator({})
    ],
  },
}

出力時にはコメントアウトを解除します。

なんともエレファントなやり方な上に、解除し忘れのリスクまで抱える素晴らしさ。

どうにか自動でやる方法を考えます。

プログラムで動的に対処

build pluginsの部分は動的に処理ができなさそうなので、他の方法を考えます。 Nuxt.jsのドキュメントを読んでいるとこんなのを見つけました。

client ビルドまたは server ビルド(または dev ビルドと prod ビルドの区別)で実行する場合は、build.extendで webpack プラグインも手動で渡すことができます。

これならいけそうです。

僕はWebPackの知識もゼロなので、webpack の設定拡張を読んだり、WebPack本家のドキュメントもチラ見しましたが、結局分からず、いつものアニキに頼って得られたコードがこれ↓です。


const WebpackObfuscator = require("webpack-obfuscator");

export default {
  build: {
    extend(config, { isDev, isClient }) {
      if ( !isDev ) {
        config.plugins.push(new WebpackObfuscator({}));
      }
    }
  },
}

これで開発時には難読化なし、出力時には難読化あり、が可能になります。

難読化具合のテストをする場合でもない限り、開発中に難読化しておく必要はないと思うのでデフォルトでこれでいい気がします。

まとめ

Nuxt.jsでJavaScript Obfuscatorを導入したら「¥x20」が表示されてしまったケースの対処コードです。


const WebpackObfuscator = require("webpack-obfuscator");

export default {
  build: {
    extend(config, { isDev, isClient }) {
      if ( !isDev ) {
        config.plugins.push(new WebpackObfuscator({}));
      }
    }
  },
}

開発時(npm run dev)には難読化しないようにします。

以上、WordPressからお届けしました!

シェアする: