ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

YAHOOの検索用APIが公開されている。開発のしかたは、こんなかんじ??

2005-12-02 18:40:43 | JavaとWeb
 YAHOOの検索用APIが、公開されています。

ここです
http://developer.yahoo.co.jp/search/


 たとえば、自社にとって、悪いうわさが流れていないかどうか、YAHOOでチェックするシステムをつくることを考えてみよう。
(別に、いいうわさでもいいし、自社にとってでなくても、平野麻樹子さんと、小笠原亜里沙さんの最新情報チェックでもかまわないけど。。)

このシステムは
(1)一定時間に、YAHOOに検索に行く
(2)受け取ったデータと、昨日までの自社の検索結果がはいったDBとくらべて、
   ・あったら、最新日付のみ更新
   ・なかったら、新規登録して、その場合は、未確認フラグをON
(3)社内のひとは、未確認フラグをたっているものを、検索して一覧でみられるようにしておいて、確認したら、未確認フラグをOFFにする。

こんなかんじのシステムだと思う。
導入時、たいへんですね。まずは、いちばんはじめに、今あるデータを全部検索して、チェックしないといけない。小笠原亜里沙さんの場合、24,700件。。。って、ほんとーかい!
 劇団ひまわり青年部の小笠原亜里沙さんは、そんなにゆーめーなのか(たぶん、そうではなく、小笠原や亜里沙で引っかかってると思う)




 まあ、そんなことはさておき、(1)の「一定時間に、YAHOOに検索に行く」ときに、そのYAHOOのAPIを使うことになる。

 YAHOOのサイトによると、アプリケーションの開発手順(以下斜体部は、ここから引用)は
1.Yahoo! JAPAN IDを取得
 まあ、YAHOOのもんをつかうときは、なんでもそーだな。
 オークションとかYAHOOブログをやってる人は、もってるよね。

2.アプリケーションIDを登録
 こういうものを登録するらしい。さっきのYAHOOサイトの左側をみると、登録できる

3.ドキュメントを読む
4.SDK(ソフトウエア開発キット)をダウンロードする

まあ、一応、仕様はよもう

で、5.コミュニティーに参加する ってあるけど、そーじゃなくって、これを、開発するには、どーすればいいのってはなしだよね。




で、その方法。
2.でアプリケーションIDを取得したら、クライアント側から、
リクエストを発行する。発行の仕方は、ここ
ここに、引数とか、書いてある。

発行先のサイトは、http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch?

YAHOOのだしてるサンプルは、
これ
http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch?appid=YahooDemo&query=%e6%b2%96%e7%b8%84&results=2

appidはアプリケーションID、上で、登録したやつ
Queryはききたいことば
resultは、返却結果の数、デフォルト10、最大50
これを、Javaでもなんでもいいから、それを使って投げると、答えはXMLで帰ってくる。
そのXMLの構造は、レスポンスフィールドにのっている
(どんなかんじか、しりたければ、上のサンプルURLをクリックしてくれ)

あ、じかんなーい。ここであっぷしちゃいます(あとで書き直すかも)

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

URLのエンコードとURLからの入力テストで問題になる~について

2005-12-02 14:41:55 | Weblog

 前のブログで、SQLインジェクションのエスケープについてかいたので、同じような感じのはなしのURLのエンコードについての話。

 むかし、どこだったかなあ。。の会社で、http://www.abcdefg.com/~12345のような、~がはいったサイトのとき、なんだったかの問題が起こるというバグがあったと思います。

 で、そこの会社の掲示板だったか、コメントを書くところだったかに「単体テストレベル以下ですよ!」と、この問題について「??本当に知っていて書いてるの??」と思える書き込みがあった気がします(記憶違いかも。。。むかしのことなんではっきりしない)。

 実は、この~(チルダです、みにくいですけど)、URLエンコード上の問題児で、単体テストでは、はじけないことがあるんですよ。。。

 ところが、URLには、よく、つかわれますよね。あるサイトにおいて、そのユーザーのホームページをあらわすとき、(上記の例だと、abcdefg.comのサイトのユーザー12345さんのホーム)は、http://www.abcdefg.com/~12345なんで、このチルダがどーしてもでてきてしまうのです(前のブログ風に言うと、字種を制限したくても、制限できない)




 で、なんで単体テストではじけないことがあるのか?

という説明の前に、どういう文字が、本来、エスケープになるのか?という話をします。

 それは、以下のサイトにくわしいです。

付録D URLエンコーディング(URLエンコード または URLエスケープ)
http://www.kinet.or.jp/hiromin/cgi_introduction/appendix/url_encode.html


 URLエンコーディングというのは、CGIなどで、値を送ったときに abc.cgi?username=%82%74%82%71%82%6b
とかなるような、%16進で現れるところのこと。

そして、
 英数字はエンコーディングしないで、そのままの値
 漢字は、エンコーディングする
とはっきりしてるからいいんだけど、チルダをふくむ記号においては

 そのサイトによると(以下斜体は引用)

英数字以外でURLエンコーディングしなくても良い文字は以下になります。
- _ . ! ~ * ' ( )

っていうことで、チルダを含んでいます。だけど、

(Internet Explorerがエンコードしない文字) * - . @ _

さらに

(Netscape Navigator や Mozilla がエンコードしない文字) * - . _

(@に注目。ねすけは、エンコードする)

 てなかんじで、チルダはエンコードされます。ただし、ライブラリとして提供されたとき、上記の理由により、チルダをエンコードしなくても、ルール違反ではありません。
 このように、チルダの扱いは(というか、 - _ . ! ~ * ' ( )の扱いは)、一定ではありません。

 そのため、チルダは、エンコードしない場合と、エンコードされる場合、どちらのケースもありうる(さらに1システム内で混在する場合もありえる)ということを意識して、システムを組んだり、テストをしたりしないといけません(つまり、チルダのテストは、必要ということ)。

 ちなみに、なぜ混在するかというと、いくら自分たちでがんばっても、そのデータを送ってくれるのはブラウザです。世界中のブラウザを確認するわけには行きません。なので、外からの入力は、混在(両方ありえる)と考えておいたほうが無難でしょう。




 ところが、仕様作成のときに、これをまったく意識しなかったり、どっちかに決めうちにして開発した場合、単体仕様書には、きめ打ちされて書いてあるか、意識されないで、その記述がないかのどっちかです。

 きめうちの場合、単体テストは、どっちかのケースしかテストしません。反対側のケースは、仕様書に書いてないのですから。

 記述がない場合も、単体テストでは、テストできないと考えたほうがいいでしょう。仕様書にかいてないのですから。
 仕様書に書いてないものは、単体では、はじけません。

  というわけで、はじめに書いた、単体テストレベル以下ですよ!」っていうのは疑問。
  たぶん、単体は通ってる。これを意識した、結合、総合テストをしていない。

 つまり、これは、結合テスト、ないしは総合テストで、チルダつきのURLを入れて、すべてのケースでうまくいくかのシナリオをだしてみないとわかんないことになります。




 ということで、URLをフォームから入れたり、CGIの引数にする場合は、チルダのテストは、しといたほうがいいです。
 URL以外のフォームでの入力の場合、 - _ . ! ~ * ' ( )のケースっていうのは、やっといたほうが、無難だと思います。

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SQLインジェクション対策をするから起こる、セカンドオーダーSQLインジェクションとその対策

2005-12-02 11:08:57 | Weblog

 またまた「日経システム構築」ネタで申し訳ないのだが今月号(2005年12月号)の31ページにセカンドオーダーSQLインジェクションという方法がある。

 これは、SQLインジェクションを防ぐのに、外部から受け取るパラメータだけ、サニタイジングしたときにおきる。

具体的に、その方法について、以下日経システム構築に書かれているのを紹介すると
(斜体部がそこからの引用で、ふつうの字体はウィリアムのいたずらの説明)

■■ 前提知識
・SQLにおいて、1行コメントを書くには -- をつけるとかける(以下コメントになる)
・文字列は'で囲む
・SQLインジェクション対策として、サニタイジングを行った場合、'はエスケープされ、'を含む文字も登録することができる

■■ 方法

・はじめに admin'-- というユーザー名と、パスワードを新規登録する
 →サニタイジングされて、admin'--が、ユーザー登録される

・次に、admin'--のパスワードを変える

 外部から受け取る値は、パスワードなので、パスワードだけがサニタイジングされる
 ユーザー名は、サニタイジングされないと、SQL文は
 update ユーザーテーブル set password='ユーザー設定パスワード'
WHERE username='ユーザー名'

 となるが、ユーザー名はadmin'--なので、結局

 update ユーザーテーブル set password='ユーザー設定パスワード'
WHERE username='admin'--'

 になる。--以下は、「前提条件」により、コメント、つまりこのSQLは、

 update ユーザーテーブル set password='ユーザー設定パスワード'
WHERE username='admin'

 という、adminのパスワードを変えていることと同じになる

・結局、admin'--に設定したパスワードがadminに設定されてしまい、他人のパスワードを変えられる

というものだそうな




 で、その対策として、「すべての箇所でサニタイジングする」っていうのが挙がってたけど、それって、それ以前に、すべての箇所でサニタイジングしないとバグになるんじゃないの?


■■ バグになりそうな例
・もし、メリーチョコレートが、ユーザー登録したら、当然Mary'sにするよねえ。。。ここに、悪意は、何一つない。あたりまえ。


・これをサニタイズすると、その例により
 Mary'sで登録される

・メリーチョコレートがパスワードを変えようとすると、上記の例により
 update ユーザーテーブル set password='ユーザー設定パスワード'
WHERE username='Mary's'

 となり、最後のs'が??となって、登録できない気が。。バグじゃない??




 なので、すべてのところでサニタイズしないと、バグになるとおもいます。

 というか、ここでの一番の問題は、上記のとおりだとすると、サニタイズでエスケープしている文字は、ほかの文字種と違う(=ほかの文字と同値ではない)わけですから、当然「ブラックボックステストで」サニタイズでエスケープされる文字について、テストされるべきです。
 そのとき、当然、ひととおりのシナリオのテストを一貫してテストすべきです。

 今のは、そのテストで、はじける例です。

 つまり、その文章のうしろに、「ソースレベルで洗い出せ」とかあるけど、それ以前に、ブラックボックステストで、エスケープする文字は、チェックしてるはずで、そういう基本的なテストは、ちゃんとしましょう。
(入力したところだけでなく、その値を使うシナリオぜんぶだよ!)




 それと、基本的に、モジュールの引数のエラーチェックっていうのは、モジュールのはじめで、必要分は、やっておくのが無難だと思います。
 というのは、そのモジュールだけ、再利用されたとき、(モジュールのはじめで引数チェックをしておかないと)モジュール引数のテストをしないで、組み込んでしまう危険があるから。

 
 あと、こういうSQLインジェクションを防ぐには、新規システムの場合、はじめから入力できる文字を絞ってしまうのがいいと思います。

 ユーザーにとって、'や-がユーザー名にいれられなくても、あんまりこまんないかも。

 あと、ご意見や、住所欄は、半角で入力されたら、自動的に全角に変換してしまい、半角を入力させないという手もある。。アメリカの人とかはどーすんだよ!と思うかも知んないけど、日本語で書かれてるホームページをみて、そこのフォームから入れているということは、みている画面で、全角に変えられても、問題ないよね(全角は表示できる画面のはず)

 入力文字を絞り込めば、テストのときも、その字種についてのチェックが減る場合もある('を入力できなくさせれば、以降のモジュールの'をテストする必要がない)。

 なんで、へらせるもんなら、へらしたほうがいいかも
 (ただし、現在動いてるものは、もうだめ(手遅れ)だけどね)



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする