歳末ご多端の折、皆様いかがお過ごしでしょうか。
mixiグループ Advent Calendar 2015 - Qiita 12日目ということで、簡単な内容ではございますが、ネットワーク周りのデバッグやトラブルシュートのTipsを共有させていただきます*1。
さて、ネットワーク周り、といえども簡単に手を加えられる箇所/環境であれば基本的にはデバッガで状態を追っていけば問題はありません。簡単にはprintfデバッグができれば大丈夫です。
開発環境の機能を使う
まずはブラウザの開発者ツールを使ってみましょう。
今回は以下の機能を満たす簡単な掲示板的なWebアプリケーションを用意しました。
- メールアドレスと本文から成るメッセージを投稿できる
- メールアドレスはフロント/サーバでバリデーションを行う
- 投稿/記事取得はXHRで行う
メールアドレスのバリデーションに関してですが、まじめにやると人間が死ぬことが一般によく知られていますのでここでは適当にやります。具体的にはフロントではブラウザに任せ、サーバ側では@が含まれているかどうかのみを判定する、ぐらいで良いでしょう。
アプリケーションを立ち上げ、一度まっとうな投稿を行い、次にバリデーションに引っかかるような投稿を試みたのが次の画面です。
ちゃんとバリデーションされてるようです。よかったですね。
さて、こう言ったアプリケーションでは例外がどのように処理されるのかが気になるところでしょう。具体的には
- リクエストが正しくない場合
- リクエストがタイムアウトした場合
- サーバ側の処理中にエラーが発生した場合
- レスポンスの形式が想定と違う場合
とか。そこは仕様で握ってテストでカバーすべきという声もありますが、まあ一回ぐらい実際の動作が見てみたいというのが人情でしょう。
ここではリクエストが正しくない場合の例として,不完全なメールアドレスでの投稿を検証してみましょう。開発者ツールからform要素にnovalidate属性を追加し、フロント側でのバリデーションを無効化します。
……おや。おやおや。メールアドレスがおかしいので登録されないはず,,,なのに新しい投稿が増えています。どうやらサーバ側のバリデーションに不備があるようです*2。こうして脆弱な実装が明らかになり、サービスのセキュリティは守られたのでした。めでたしめでたし。
このようにクライアント側やサーバ側に簡単に変更を加えられるのであれば比較的容易に動作確認が行えます。が、そうは問屋が卸さないといった場合もありましょう。ままならないのが人生だとはよく言ったものです。
HTTPプロキシを使う
次に制限された環境下で例外的な挙動を確認する方法として、HTTPプロキシを利用する方法を紹介します。今回は BurpProxy を使いますが、各位好きなツールを使っていただければと思います。というか好きなツールがあるということならばもはやこの記事を読む必要はないので、他の有意義なことに時間を使いましょう。
早速ですが実践です。プロキシを利用した通信を行えるようにしましょう。Burp Proxyは立ち上げると8080でリクエストを待ち受けますから、httpリクエストがそこに向かうように設定します。Macであればアプリケーションが独立してプロキシの設定を持っているFirefoxがおすすめです。
適当に設定しまして先ほどのページを更新してみます。BurpProxyのProxyタブを開くと、BurpProxyが止めているHTTP Requestが確認出来るはずです。
こんな感じ。確認出来ない場合、設定が正しく出来ていないか、BurpProxyのProxyタブ 内の Interceptタブ にある Intercept ボタンが off になっているの二通りかなと思います*3。
とりあえず最初のロードでは何もしませんので,いったんInterceptをオフにするか、ぽちぽちForwadを押していきましょう。これで準備が整いましたので、開発者ツールでやったのと同じことをBurpProxyでやってみます。
Form上では正しいメールアドレスを入力し、リクエストを送ります。Burpでリクエストをいったん止め、Paramsタブに切り替えてシュッとリクエストの内容を変更します。シュッとやりましょう。
結果がコチラです。相変わらずサーバサイドのバリデーションがざるであることが確認出来ましたね。こうして脆弱な実装が明らかになり、サービスのセキュリティは再び守られたのでした。めでたしめでたし。
今回は例としてリクエストを変更しましたが、当然レスポンスの書き換えも可能です。そのあたりはいろいろと使いながらやっていくのが良いでしょう。
httpsでも似たようなことをしたい
BurpProxyに関しては、初回起動時に内部で証明書を生成しますので、これを信頼するように設定することでhttpと同様に取り扱うことができます。iOSでの例を以前qiitaに書きましたので、ご覧いただければと思います。
おわりに
ネットワーク周りの要求が日増しに高まるこの頃、拙い記事ではございますが、この記事が皆様の一助となれば幸いです。何かと気忙しい毎日ですが、お体にお気をつけてお過ごしください。
明日は kitaindia さんの「Find Job! のリニューアルがんばりました」です。
*1:11日目は satetsu888 さんの Bitcoin faucet 〜 無料でBitcoin が手に入るカラクリ 〜 - Qiita でした
*2:時刻は既に午前2時を回っておりまして、単刀直入に申し上げますと私は眠い。眠いのでサーバ側は最低限動くところまでしか作ってません。なんでテクニックの紹介だけにせず実践までしようとしたのか、本当に理解に苦しみます。
*3:HTTP historyタブに通信した形跡があれば設定は正しいはずなので、Interceptを有効にしてもういちど更新してみましょう。うまく設定できてないパターンとしては、特定のホスト、例えばlocalhostやループバックアドレスへのリクエストについて、プロキシサーバをバイパスする設定になってることがあります。ご注意下さい