まいどどうも

本日もどうもありがとう!
朝から小学校のころの幼なじみと喫茶店行ってました。
気が付いたら時が経ってました。




コードを守れ――開発者のための17のヒント【前篇】

Computerworld 3月1日(金)0時20分配信

あなたのコードは大丈夫?

 Webがらみのおそろしい事件話は、昨今さらなる惨状を呈するようになっている。初めは数件のクレジットカード番号の盗難程度だったが、いつしかその被害規模は数千単位に膨れ上がった。今日では、何百万もの金融データがセキュリティ侵害にさらされていると言われ、潜在的な脅威に対するわれわれの感覚も麻痺してしまった。だが、クレジットカード番号などはワルモノが狙っているターゲットの上っ面にすぎない。サイバー戦争の研究所が教えてくれたシナリオは、もっと物騒な代物だった。

 セキュアなコードの記述は、最初のループが形成されるはるか以前に始まっている。コードを保護するプロセスは決して単純ではない。安全性にばらつきのあるコードを平均化するには、アーキテクトやエンジニア、監査担当者、マネージャーらが、コードのあらゆる部位において何らかのトラブルが発生する可能性を常に想定しておく必要がある。攻撃者が仕掛けてくるペテンをすべて予想するのは困難でも、攻撃を受けうる箇所を減らし、穴をふさぎ、侵害がもたらす影響に対して守りを固めるため、できることは全部やっておかねばならないのだ。


 本稿では、より安全なコードを生成する17のヒントを紹介する。完全なリストからはほど遠いものの、これらに留意すれば少しはゴールに近づけるはずだ。

ヒントその1:インプットの検査は厳格に

 攻撃者がマシンへ侵入する場合、そこには必ず道が必要になる。最も簡単な方法は、コードが開けてくれるドアから入っていくというものだ。インターネットからのインプットを受け取るソフトウェアであれば、だれかがこっそり何かを潜り込ませようとしても不思議ではない。

 バッファ・オーバフローはそうした手口の古典と言える。不精なCプログラマが記述したコードが、C言語が文字列の最後の符号として規定している0(ゼロ)が現れるまで一連の文字列を際限なく取り込んだとき、この脆弱性は発動する。ゼロ終端する文字列を送るまでの間、意図的に長いデータ・パケットを送信してプログラミング・スタックおよびメモリを上書きできることを、攻撃者らは大昔に突き止めていた。悪知恵を利かせてコードを記述すれば、何でも好きに操れるし、書き換えられるのだ。

 ほかにも、SQLインジェクションが侵入の常套手段として知られている。Webフォームがユーザーに郵便番号を尋ねるとしよう。ユーザーが数字を入力し、フォームはこれを手順通りSQLクエリへペーストする。ずる賢いハッカーはここに余分な文字を足して、データベース検索以上のことをできるよう策を巡らせる。ソフトウェアが無分別にすべてのインプットを取り込むと、当該のSQLクエリをデータベースへ直接送ることになってしまう。

 入力されるデータのサイズと構造を検査し、インターネットの向こう側にいるだれかを何があってもけっして信じないようにすれば、こうした問題は解消できる。

 プログラマは一般的に、柔軟性は高く、強制力は弱いコードを提供したいと考えるものである。データを1ビット残らずチェックするのは、ソフトウェアにとっては時間のムダだし、プログラマにとっては気の遠くなる作業だ。だが、XMLやJSONなどのデータ転送言語を使用するだけでは、データをこれらの問題から確実に守ることはできない。プログラマがコードを安全に保つためには、やはり徹底的なチェックを行うしかないのである。

ヒントその2:必要なものだけを保存し、それ以上のものには手を出すな

 顧客に住所を尋ねる際は、そもそも彼らに郵便局から手紙を送ることがあるのかとまず自問しよう。電子メールで満足のいくやり取りができるなら、顧客の自宅や会社の住所を記録しておかなくてもよいはずだ。そうした余計な情報は、処理のための時間や保管するディスク・スペースを浪費し、さらにはデータ窃盗の格好の標的にもなりかねない。

 プログラマはしばしば収集魔的思考に取りつかれがちで、利用する日はまず来ないと思ってよいものでもかたっぱしからコピーを取っておこうとする。この性質はソフトウェアのデバッグには役立つかもしれないが、データの痕跡を残すことになり、それを第三者が見つけるおそれが出てくる。

 データベースに含まれているその列は、その表は、絶対に必要不可欠なものなのか。疑わしいときは、フォームを短くしたり、データベース・テーブルを小さくしてみよう。データを集めたくなる衝動を何とかして抑えてほしい。情報窃盗犯からは恨まれるだろうが、ほかの人々はフォームに記入するデータが減って喜ぶに違いない。

ヒントその3:パスワードを信用し過ぎないこと

 パスワードの問題性はだれもが知るところだが、よりよい解決策を提示できる者はいない。人はパスワードを忘れ、あまりにシンプルな文字列を設定し、しかもそれを繰り返し使用する。それでも、パスワードに勝る柔軟性あるいは簡便性を持つソリューションはほかに見当たらないのだ。

 一部の企業はすでに多要素認証を導入し、承認の過程において複数の“関所”を設けるようにしている。例えば、ユーザーの携帯電話に乱数を記したテキスト・メッセージを送信し、それをパスワードと一緒に入力させるといった方法がある。携帯電話を家に置いてきたり、バッテリを切らしていたり、建物内でメッセージを受信できない場所にいたりしなければ、これはすぐれた手段だ。

 暗号鍵をしまっておく特別なハードウェアを利用してセキュリティを強化することも、もちろん常に1つの選択肢として存在する。ただしそうした機器は高価なうえ、携帯電話以上になくなりやすい。

 ユーザーがサービスにログインするのに使うIPアドレスを追跡、記録しているサイトもある。その手のシステムに未知のアドレスから入ろうとするとサイトが異変の可能性を察知し、注意を促す丁重な電子メールをユーザーに送ってくる。

 これらの対策はどれも完ぺきとは言いがたいが、パスワードに頼っているだけの状態よりはましだろう。重要なのは、大文字や小文字のアルファベット、数字、句読点などを適切なやり方で組み合わせてパスワードを作ったとしても、安全性には限界がある事実を認識することだ。

ヒントその4:要件の取り決めに細心の注意を

 セキュアなコードの開発は、コード・エディターの中で行うだけでは実現しない。マネージャーらが要件のたたき台を作り、開発者と協議する際、要件の1つ1つがいずれ問題の種とならないか全関係者が真剣に検討する必要がある。

 ある機能が面白いものになりそうでも、そのせいで余計な機密情報の保管を強いられたり、求められるセキュリティ・レベルがあらゆる箇所で無駄に引き上げられたりしないだろうか。いくらクールな機能だからといって、すべての厄介事を引き受けるだけの価値は本当にあるのか。将来の侵害に備えてコードの安全化に着手する最適なタイミングは、要件文書がまだ固まっておらず、顧客がよだれを垂らしそうな機能の数々を提示する前の段階なのだ。

ヒントその5:コードにはほどよい遅延を追加せよ

 コンピュータ頼みの攻撃は多くの場合、侵害の試みが何度も執拗に繰り返される。数千、数百万、あるいは数兆回におよぶ反復入力も、コンピュータならいとわずに代行してくれるからだ。ユーザーを装って何百万ものクエリを送信し、データベースをスクリーンスクレイピングするケースもあれば、たった1つの正解にたどり着くまで数兆個のパスワードをぶつけてくるケースもあるだろう。

 入力の処理に少しずつ遅延を発生させると、こうしたボットを混乱させることができる。この領域に限っては、ソフトウェアを高速にしすぎる、もしくは効率的にしすぎるのは一般的に好まれない。生身の人間の操作を十分サポートできる程度に速く、同時に攻撃ボットが大量の収穫を得るには遅いスピードが理想的だ。

 一部のログイン・プログラムは、不正確なパスワードが入力されるたび遅延時間を倍にしている。また、各IPアドレスからのクエリ数を制限するデータベースや、人間にわざと電子メールを送ってペースを落とさせるシステムなども存在する。人間は1秒や2秒の遅れは気にしないが、ボットだと時間を持て余して非効率化が進行するため、これらの対策はいずれもセキュリティ上のメリットとなる。

ヒントその6:暗号化は必要以上に行え

 暗号化すると既存の装置を動かす手間が増え、デバッグもかなり面倒になるため、これをあまり利用しないという人は多い。そもそもシステム内のエラーを見つけるのは困難なのに、データがわけのわからない数字の羅列に置き換えられていればなおさらだという理屈はよくわかる。

 しかし、自分に把握できないものは攻撃者にも理解できないことを忘れないでほしい。データベースへ保存する前に個人情報にカギをかければ、データベースそのものもこれを支えるOSも、さらにはある程度までならその下層で動作しているハイパーバイザまでも、侵害に関する心配をしなくてよいのだ。

 暗号化を最適な頻度で実行しても、機能性が損なわれる恐れはほぼない。筆者が自著の『Translucent Databases(透明性の高いデータベース)』において複数の事例を調査したところ、個人情報を保護しながら便利なサービスを提供することは十分に可能だとわかった。強固な安全性は、それ自体が1つの機能だとも言える。

ヒントその7:「壁」を立てておく

 セキュリティを強化する必要性と使い勝手のよさの追求を天秤にかけた場合、前者は後者にしばしば押されてしまう。システムのさまざまな部分でログインし直すのを嫌う人は確かに多い。しかし、システムや出力系統の全部位を1つのポータルとしてリンクさせるのは危険な行為だ。一箇所でもほころびがあれば、すべてに影響がおよぶことになる。

 ユーザーがシステムを操作し、1クリックでやりたいことをできるようにするには、どの程度の使い勝手のよさを実現するべきなのか判断するのは容易ではない。正規ユーザーのために利便性を高めることは、システムへの侵入をたくらむ攻撃者にも都合がよいことを肝に銘じておこう。

 機密レベルが最も高いオペレーションは別個のシステムに隔離し、これを利用したいユーザには再度ログインを義務づけるべきだ。銀行なら自身のポータル・サイトに残高確認機能や預金機能を実装しているだろうが、預金の引き出しに関しては、処理の前により厳格な認証を行う必要がある。

ヒントその8:使うのはテスト済みのライブラリにすること

 暗号化を首尾よく行うのは至難の業だ。最先端の理論に基づき、慎重にコードを記述しても、ループホールやバックドアは作成されうる。すでに実績のあるライブラリをもう一度作り直すのは基本的に間違ったことだが、これが暗号化に利用されると問題はさらに深刻化する。暗号化においては、実証済みのライブラリの存在が何よりも重要だ。そこからすぐれたコードを選択して利用し、決して独自のアルゴリズムを作らないよう気をつけたい。

■後篇に続く
(ピーター・ウェイナー)


http://headlines.yahoo.co.jp/hl?a=20130301-00000001-cwj-sci
※この記事の著作権は、ヤフー株式会社または配信元に帰属します