イントロダクション
avaScript を使用して、ブラウザで現在表示しているページの URL を取得する場合には、location オブジェクトから取得するのが一般的です。
しかし、この location オブジェクトは注意して使わないと、意図しない情報を取得してしまったり、Webページにアクセスするための十分なURLを組み立てられなかったり、最悪脆弱性を作りこんでしまう恐れがあります。
その一つに、URLのドメインの前にベーシック認証の情報を埋め込めてしまうという点が挙げられます。
そして、これは最悪脆弱性につながる問題です。
(
※ 脆弱性につながる問題は、2011年12月~2012年8月頃に一部のブラウザにて発覚した問題であり、アップデートの提供されている最新の現在主流のバージョンのブラウザでは修正されています。)
以下で、詳しく見ていきます。
ベーシック認証とは?
ベーシック認証は、Web ページの閲覧を制限するための方式の一つです。
ユーザ名とパスワードによって、Web ページの閲覧を制限します。
ただし、上記の 1 つ目のリンク先に記載されているように、セキュリティ的に十分ではないため(暗号化されていないユーザ名・パスワードをインターネット上に送信するなど)、あくまで簡易的な方式だと認識しておく必要があります。
URLのドメインの前にベーシック認証の情報を埋め込める
一般的なインターネット利用者はほとんど知らない可能性があるのですが、URLのドメインの前には、ベーシック認証のログイン情報を埋め込むことができます。
参考情報
※ ここでは、www.example.com は説明用に記載したドメイン名です。実際にアクセスするためのドメイン名ではありません。
赤字太字で示した部分が、URL のドメインの前に埋め込んだ、ベーシック認証の情報です。
ここに、ベーシック認証に使用するユーザ名「user」とパスワード「password」が埋め込まれています。
通常、ベーシック認証が施された Web ページにアクセスすると、ユーザ名とパスワードを入力するように求めるダイアログが表示されますが、このようなドメインの前にベーシック認証の情報を埋め込んだ URL を使用すると、そのまま Web へアクセスすることができるようになります。
ベーシック認証を埋め込んだ URL にアクセスした場合の、location.href の値
さて、そのようなベーシック認証を埋め込んだ URL にブラウザでアクセスした場合に、location.href の値はどのようになるのでしょうか?話の流れから、なんとなくどうなるのか想像できてしまいますが、location.href の値はベーシック認証を含んだ URL になります。
例)http://user:password@www.example.com/ の場合
location.href : "http://
user:password@www.example.com/"
ベーシック認証を使ってないから関係ない?いいえ、全員に関係あります
一般的な Web サイトやブログなどを運営している場合には、上記のようにセキュリティ上の問題点もあることから、ベーシック認証を使うことはまずないと思います。ただし、このベーシック認証の情報を URL に埋め込むことは、どのページに対しても行えてしまうのです。
例えば、ベーシック認証が設定されていない Web ページの URL に、何らかのユーザ名と何らかのパスワードを埋め込んでアクセスしてみると、通常の{ベーシック認証が埋め込まれていないものと同様の}Web ページが表示されます。
それらの情報を埋め込む方法としては、ブラウザのアドレスバーに直接打ち込んでも良いですし、HTML の a タグの href 属性に埋め込んでも良いでしょう。
そして、ユーザ名:パスワード@のように、ユーザ名とパスワードが分かれていなくても、適当な文字列@ のような形式ですら、URL に埋め込めてしまうのです。
さて、そのようにしてアクセスした通常の{ベーシック認証が埋め込まれていないものと同様の}Web ページにて、location.href を確認してみると、ベーシック認証が埋め込まれた URL になっているのです。
例)http://user:password@www.example.com/ の場合
location.href : "http://
user:password@www.example.com/"
Web ページやブログによっては、現在表示されている Web ページの URL を JavaScript によって取得して、何らかの処理をしている場合があります。
そのような場合に、上記のようなベーシック認証の情報が URL に含まれていると、そのような情報が含まれていることを前提に処理していないと、意図しない結果につながることがあります。
URL のベーシック認証情報が脆弱性につながった事例
この URL のベーシック認証情報の埋め込みですが、一部のブラウザでは脆弱性を引き起こすような事例もあったようです。この情報は 2012 年 9 月ごろの情報です。
影響を受けるブラウザについては、上記の 2 つ目のリンク先に記載されています。
この脆弱性は、一部のブラウザの特定バージョンの location.href の処理に問題があったため、発生したものです。
問題のブラウザでは、URL においてベーシック認証の情報が記載されている部分に "%2F" が含まれていた場合に、 location.href で URL を取得すると、"%2F" が "/" にデコードされて返されるというものです。
そのため、location.href で取得した URL を用いて、Web ページのリロード処理や、追加情報を Web サーバから取得する処理などを行うと、意図しない Web サーバへアクセスしてしまうことになります。
どういうことなのか具体的に説明します。
正当な Web ページ(example.com)へのアクセスにおいて、次のような URL が渡されます。
URL :
http://example.net%2F@example.com/
※ example.com, example.net は説明のために使用したドメインであり、実際にアクセスするためのものではありません。
example.com のページ内で、location.href でページの URL を取得すると、問題のブラウザでは、次のような文字列が取得できます。
location.href の値:
http://example.net/@example.com/
"%2F" が "/" にデコードされることで、example.com にいたはずなのに、まるで、example.net にアクセスしているように見えてしまいます。
Web ページによっては、location.href の値を使用して、リロード処理を行っていたり、追加の情報を動的に読み込んでいることがあります。
そのような場合に、意図しないページへ飛ばされたり、意図しないデータを読み込まされたりします。
そのため、場合によってはフィッシング詐欺や個人情報・機密情報の漏えいといったものに悪用される恐れがあります。
JavaScript:location.href は使わない方が良い?
以上の問題があるため、location.href を使う場合には注意が必要です。location.href を使う場合には、ベーシック認証の情報が入り込むことを前提に使用する必要があります。
また、"%2F" が "/" にデコードされる問題を持ったブラウザでは、最新のバージョンでは問題が修正されているようです。
(Windows 版 Safari は、更新自体が止まってしまっているので、そもそも使用自体をやめなければならない状態です。)
影響を受けるブラウザとして記載されている Android 4.0.3 では、確かにこの現象が発生することを確認しました。
(手元に直ぐに用意できる実機が無かったため、開発用の Android エミュレータで確認しました。)
(Android 4.0.3 は 2011年12月ごろに提供を開始されたバージョンです。
問題が修正済みとされている Android 4.1 の
提供開始時期は 2012年7月ごろです。
従って、問題が発生するバージョンを搭載した Android 端末がプリインストールされて出荷されていたのは、今(2015年2月)から 2 年 5 か月ほど前ということでしょう。
端末によってはその後に新しいバージョンの Android にアップデートできたものもあるかと思いますが、端末によってはアップデートできないものもあるでしょう。)
確認のため、使わせていただいたのは、以下のページの挙動の再現の部分です。
@XSS (一部のブラウザのlocation.hrefがXSSを引き起こしやすいことに関する注意喚起)
http://l0.cm/atxss/
Android 4.0.3 エミュレータ ブラウザで「挙動の再現 4. の URL」へアクセス なお、このブラウザのアドレスバーでは、 @より前の部分が表示されているが、 Windows の Chrome(バージョン 40.0.2214.111 m) でアクセスしたときには、 @より前の部分は表示されていなかった |
Android 4.0.3 エミュレータ ブラウザで「挙動の再現 5. のリンク」をクリック javascript:alert(location.href) の結果が表示されている 確かに、 "%2F" が "/" にデコードされている |
もし、この "%2F" が "/" にデコードされる問題によって、脆弱性につながりそうな処理を含んでしまう場合には、脆弱性を持つ古い端末がインターネット上から消え去るまでは、location の他のプロパティを組み立てることによって、現在表示している Web ページの URL を作り出す必要がありそうです。
現在使われている iOS, Android のバージョンについての統計情報は、Google, Apple のそれぞれより、以下のページで提供されています。
iOS では、{影響を受けるとされる iOS 6.0 未満}を含む iOS 7よりも古い端末のシェアはわずか 3% です。(2015年2月現在)
iOS では影響を受けるバージョンで動作している端末はほとんどなさそうですが、Android ではまだ 1 割程度影響を受けるバージョンで動作している端末があります。
location の他のプロパティを組み立てることによって、現在表示している Web ページの URL を作り出す方法は次のとおりです。
JavaScript コード:
var url = location.protocol + "//" + location.host + location.pathname + location.search + location.hash;
このコードを使用すると、以下のアクセスした URL の場合には、次のように結果が得られます。
アクセスしたURL:
http://example.net%2F@example.com/content-path/content?query=abc#where
※ example.com, example.net は説明のために使用したドメインであり、実際にアクセスするためのものではありません。
結果:
url : "http://example.com/content-path/content?query=abc#where"
ちなみに、問題の無いブラウザで、location.href の値で取得した場合には、次のようになります。
location.href (問題の無いブラウザの場合) :
"http://example.net%2F@example.com/content-path/content?query=abc#where"
このような、URL におけるベーシック認証の情報の含有には、常に気を付けていなければなりません。
その他参考文献
関連記事
location の値を扱う上での注意
変更履歴
2015/2/14
- 脆弱性につながる問題は、2011年12月~2012年8月頃に一部のブラウザにて発覚した問題であり、アップデートの提供されている最新の現在主流のバージョンのブラウザでは修正されていることを冒頭に記載しました。
- "%2F" が "/" にデコードされる問題を持ったブラウザを搭載した Android 端末の提供開始時期を記載しました。
- "%2F" が "/" にデコードされる問題が修正されたブラウザを搭載した Android 端末の提供開始時期を記載しました。
- Android 端末の現時点でのバージョンシェアを記載しました。
- iOS 端末の現時点でのバージョンシェアを記載しました。