先日、ドコモが提供するスマートフォン用の回線であるSPモードを使用して普通にインターネットをしていたら接続できないページに出会いました。インターネットをしていて接続できないページがあるくらい珍しいことではないですが、接続できない状況が普通ではありませんでした。どうも特定の文字列がURLに含まれていると接続できなくなるようなのです。
例えば以下のようなURLに接続できません。
http://www.google.co.jp/search?q=%22%3E%3Cscript%3E
このようになります。
いろいろな環境から接続を試みた結果は以下です。
× Android標準ブラウザからSPモードで接続
× Firefox MobileからSPモードで接続
× パソコンのFirefoxから携帯を使用してSPモードでテザリング接続
○ Android標準ブラウザで自宅の無線LANからWi-Fi接続
このようにアプリケーションに関係なく、SPモードを介した接続のみができない状況であることから、SPモードの通信自体になんらかの原因があると考えました。どのようなURLへ接続ができないのかを検証するために、あらゆる文字列を含んだURLへそれぞれ接続できるかを試してみました。
× http://example.com/?q1="><script>
× http://example.com/?q1="><script>aaa
○ http://example.com/?q1="></script>
○ http://example.com/?q1="><body onload=alert(1)>
○ http://example.com/?q1="><script >
○ http://example.com/?q1="><scriptx>
○ http://example.com/?q1="><script
× http://example.com/?q1='><script>
○ http://example.com/?q1=><script>
× http://example.com/?q1='"><script>
× http://example.com/?q1='"''"''"'"><script>
○ http://example.com/?q1=aaa"><script>
○ http://example.com/?q1=">aaa<script>
× http://example.com/?q1="><SCRipt>
× http://example.com/?q1=1&q2="><script>
× http://example.com/?q1=1?q2="><script>
○ http://example.com/q1="><script>
× http://example.com/&q1="><script>
× http://example.com/%3Fq1="><script>
○ http://example.com/?_="><script>
× http://example.com/?1="><script>
○ http://example.com/?="><script>
これらの結果から推測できる遮断される条件を、JavaScriptの正規表現でまとめると大体以下のようになります。なお、httpsの場合はどのパターンも正常に接続できます。
また、何度か検証をしてしばらくしてから再度試してみたところ、今度は接続ができたことがありました。あれ、直った?と思いましたが、その後も何度か時間をあけて試していると、接続できたりできなかったりする場合があることに気付きました。
調査をしていくと、接続できる場合とできない場合に、規則があることがわかりました。
1.78.*.*といったIPアドレスをもらった場合には接続ができ、それ以外の1.66.*.*、183.74.*.*などといったIPアドレスでは接続ができなくなるようです。
現在この事象についてわかっているのはこれだけです。
なぜこのようなことが起きているのでしょうか。想像できるのは、SPモードというプロバイダ単位でXSS対策をしようとしているのではないか、ということです。
ただその割には、一番基本的な<script>タグですらきちんと止める気がないような遮断条件であるし、特定のIPアドレスでは遮断されなかったりで、一体何がしたいのかというかんじもあります。
まずは限定的に導入してみて、影響がどれほどのものなのかのテストでもしているのでしょうか?それとも単にバグ?
まだ理由ははっきりしませんが、攻撃への対策であるのなら、正当なリクエストにも攻撃に近い文字列は入りうるので、今のアクセスすらさせない方法はやりすぎであると思います。現段階ではまだ非常に限られた文字列だけですが、今後防御範囲を拡大しようとして、さらに副作用が広がるようなことがないことを願います。
ひとまずは、特定の文字列を含むURLに接続ができない不具合としてドコモに問い合わせてみました。1日以内に返事を頂きましたが、期待した回答がもらえなかったため、まだやりとりが続いています。また何か進展があったらここに追記したいと思います。
XSSっぽいリクエストをプロバイダが遮断するなんて前例がないなどとTwitterで言っていたら、徳丸さんが過去に発見したソフトバンクの事例に近いと、徳丸さんご本人からTwitterで教えて頂きました。ソフトバンクのガラケーでは、URL中のパーセントエンコードをしていない<>"が削除されるようです。
携帯電話事業者に学ぶ「XSS対策」 - ockeghem(徳丸浩)の日記
http://d.hatena.ne.jp/ockeghem/20100726/p1
なんか、携帯事業者はこういう方法をとりたがるんですかね。
追記 2012/6/1 19:00
いま試したところ、以前接続ができなかった1.66.*.*、183.74.*.*などといった、1.78.*.*以外のIPアドレスからも接続ができました。問題は解消されたとみてよさそう?
追記2 2012/6/12 17:00
ドコモから正式に、担当部署へ確認した結果、サーバーの設定を一部変更したことで修正したとの回答を貰いました。結局意図的だったのか不具合だったのかは不明ですが、少なくとも、修正したということは、このアプローチによるXSS対策をやめる側にたったか、単に不具合だったということを意味しており、危惧していた副作用などの問題が今後広がることはなさそうです。
例えば以下のようなURLに接続できません。
http://www.google.co.jp/search?q=%22%3E%3Cscript%3E
このようになります。
いろいろな環境から接続を試みた結果は以下です。
× Android標準ブラウザからSPモードで接続
× Firefox MobileからSPモードで接続
× パソコンのFirefoxから携帯を使用してSPモードでテザリング接続
○ Android標準ブラウザで自宅の無線LANからWi-Fi接続
このようにアプリケーションに関係なく、SPモードを介した接続のみができない状況であることから、SPモードの通信自体になんらかの原因があると考えました。どのようなURLへ接続ができないのかを検証するために、あらゆる文字列を含んだURLへそれぞれ接続できるかを試してみました。
× http://example.com/?q1="><script>
× http://example.com/?q1="><script>aaa
○ http://example.com/?q1="></script>
○ http://example.com/?q1="><body onload=alert(1)>
○ http://example.com/?q1="><script >
○ http://example.com/?q1="><scriptx>
○ http://example.com/?q1="><script
× http://example.com/?q1='><script>
○ http://example.com/?q1=><script>
× http://example.com/?q1='"><script>
× http://example.com/?q1='"''"''"'"><script>
○ http://example.com/?q1=aaa"><script>
○ http://example.com/?q1=">aaa<script>
× http://example.com/?q1="><SCRipt>
× http://example.com/?q1=1&q2="><script>
× http://example.com/?q1=1?q2="><script>
○ http://example.com/q1="><script>
× http://example.com/&q1="><script>
× http://example.com/%3Fq1="><script>
○ http://example.com/?_="><script>
× http://example.com/?1="><script>
○ http://example.com/?="><script>
これらの結果から推測できる遮断される条件を、JavaScriptの正規表現でまとめると大体以下のようになります。なお、httpsの場合はどのパターンも正常に接続できます。
location.pathname.match(/[?&][a-z0-9]+=("|')+><script>/i) || location.search.match(/[?&][a-z0-9]+=("|')+><script>/i)
また、何度か検証をしてしばらくしてから再度試してみたところ、今度は接続ができたことがありました。あれ、直った?と思いましたが、その後も何度か時間をあけて試していると、接続できたりできなかったりする場合があることに気付きました。
調査をしていくと、接続できる場合とできない場合に、規則があることがわかりました。
1.78.*.*といったIPアドレスをもらった場合には接続ができ、それ以外の1.66.*.*、183.74.*.*などといったIPアドレスでは接続ができなくなるようです。
現在この事象についてわかっているのはこれだけです。
なぜこのようなことが起きているのでしょうか。想像できるのは、SPモードというプロバイダ単位でXSS対策をしようとしているのではないか、ということです。
ただその割には、一番基本的な<script>タグですらきちんと止める気がないような遮断条件であるし、特定のIPアドレスでは遮断されなかったりで、一体何がしたいのかというかんじもあります。
まずは限定的に導入してみて、影響がどれほどのものなのかのテストでもしているのでしょうか?それとも単にバグ?
まだ理由ははっきりしませんが、攻撃への対策であるのなら、正当なリクエストにも攻撃に近い文字列は入りうるので、今のアクセスすらさせない方法はやりすぎであると思います。現段階ではまだ非常に限られた文字列だけですが、今後防御範囲を拡大しようとして、さらに副作用が広がるようなことがないことを願います。
ひとまずは、特定の文字列を含むURLに接続ができない不具合としてドコモに問い合わせてみました。1日以内に返事を頂きましたが、期待した回答がもらえなかったため、まだやりとりが続いています。また何か進展があったらここに追記したいと思います。
XSSっぽいリクエストをプロバイダが遮断するなんて前例がないなどとTwitterで言っていたら、徳丸さんが過去に発見したソフトバンクの事例に近いと、徳丸さんご本人からTwitterで教えて頂きました。ソフトバンクのガラケーでは、URL中のパーセントエンコードをしていない<>"が削除されるようです。
携帯電話事業者に学ぶ「XSS対策」 - ockeghem(徳丸浩)の日記
http://d.hatena.ne.jp/ockeghem/20100726/p1
なんか、携帯事業者はこういう方法をとりたがるんですかね。
追記 2012/6/1 19:00
いま試したところ、以前接続ができなかった1.66.*.*、183.74.*.*などといった、1.78.*.*以外のIPアドレスからも接続ができました。問題は解消されたとみてよさそう?
追記2 2012/6/12 17:00
ドコモから正式に、担当部署へ確認した結果、サーバーの設定を一部変更したことで修正したとの回答を貰いました。結局意図的だったのか不具合だったのかは不明ですが、少なくとも、修正したということは、このアプローチによるXSS対策をやめる側にたったか、単に不具合だったということを意味しており、危惧していた副作用などの問題が今後広がることはなさそうです。