このページでは、Firefoxの拡張機能であるNoScriptについての解説を行います。 NoScriptは主に各WebサイトでのJavaScriptの制限を行う拡張機能として知られますが、 それ以外にも現代のWebブラウジングにおいて非常に役に立つ機能を搭載しています。
Giorgio Maone氏が開発したNoScriptは、 2005年05月にバージョン1.0がリリースされた後、数多くのユーザーに利用され、またメディアからも高い評価を受けています。 2007年11月現在のバージョンは1.1.8.3であり、ここでの記述もこのバージョンを元にしています。
NoScriptの主な機能としては下記のようなものがあります。
また、NoScriptはブラウザのJavaScript設定に関係なく動作しますので、JavaScriptはブラウザ自体の設定で無効にし、 NoScriptをFlashやiframeの制限などだけに利用する事も出来、 JavaScriptを全く利用するつもりの無い方にも有用なツールとなります。
この当社のサイトでは、基本的にJavaScriptとCSSが利用出来る環境を対象にしていますが、 それらが利用出来ない場合でも、重要な情報は表示されるような記述を行っています。
特にJavaScriptに関しては、携帯などそもそもJavaScriptに非対応な環境に加え、 JavaScriptをサポートするブラウザであるにもかかわらず、セキュリティ上の理由からユーザー側でJavaScriptを無効にしているケースもありますので、 その点を考慮する必要があります。
残念ながらJavaScriptの利用は、 Cross-site Scripting(XSS)に代表されるようなセキュリティ上のリスクを孕んでいますので、 JavaScriptを有効にする事を躊躇するのはある意味当然と言えるかもしれません。
が、現在のJavaScriptは、高機能なWebアプリだけでは無く、多くのWebサイトでUIの実装やコンテンツの整形にも利用されていますので、 JavaScriptを無効にしている事は、それだけ機能制限を受ける事にも繋がります。
その為、どうしても必要な場面ではブラウザの設定を変更し、JavaScriptを有効にする事が行われていますが、 一々設定を変更するのはかなりの手間であり、また設定変更を忘れたまま悪意あるサイトにアクセスする危険性もあります。
そこでサイト毎にJavaScriptなどの有効/無効を設定出来る、 FirefoxのAddOnであるNoScriptの導入をお勧めします。
NoScriptはFirefoxの拡張機能ですので、利用する為にはまずWebブラウザとしてFirefoxを利用する必要があります。
現在最もシェアの高いPCブラウザはInternetExplorer(IE)6.0であり、
IEしかサポートしていないWebサイトもありますが、
同一PC上でのWebブラウザの併用も可能ですので、この機会に、IE6よりも優れた機能を多数搭載したFirefoxをインストールされる事をお勧めします。
Firefoxのインストールはこちら
Firefoxがインストール済みならば、NoScriptのインストールは簡単です。 NoScriptのインストールページにあるインストールと書かれた緑色のボタンをクリックすると、 確認ダイアログが表示されますので、そこでインストールを選択するだけで完了です。
インストール直後の初期状態では、google.comやyahoo.comなど(google.co.jpやyahoo.co.jpは未登録)がWhitelistに登録されていますので、 それらのサイトではJavaScriptなどのスクリプトの実行が許可されています。 もちろん実行が許可されたサイトでも、ブラウザ自体の設定でJavaScriptが有効になっていなければJavaScriptは実行されません。
一方Whitelistに登録されていないその他無数のサイトでは、JavaScriptの実行は不許可になっていますので、 それらのサイトでJavaScriptが使用されている場合は、下記のような表示が画面下部にあるステータスバーの上に表示され、JavaScriptは実行されません。
JavaScriptが禁止されているサイトが十分に安全であると考え、JavaScriptを許可したい場合には、 次のいずれかの方法でそのサイトのドメイン(この例ではdistraid.co.jp)を許可します。
それぞれの方法で表示されるメニューにある、distraid.co.jpを許可か、distraid.co.jpを一時的に許可を選択する事で、 distraid.co.jpにあるJavaScriptの実行を許可出来ます。defaultではこの選択時に自動的に再読み込みが行われ、 JavaScriptが有効になったページが表示されます。
許可と一時的に許可のどちらを選択しても、Whitelistに登録しJavaScriptなどを許可しますが、 一時的に許可の場合には、そのサイトのWhitelist登録状態はブラウザを終了させるまでになり、 次回ブラウザを立ち上げた時には、そのサイトはWhitelistにもBlacklistにも登録されていない中立な(JavaScriptは実行されない)未登録状態となります。
Shift+Ctrl+\キーで、一時的に許可と未登録状態の切り替えが可能です。
NoScriptのオプション|Whitelistで、許可したいドメイン名を入力します。 この場合には、メニューで許可を選択した場合と同様に、永続的にそのサイトを許可状態として登録します。
Whitelistに登録しそのサイトのスクリプトを許可した後に、再び無効にしたい場合には、 メニューからdistraid.co.jpを禁止を選択します。許可したサイトは太字、一時的に許可したサイトは斜体になっています。
表示は禁止とありますが、これは後述するBlacklistに入れるという訳ではなく、 WhitelistにもBlacklistにも未登録な、中立な状態(JavaScriptなどは無効)に戻す事になります。
また、オプションのWhitelistの許可サイト一覧からも直接削除出来ます。
Whitelistに登録しているサイト以外では、JavaScriptなどの実行は許可されていませんので、 基本的にはBlacklistに登録する必要はありません。 が、頻繁に利用するサイト、あるいは多くのサイトから呼び出されるスクリプトを置くサイトを有効にするつもりが無い場合には、 Blacklistへ登録する意味があります。
Blacklistに登録したサイトでは、JavaScriptなどがあったとしても、それらをブロックした時の通知が表示されませんし、 メニューからそのサイトを許可するという選択が消えますので、表示上の煩わしさが解消されます。
Blacklistに登録しているサイトをBlacklistから削除したい場合、あるいはそのサイトのスクリプトを許可したい場合には、 メニューのUntrusted項目から、そのサイトを許可あるいは一時的に許可を選択します。 このような方法でBlacklistから削除した時点では、未登録ではなく許可した状態になっていますので、Blacklistからは削除したいが許可はしたくない場合は、 メニューから~を禁止を選択して、そのサイトをWhitelist未登録状態にする必要があります。
サイトで共通のJavaScriptやFramework,WebAPIなど、Webページでは多くの場合、<script>のsrc属性を使い外部JavaScriptファイルを利用します。
UIや機能実装などに使うJavaScriptは、Webページと同じサーバーあるいは同じドメインのJavaScriptファイルを使う事が一般的ですが、 アクセス解析や広告バナーでは、それらのサービスを提供する業者のサーバーに置かれているJavaScriptファイルを使用するような形態が多くなります。
NoScriptでは許可/不許可はドメイン毎に設定しますので、使用しているJavaScriptが別ドメインのサーバーに置かれ、それらの実行を許可したい場合には、 それぞれのドメインを許可する必要があります。
一部のJavaScriptが許可されている場合は、ステータスバーのアイコンがSに小さな禁止マークが付いたものになり、 ブロックされた時の通知も、JavaScriptは一部許可されていますになります。
また、外部JavaScriptが置かれているドメインを許可していない場合には、それらが実行されないのは勿論ですが、 ブラウザでのJavaScript無効と同様に、JavaScriptファイル自体の読み込みも行われませんので、余計なトラフィックが発生せずに済みます。
defaultでは、Flashやiframe(のsrcに指定されたファイル)がBlacklistに登録されたサイトに置かれたものであっても、それに関係無く全て表示されるようになっています。 よって、この例ではオプションを変更し、FlashとiframeはWhitelistに登録されていないサイトでは無効にするようにしています。
JavaScriptが無効の場合には、UIやレイアウトなどに不自然と思われる点が見受けられる場合がありますが、 無効になっている状態が明確に判るとは限りません。
一方Flashやiframeが無効になっている場合には、本来それらが表示されるエリアが空白になり、そこにNoScriptのアイコンが表示されますので、 一見して無効になっている状態が確認出来ます。
また、Flashやiframeが無効になっているエリアをクリックする事で、一時的に許可(表示)する事が出来ます。 この許可は、Whitelistに登録するという事ではなく、本来そこのエリアに表示されるべき対象を現在のタブだけで有効にするだけですので、 同じページにある同じドメインに置かれるFlashやiframeは無効のままですし、 別のタブで同じページを表示した場合には、全て無効状態となっています。
JavaScriptなどをブロックした時には、ステータスバーにアイコンが表示され状態が判りますので、 毎回画面下に出る通知が不要である場合には、スクリプトをブロックしたときに情報を表示するのチェックを外します。
ブロックした時の通知は残したいが、表示後自動的に消したい場合は、5秒後に隠すをチェックします。消えるまでの時間はabout:configのnoscript.notify.hideDelayで変更可能です。
XSS: Cross-site Script(XSS)だと疑われるリクエストが送られる場合に警告を表示。
のような記述があった場合に通知されます。この通知を実際に機能させるには、詳細設定|Untrustedにある同名の設定か、noscript.forbidMetaRefreshをチェックして有効にしておく必要があります。
また、これはNoScriptでJavaScriptが無効になっている場合にだけ機能し、ブラウザ自体の設定でJavaScriptが無効になっている場合は通知は行われません(refreshで飛ばされます)。
JavaScriptの実行が禁止された(Whitelistに登録されていない)サイトで、各種Pluginも禁止するかどうかを設定します。 また、JavaやFlashなどのPluginと共に、iframeエレメントの可否も設定可能です。
Pluginやiframeは、外部JavaScriptファイルと同様に、src属性で実際に利用するファイル(コンテンツ)を指定しますので、 その指定されたコンテンツを取得する為にリクエストする対象のドメインがWhitelistに登録されているか否かが判定基準となります。
プレースホルダーとアイコンを表示する: Pluginが無効になっている場合には、本来Flashやiframeが表示されるべき場所が空白になりNoScriptのアイコンが左上に表示されます。 また、無効になっているFlashやiframeをクリックし個別に許可する場合は、必ずこのオプションがチェックされ、プレースホルダーとアイコンが表示されている必要があります。
オブジェクトを一時的に許可する前に確認する: チェックしていなければ、無効になっているFlashやiframeを1クリックで表示出来ます。
Apply these restrictions on trusted stites too: チェックした場合は、これらの制限をWhitelistに登録されたサイトにも適用します。 つまり全てのサイトで、ここで設定したPluginやiframeが禁止になりますが、 上記のプレースホルダー設定と組み合わせ、その時に必要だと思われるPluginやiframeだけを表示させる事も出来ます。
Temporarily allow top-level sites by default: リンクをクリック、アドレスバーにURLを入力、 あるいはbookmark経由などでブラウザに表示したサイトがBlacklistに登録されていなければ、自動的に一時的に許可しWhitelistに登録します。 公式のドキュメントにもありますが、このオプションを有効にするのはお勧め出来ません。
Left clicking on... (ctrl+shift+BACK SLASH): Ctrl+Shift+\のショートカットキーで一時的に許可の登録/削除切替を行う場合に、どのレベルのドメインで許可するのかを選択します。 また、about:configのnoscript.toggle.tempをfalseに設定する事で、一時的に許可ではなく許可登録にする事も可能です。
Allow sites opend through bookmarks: bookmark経由で開いたサイトを自動的に許可します。
Firefoxのアドレスバー(ロケーションバー)にabout:configと入力する事で、Firefoxの設定画面を表示出来ます。
NoScriptの設定画面には存在しない設定や、Blacklistの直接編集などが可能です。
基本的に、XSSはサーバー側に問題がある為に発生する脆弱性ですので、 サイトの利用者である一般ユーザーが出来る対応としては限られたものになります。
NoScriptでのXSS対策も、それで完璧に安全になるという訳ではなく、ある程度安全性が向上するぐらいだと捉えるのが現実的です。 が、やはりJavaScriptを利用する場合には、NoScriptが無い場合と比較すると、格段に安全性が上がります。
NoScriptのXSS対策では、リンク元とリンク先のサイトがそれぞれWhitelistに登録されているか否か、 あるいはそのリクエストがGETかPOSTのどちらで行われるかなどが関係します。
リンク先のサイトではJavaScriptが実行されない為、XSSチェックやサニタイジングなどの処理は行われません。
GETとPOST共にXSSチェックが行われ、疑わしい場合にはサニタイジングが行われます。
GETの場合には、about:configでのnoscript.injectionCheck設定に従いますが、defaultではXSSチェックを行います。 が、POSTではチェックは行われません。
XSSチェックが行われる状況では、疑わしいquery, post dataやfragment-idはサニタイジングが行われますので、 XSS攻撃だと判定されたJavaScriptコードを含んだリクエストは無効化されます。 が、無効化を行うのはNoScriptで疑わしいと判断された場合だけですので、 XSS攻撃を意図したリクエストをスルーしてしまう危険性や、 あるいは全くXSSと関係無いリクエストをXSS攻撃と判断してしまう可能性もあります。
また、XSSチェックが行われないパターンでは、 リンク先でJavaScriptが無効になっているケースではある程度安全だと言えますが、 後述するType2のXSSには対策が不十分となる場合もあります。
Sanitize cross-site suspicious requests: リクエストをチェックし、XSS攻撃だと疑われる場合にはquery stringやfragment-idを無効化します。
Turn cross-site POST requests into data-less GET requests: POSTリクエストにおいてXSSチェックが行われる場合(リンク元が未許可サイトでリンク先が許可サイト)では、 POSTデータは破棄され、リクエストメソッドがGETリクエストとなります。
Anti-XSS Protection Exceptions: 上記のPOSTデータの破棄は確かに安全性は向上しますが、効果範囲が広すぎて弊害を生む事も十分考えられます。 そこで、リンクの元のサイトを許可する事は躊躇われるが、リンク先のサイトが十分に安全だと考えられる場合には、 正規表現を使い、リンク先をXSSチェックの対象外として登録する事が出来ます。
Type0のXSSは後述するType1やType2のように、 クライアント側から送られたデータがサーバー側で適切に処理されていない事が原因となるのではなく、 クライアントサイドのJavaScriptの処理部分に問題があるケースとなります。 また、これが他のXSSと決定的に違うのは、動的に生成されたページだけではなく、静的なページでも発生するという事です。
例として、Fragment identifier(fragment-id)と呼ばれる、URIの#以降の部分を使うケースを説明します。
http://example.com/test.php#foobarのようなURIでは、#の後のfoobarがfragment-idですが、 このURIをブラウザのアドレスバーに入力し、リクエストをサーバーに送る場合には、#以降の部分はサーバーには送られず、 http://example.com/test.phpだけのリクエストになります。 そしてブラウザでは、サーバーからレスポンス(ヘッダとHTMLなど)が返された後に、fragment-idにfoobarが指定されたものとして処理します。
http://xss.example.com/static.htmlというページに下記のようなJavaScriptがある場合、
http://xss.example.com/static.html#<script>alert(document.cookie);</script>のようなURIをブラウザで表示すると、 alert(document.cookie);というJavaScriptコードがそのまま実行されてしまいます。
fragment-idを使ったType0のXSSでは、サーバー側はstatic.htmlファイルのリクエストがあった事は判りますが、それがXSS攻撃だという事を探知するのは非常に難しくなります。
このType0のXSSに関しては、Amit Klein氏のDOM Based Cross Site Scripting or XSS of the Third Kindで詳細に書かれています。
Type1とType2のXSSの違いは、 Type1の場合(Type0も同様)には、悪意あるJavaScriptコードが実行されるのは、そのようなコードを含んだリクエストをサーバーに送り、 そのレスポンスとしてサーバーから返されたページだけであり、その攻撃を受けるのもそのリクエストを送った本人だけですが、 Type2の場合には、悪意あるコードがサーバーのDBやファイルに格納され、そのコードを含んだページがリクエストされる度にユーザーに対してXSS攻撃を行います。 よってType2の方が危険性は高くその影響も大きくなります。
Type1のXSSは、リンク先のサイトでJavaScriptが実行されなければほぼ問題はありません。 とはいえ攻撃対象となるサイトは、JavaScriptを有効にする必要があるようなサービスを提供するサイトであるケースも考えられる為、 単純にJavaScriptを無効にするという対応では不都合が出る場合があります。
そこにJavaScriptを有効にしつつXSS対策も可能なNoScriptの価値があるとも言えます。
Type1や2のXSSは既に広範に知られた脆弱性であり、ネット上で数多くの優れた文献が見付かりますので、ここでの説明は省きます。
Type0やType1のXSSでは、XSS攻撃コードを含んだリクエストをサーバー側に送るユーザーと、実際にXSS攻撃を受けるユーザーは同一ですが、 Type2の場合にはその関係が成り立ちません。
NoScriptのXSS対策では、全てのクロスサイトリクエストに対してXSSチェックが行われるわけでは無く、 特にリンク先のサイトが不許可(Whitelistに登録されていない)サイトの場合には全くチェックは行われません。 よって、この場合では例えXSS攻撃コードを含んでいたとしても、そのままリンク先のサイトへリクエストを送ってしまいます。
Type0やType1では、リンク先でJavaScriptが実行されない為にほぼ無害ですが、 Type2のXSSでは、そのようなXSS攻撃コードを含んだデータがサーバーに格納される事になり、 NoScriptのJavaScript実行制限により自分自身は安全だとしても、他のユーザーが被害を被る場合も有り得ます。
また、以前XSS攻撃コードを含んだリクエストを送ってしまったXSS Type2の脆弱性があるサイトを、 その後Whitelistに登録し許可する事で、過去に自分が送り込んでしまったXSS攻撃の被害に遭うという可能性もあります。
勿論これはNoScriptが無い場合と同様ですので、NoScriptによって状況が悪化するという事ではありませんが、 XSS対策としてNoScriptは万能では無りませんので、サイトをWhitelistに登録し許可する場合には注意が必要です。