javascriptのリアルゲーム投稿サイト -sightlasの開発ブログ

sightlasの開発ブログと称して、全然関係のない(?)技術論や日常の出来事を書きます。

JavaScript投稿を可能にすべく解決しなきゃいけないセキュリティ問題

この記事は、サイトの名前とデザインを一新した時に、最初に書くネタになると思うのですが、思い付いたので構成をメモっておきます。

 

掲示板やSNSなどにJavaScriptの投稿を許可すると、悪意あるコードが投稿される可能性があります。代表的なのが、XSS、iframeを使った他サイトの知らぬ間操作などですね。

この攻撃は、windowや、document、location、dom、ajaxなどを使って行われます。つまり、これらが使われているか調べれば、投稿されたJavaScriptに悪意ある攻撃が仕込まれているかわかるはずです。

 

ところがJavaScriptには、どんな機能を使っているか偽装する方法が用意されています。分類すると次のような感じでしょうか。

 

1.windowやdocumentなどを偽装する

 グローバルスコープでthisを使ったり、selfプロパティを使えばできます。

 

2.プロパティ名を偽装する

例えば、document.cookieは、

document[ "c" + "o" + "o" + "k" + "i" + "e"]

const c = "cookie";

document[c]

なんて書けます。

 

3.文字列からコードを実行する

eval("alert(document.cookie)")なんてのは可愛いほうで、setIntervalや、数値オブジェクトのconstructorプロパティを使った方法まであります。

d.hatena.ne.jp

 

つまり、JavaScriptの実行内容を偽装する方法は無限にある、ということですね。

特に数値のconstructorから任意のコードが実行できる仕様を作るなんてどうかしてます。JavaScript投稿サイトなど断じて許さん、という意思を感じるほどです。

 

でもこれらを解決しなければ、JavaScript投稿サイトなんて作れません。偽装の方法が無限にあるのなら、実行時に判定するしかありません。

実行時とはつまり、どの機能を使って良いかを実行直前に判定する、ゲートのような仕組みを構築するということです。

ざくっと説明すると、本物のwindowやdocumentを偽物と入れ替えるAプラン、全ての処理実行時にオブジェクト、プロパティ、引数をチェックするBプランで対処します。

Bプランは理論上、JavaScriptに限らず全てのプログラムで使えるのですが、速度上不利なので、バックアッププランとして控えているだけです。実際には使うことはないと思われます。

 

理屈上はプランAで解決できるはずなんだけど、実装はコンパイラを作るようなものなので、簡単じゃないんですよね。

もう少しで、TreeJSやangularJSに対応できる希望的観測があるので、そこまでできたら、サイトデザインを一新して、ちゃんと公開する方向に持っていきたいなー。