この記事では、Coinhive事件に続いて、警察に不正プログラム(いわゆるウイルス、不正指令電磁的記録)とみなされた、無限にアラートを表示するプログラムの何が問題なのかわからなかったので一歩ずつ検証も交えて考察してみようとお思います。
不正指令電磁的記録とは
何が問題なのかを知るにはまず、警察が言っている不正指令電磁的記録、俗にいう不正プログラムの定義を理解する必要があります。
不正指令電磁的記録は不正指令電磁的記録に関する罪に定義されており、Wikipediaから引用すると
- 人が電子計算機を使用するに際してその意図に沿うべき動作をさせず、又はその意図に反する動作をさせるべき不正な指令を与える電磁的記録
- 前号に掲げるもののほか、同号の不正な指令を記述した電磁的記録その他の記録
とあります。
要するに、思った通りに動かないようにするプログラム類ってことですね。
何が問題だったのか
それでは不正指令電磁的記録が大雑把に理解できたので、何が問題なのか考えてみましょう
考えられる問題点:
- 挑発的なメッセージ
- アラートを表示する
- 連続でアラートを表示する
- 無限に繰り返す
- 無限にアラートを表示する
それでは1つずつ確認していくましょう。
1. 挑発的なメッセージ
挑発的なメッセージで、故意があるとは捉えられますが、これが直接問題に繋がるとは考えられないですね。
2. アラートを表示する
最近アラートを目にする機会は減りましたがJavaScriptに古くからある有名な機能の1つですね。ブラウザ側で実装されたインターフェースなので細かい制御ができなく、最近では自前で実装することが比較的多くなりました。
ただ少し古いページや、UXにこだわらないサイトなどで今でも目にする機会が時々あります。古くからある関数だということもあって現在でもページの動作の一部として使われているので、alertを表示すること自体が意図に反する動作とは考えづらいですね。
3. 連続でアラートを表示する
アラートの表示自体には問題がなさそうなので次は連続でアラートを表示することを考えてみましょう。
alertは同期的に実行されスクリプトの実行、正確に言うとページ全体の動作を停止させます。なのでalertが表示されている最中はページをクリックしても反応しません。それが連続で続くことでアラートをすべて閉じるまではページの操作ができなくなるので意図に反した動作のような気もします。しかしちょっと待ってください。そのページの操作ができなくなるというのはalertの仕様で、それが意図に反した動作ではないのは2で確認しましたよね。
では程度問題なのでしょうかか。1回10回100回1000回・・・のどこまでが意図に沿った動作で、どこからか意図に反する動作なのか、無限回を含めて考えるために先に無限に繰り返すことを考えてみます。
4. 無限に繰り返す
確かに無限ループfor(;;);
を実行するとCPU使用率が跳ね上がり、Coinhiveのときに警察が主張したPCが重くなる、余分な電気代がかかることはあるかも知れません(最もCPUを使用するとウイルスなのかについて議論する必要はありますが)
しかし今回のプログラム(再現)はfor(;;) alert('無限ループだよ!')
であり、ループごとにalertを表示しています。alertは同期的に実行される、つまりalertに達した時点でJavaScriptの実行が止まるので、alertを閉じるまでは無限ループの実行は止まります。
そうです。実はalertを閉じた瞬間に1回しかループが回らないのでCPUは殆ど使わないのです。実際にfor(;;);
とfor(;;) alert('無限ループだよ!')
を試しましたが、alertなしだと実行してすぐブラウザが管理するCPUが100%に達してページの動作が非常に不安定になりますが、alertありだと0%のままで、ツールを使用して可能な限り早く閉じた際かろうじて数%になる程度でした。そして通常時よりむしろalertが表示され処理がブロックされているときのほうがCPU使用率が低かったです。(Chrome最新版)
実際に検証してみたら機械レベルで高速にalertを閉じたとしても通常状態より低いCPU使用率、無限ループでCPUを使うからウイルスだ!ということが言えないことがわかりました。
5. 無限にアラートを表示する
無限の繰り返しが問題なさそうだということが分かったところで、程度問題なのかを考えてみます。
まず有限回だと理論上はアラートを閉じていけばいずれなくなるから問題なく、無限回だと永遠に表示されるから意図に反する動作という考え方ができます(昨日の記事はこの考え方に基づいて書いています)
しかしそれは理論上の話であって、仮に繰り返し回数をJavaScriptで扱える最大の数である9007199254740991回としましょう。試しに1000回を先程のツールを使って限りなく早く閉じた状態でかかった時間を流行ってみたら36秒ほどでした。少なく見積もって1000回=30秒だとすると毎分2000回で9007199254740991回だと(9007199254740991/2000/60/24/30/12≒8687499)、約900万年かかります。
上の考え方だと無限回はダメなのに、900万年もかかる有限回はOKになってしまいます。これはどう考えてもおかしいですよね。
となると無限/有限での線引ができないので、程度問題で考えるとき違法/合法の境界線を作らなくてはいけなくなります。ただどこで区切るかは非常に問題ですよね。**仮に100以上は違法だとしてなんで100なの?**となったらそこまでです。
なので程度問題で考えるのは無理があるかも知れません。程度問題もダメとなるともう八方塞がりのように感じますが、一度原点に戻ってみましょう。
不正指令電磁的記録はそもそも意図に反する動作をするプログラムだったのでそれを考えてみることにします。
6. 意図に反する動作
というわけで原点に戻ってきました。そうポイントは意図に反する動作なのです。つまりユーザーが表示することを想定していれば何ら問題はないことになりますね。
しかしこれは文字通りユーザーの意図に反する動作は違法ということで、意図していなかったと言われてしまわれるとぐうのねもでません
なのでそうならないよう、ユーザーの意図に沿うようにちゃんと何をするのかをすべて知らせて、実行するか選択してもらわないといけませんね。あれ?でもこの知らせるスクリプトの存在はどうやって知らせるのでしょうか。無限ループって怖いですね。
そんな"意図なかった"と言われる可能性があるので、もう何もできないじゃないですか...
もう目をつけられないように怯えてコードを書くことしかもうできないのです...
今回の件はブラクラ(のようなもの)だから当然だと考える人ももいると思いますが、それは今回の件の話であって、例えば誤ってバグを混入させてしまった(悪意の無い)スクリプトだとしても同じ様に適応していくと違法とみなされかねないのが問題なのです
ここまで読んですでに気づいてる人もいるかも知れませんが、今回の事件はこの前のCoinhive事件と本質は同じなのです。利用者の意図という非常に曖昧な要件の撤廃や何が不正なのかはっきりとした基準を明記などの問題の解決に繋げられるようにモロさんには頑張っていただきたいです
結論
法律に問題がある。そしてモロさんは偉大。
この記事はあくまで個人の考えに基づくものです。誤り等があったらそっと教えてくれると助かります。異論は歓迎ですがなるべく建設的な議論をしましょう!