kintoneのプラグインはzipを解凍すれば中身のJavaScriptを読むことができます。自分でプラグインを配布する立場になると、このコードを隠せないかと考える方もいると思います。
結論から書くと、隠すことはできません。できるのは読みにくくすることまでです。この記事では、難読化で何ができて何ができないのかを整理します。実際の手順と、最終的に採用しなかった判断も書きます。
前提:ブラウザで動く以上、コードは隠せない
プラグインのJavaScriptはブラウザ上で実行されます。実行するためには必ずブラウザに読み込まれる必要があり、読み込まれたコードは開発者ツールから参照できます。
zipの側で何をしても、この事実は変わりません。ソースコードを完全に秘匿する手段は存在しない、というのが出発点になります。
難読化でできること
できるのは、読む気を失わせるところまでです。
具体的な手法としては、複数ファイルをひとつにまとめ、改行や空白を削除し、変数名や関数名を意味を持たない短い文字列に置き換えます。いわゆるminifyと難読化です。
たとえばこういったコードが、
function isDropdownSelectionAllowed(record, rule) {
const cell = record[rule.dropdownFieldCode];
// ...
}
こうなります。
function n(t,e){const o=t[e.dropdownFieldCode];...
全体が1行に潰れ、変数名は n や t に置き換わります。読めないわけではなく、時間をかければ追えます。ただし通常は追う気が起きません。難読化の効果はその程度のものだと理解しておくのが正確です。
実際にやってみる
難読化には javascript-obfuscator を使いました。Node.jsが入っていれば、コマンド1つで導入できます。
npm install -g javascript-obfuscator
対象のファイルを指定して実行します。
javascript-obfuscator ./src/js/desktop.js --output ./src/js/desktop.min.js --compact true
これで desktop.min.js が出力されます。オプションを付けると難読化の強度を上げられますが、強くするほど実行速度が落ちるため、まずは既定に近い設定で試すのがいいと思います。
なお、難読化後のファイルは編集できません。元のソースは必ず残しておき、そこから難読化した出力を別名で吐く運用になります。
出力したファイルをプラグインに組み込むときは、manifest.jsonの参照先を書き換える必要があります。ここを忘れると難読化前のファイルが読み込まれたままになります。
"desktop": {
"js": ["js/desktop.min.js"]
}
あとは通常どおりパッケージし直すだけです。
cli-kintone plugin pack --input ./src/manifest.json --output ./plugin.zip --private-key ./plugin.ppk
この状態でアプリに入れ直したところ、難読化したコードでも問題なく動作しました。
注意点:文字列リテラルは残る
ひとつ気をつける点があります。置き換えられるのは変数名や関数名だけで、文字列リテラルはそのまま残ります。
kintoneプラグインでは、設定を保存するときのキーやフィールドコードを文字列として扱います。これらが書き換わると動作しなくなりますが、難読化ツールは文字列を触らないため壊れません。
裏を返すと、文字列として書かれている設定キーやフィールドコードは、難読化しても読めるままです。何を隠したいのかによっては、期待した効果が得られない可能性があります。
難読化でできないこと
ここが一番重要な部分です。
読みにくくすることと、書き換えられないようにすることは別の話です。
たとえばプラグイン内に「この条件を満たしていたら動作する」という判定を書いたとします。これを難読化しても、判定処理はブラウザに読み込まれる場所に置かれたままです。読みにくくなるだけで、書き換え可能な場所にあるという事実は変わりません。
つまり、守りたいロジックがあるならブラウザ側に置くべきではない、という話になります。難読化はこの問題を解決しません。難読化は保護のための仕組みではなく、あくまで可読性を下げるための仕組みです。
「難読化すれば守れる」という認識でいると判断を誤るので、ここは切り分けておく必要があります。
.ppkが守っているもの
関連して、プラグインのパッケージ時に使う秘密鍵(.ppk)についても整理しておきます。
この鍵はプラグインの識別に使われます。誰かが中身をコピーして自分の鍵でパッケージし直しても、kintoneからは別のプラグインとして扱われます。
つまり鍵が防いでいるのは、中身の流用ではなく、同一プラグインとしてのなりすましです。この違いを理解すると、鍵を外部に出してはいけない理由もはっきりします。難読化と鍵は守る対象が違う、と整理しておくと混同しません。
採用しなかった理由
手順を確認したうえで、配布しているプラグインには難読化を入れていません。理由は2つあります。
ひとつは、隠す必要のあるコードを書いていないためです。公開されている仕組みを組み合わせているだけで、模倣されて困る独自のロジックは含まれていません。読まれても実害がありません。
もうひとつは、読める状態のほうが利用者にとって安心材料になると考えたためです。業務システムに組み込むファイルの中身を確認できることには価値があります。難読化された1行のコードより、読めるコードのほうが導入判断はしやすいはずです。
まとめ
難読化について整理すると、次のようになります。
- ブラウザで動く以上、コードの秘匿はできない
- 難読化でできるのは可読性を下げることまで
- 文字列リテラルは置換されないため、設定キーなどは読める
- ロジックの保護が目的なら、そもそもブラウザ側に置かない設計が必要
- .ppkが守るのは中身の流用ではなく、なりすまし
難読化を入れるかどうかは、隠したいものが本当にあるかで決めるのが妥当だと思います。判断の前に一度手元で通しておくと、効果の範囲が具体的に分かるのでおすすめです。