今回は、ブログサービスを提供する場合のセキュリティを考えてみます。ブログには前回説明したWikiと似ている部分がありますので、共通点と相違点という観点から見ていきたいと思います。
Wikiとブログの共通点
両者の共通点はユーザ参加型、つまりユーザにHTMLを編集させるという点です。そのため、ブログにおける懸念事項やそれに対するセキュリティ要件もWikiと似ています。
Wikiで使われるWiki記法は、セキュリティを確保する一方で表現の自由度が落ちるという欠点がありました。ブログの場合は、より幅の広い表現ができたほうがユーザの満足度も高くなり、多くのブログユーザを獲得できるため、表現の自由度を落としたくはありません。そのためHTMLを直接編集する機能も備えておきたいというケースもあると思います。さらにスクリプトも許可したいケースもあると思います。しかしどんなHTMLやスクリプトでも許可するわけではなく、不正なスクリプトにより被害が起こらないようにしておく必要があります。
Wikiとブログの相違点
Wikiは1つのページを複数人で編集していましたが、ブログでは複数人がそれぞれ自分のページを持つことになります。各ページを編集するのは基本的に1人ですが、他の人はコメントを書き込むことができます。また、ブログは個人の重要な情報発信ツールでもありますので、検索エンジンに引っかかりやすくする必要もあります。これはSEO(Search Engine Optimization)対策と呼ばれています。SEO対策ではドメインが重要な意味を持ちます。
Googleは、ドメインが同一であれば1つのサイトとみなすようです。そして検索結果に表示されるのは、1つのサイト(1つのドメイン)につき2つまでとなっています。大手ブログサービスの中でトップ2に入ることは困難ですから、多くのブログは検索エンジンには引っかからないということになります。
一方、サブドメインを用いた場合はそれぞれが別のサイトとしてみなされますので、検索エンジンにも引っかかりやすくなると言われています。
たとえば、http://blog.example.com/というドメインでブログサービスを提供するとします。
この場合、ユーザのページは図1のようになります。
一方、サブドメインを使用した場合は図2のようになります。
どちらの方法を採るかは開発や運用等、いくつかの条件との兼ね合いで考えることになりますが、ここではセキュリティについて考えてみましょう。
ドメインとセキュリティの関係
ブログサービスを同一ドメインで提供する場合とサブドメインで提供する場合では、ユーザがスクリプトを記述するのを許可するかという点が異なっています。
同一ドメイン使用の場合
スクリプトの実行を許可すると、スクリプトを利用して認証Cookieを盗難されてしまうので、スクリプトを禁止にする必要があります。Wikiの場合はHTMLを直接編集させないようにすることでスクリプトを禁止することができましたが、ブログの場合はユーザにある程度HTMLタグを編集させる必要があるため、同じようにはいきません。
ここで、前回の例をもう一度見てみましょう。ブラウザにより構文解析が異なる例を紹介しました。
これらを構文解析する際に、ブラウザごとの挙動の違いまで考慮に入れていたのでは構文解析しきれないと説明しました。ではブログの場合はどのように処理すればよいかを考えてみます。
まず、ブラウザごとの挙動の違いなどは考えずに構文解析するようにし、不完全なHTMLタグが入力されていた場合には、タグと見なさずに構文解析します。
たとえば、1.htmlの場合は先頭のH2はタグとして不十分なため、タグとは見なしません。2行目の<b>はタグですので、許可されたタグかのチェックを行います。許可されたタグである場合には、属性のチェックに入ります。この例の場合、属性はありませんので許可されます。
このように、うまく構文解析ができない場合は安全側に倒れるように構文解析を行い、タグ、属性はホワイトリストでチェックすれば、危険を少なくした上でユーザにHTMLを記述させることができます。
サブドメイン使用の場合
認証Cookieをサブドメイン宛に発行していれば、スクリプトを悪用して認証Cookieを盗まれることはなくなります。そのためスクリプトを許可することもできます。ただし、コメント欄は不特定多数の人が書き込める上に、文字装飾や凝ったデザインをする必要性も小さいため、HTMLタグを禁止にしてしまってよいでしょう。
しかし、認証Cookieが盗まれないからといってスクリプトを許可してよいか、ということについては十分に検討する必要がありますので、以下で考えていきます。
スクリプトの脅威
認証Cookieが盗まれなければスクリプトを許可してよいか、という問題について考えてみます。もし、ユーザがアクセスするサイトの管理者が悪意を持った人であった場合、スクリプトを実行させることで以下のことが可能です。
- キーロガーの実行
- アクセス履歴の盗難
- クリップボード内の情報盗難
- ローカルネットワークへのポートスキャン
ユーザがサイトにアクセスする場合には、これらのことを覚悟の上でアクセスすることになります。もしくは、サイトの管理者を信頼して上記のようなことはしないだろうという認識でアクセスしているのだと思います。
では、どのようなサイトであれば信頼してアクセスしているのでしょうか。多くの人は、大手企業でよく耳にするサイトだからとか、すでに信頼しているサイトからリンクされているからとか、検索エンジンで最初に出てきたからという理由だと思います。反対に、スパムメールで送られてくるような見たこともないサイトにはアクセスしないでしょう。
このような信頼関係がドメインとサイト管理者、ユーザの間には存在します。この信頼関係が崩れないようにしておく必要があります。
たとえば、http://alice.example.com/というようなサブドメインでブログサービスを提供した場合、攻撃者を含むさまざまなユーザがexample.comのサブドメインを使用してサイトを開設します。上記のような攻撃による事件が起こった場合、example.comドメインの信頼性が低下します。もし企業のWebサイトがhttp://www.example.com/であった場合には、企業サイトまでアクセス低下が予想されます。
また逆に、すでに企業のWebサイトをhttp://www.example.com/で提供している場合、ユーザはある程度example.comドメインを信頼してしまっているため、攻撃者が作成した罠サイトに誘導されやすくなります。
このようなことを防ぐためには、スクリプト実行を許可する場合には他のサービスとは全く別のドメインを使用するようにしておく必要があります。