最新 追記

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 1906   昨日: 3535

2006年01月14日

ぜひ買いたいこの一冊(脆弱性コードレビュー練習用その1)

ジュンク堂本店の「PHP」コーナーで一番目に付く位置に飾られていた本を読 んでみた。

    改訂新版 基礎PHP, 山田祥寛監修、 WINGSプロジェクト(本田将輝、山葉寿和、斉藤崇、森山絵美、渕幸雄、青島裕、山田奈美)著, インプレス, 2004年10月1日初版発行 2005年12月11日第1版第5刷発行

帯の宣伝文句はこうだ。

PHP5で作るWebアプリケーション
待望の改訂版登場!
最新機能まで踏み込んだ内容と、必要な環境を収録したCD-ROMで、着実に学ぶ

着実に……ですか。

最初の動くサンプルコードはこうなっている(p.72)。

<html>
<head><title>hello_world.php</title></head>
<body>
<?php
$var_str="Hello World";
print ($var_str);
?>
</body>
</html>

ここは教育上、次のように教えるべきだ。

<?php
$var_str = "Hello World";
print(htmlspecialchars($var_str));
?>

HTMLを出力しているのだから当然にhtmlspecialchars()を入れる。 (セキュリティどうこういう説明はここでは不要。)

$_GET ないし $_POST を使う最初のサンプルはこうなっている。 (3.1節「サーバーとクライアント間のデータのやりとり」p.151)

<?php
$name = $_POST['name'];
print("次のデータを受け取りました<br />");
print("名前:".$name."<br />");
?>

クロスサイトスクリプティング脆弱性だ。ずっとこんな調子でサンプルコード が続く。

3.3節「ファイルを扱う」にこんな記述がある。(p.159)

$updirにアップロード場所を代入しています。「./upload/」の「.」はカレン トディレクトリのことで、通常このPHPスクリプトが置いてあるディレクトリ を指します。アップロードディレクトリはフルパスで指定しても構いませんが、 通常はセキュリティ・可搬性を考え、相対パスで指定しま す。フルパスでは、スクリプトの置き場所を変えた際に、書き換えが 必要になります

「ファイル丸見え漏洩」を起こす糞CGIプログラムの製造を助長する記述だ。 こういう糞解説は2002年に絶滅したと思っていたが……。 セキュリティのことを考えれば、絶対パス名で置き場所を指定するようにし、 スクリプトを設置する者が安全な場所を意識しながら設定変更して使うように するべきだ。

3.7節の「セッションを利用するための設定」には次の記述がある。(p.188)

セッションを利用するには、php.ini を以下のように設定してください。

(1) session.use_trans_sid = on
(2) session.save_path = 任意のディレクトリ

session.use_trans_sid を on にしてはいけない。この本 はこれを on にする理由について次のように言っているが、

(1)をonにすると、PHPのセッション管理関数を利用して、セッションIDの引渡 しを透過(自動)的に行えるようになります。このパラメータがoff になっている場合、セッションIDは自動的にサーバーに送信されないため、プ ログラム中で明示的に受け渡しのロジックを記述しなければなりません

デタラメである。

ざーーーと読み進めて、6章「テンプレートシステムを使った本格アプリケー ション 〜スケジュール管理〜」を読んでみる。ログイン機能を作ってみせる ようだ。

6.4節「ログインしてみよう」の「ログインユーザーチェックとセッション開 始」のコードはこうだ。(p.348)

    function login_check($p_user, $p_pass) {
        $this->indi_check($p_user, "ユーザーID");
        $this->indi_check($p_pass, "パスワード");
        $sql = "SELECT user_id,user_name FROM user_table "
            ." WHERE user_id = '".$p_user."' "
            ." AND PASS_WORD = '".$p_pass."'";
        $row_result = $this->db_object->getRow($sql,DB_FETCHMODE_ASSOC);
        if ($row_result["user_id"] == $p_user) {
            session_start();
    (略)
    }
    function sub_init() {
        (略)
            $this->login_check($_POST["in_user_id"],$_POST["in_pass_word"]);

来たこれ。「indi_check」はなんだ? いわゆるひとつの「さにたいじーんぐ」か?

p.340 に書いてあった。

function indi_check($p_string, $p_name) {
    if (strlen($p_string) == 0) {
        $this->disp_err_message($p_name." は必ず入力してください");
    }
}

脱力。SQLインジェクション脆弱性だ。

ここまでまるまるズバリ典型的な脆弱パターンが、2004年10月発行という最近 出版の本に出ていることに驚く。インプレスでもこの程度なのか。

で、最後までパラパラと見たが、どこかに脆弱性の説明はあったのだろうかと、 索引から次のキーワードを探してみた。

  • クロスサイトスクリプティング
  • Cross-Site Scripting
  • XSS
  • SQLインジェクション
  • ダイレクトSQLコマンドインジェクション

ない。どれもない。

今後のあるべき姿として次などが考えられる。

  • Webアプリ関連書籍を企画する出版社は、出版社としての信用を維持する ため、著者にセキュリティ知識について尋問した方がよい。
  • 大規模書店は、書店としてのセンスを疑われないため、脆弱性のある本 は目立たないところに置くようにした方がよい。

JPCERT/CCの判断力も蝕む サニタイズ脳の恐怖

というお知らせが来たが、こんな記述があった。

[2] Perl のフォーマット文字列処理の脆弱性

(略)

この問題は、Perl で書かれたプログラムを修正し、外部から入力さ れたフォーマット文字列をそのまま処理しないようにすることで解 決します。

そうじゃなくて、「外部から入力された文字列をフォーマット文字列として 使わないようにする」が正しい*1

ここでもサニタイズ症候群か。

どんな脆弱性でも全部、「ニュウリョクヲ ソノママツカワナイ(ロボットの声で)」 と言っておけばそれっぽくまともなことを言っているかのように聞こえてしま う*2という……。そしてそれが癖になる。じつに恐ろしい。

サニタイズすることで解決します」を「そのま ま処理しないようにすることで解決します」に置き換えたってバレ バレだ。

  • JPCERT/CC REPORT 2005-02-23

    Advanced Web Statistics (AWStats) には、入力を適切にサニタイズしないな どの複数の脆弱性があります。

  • JPCERT/CC REPORT 2005-03-02

    bsmptd には入力されたアドレスを適切にサニタイズしない脆弱性があります。

ここまでテンプレ化していると、サルでも書ける。というか、書いてあっても 何の情報もない。(ただしこれらは翻訳のようだ*3。 CIACとDebianの元の文書からしてサニタイズ症候群になっている。)

*1 さらに言えば、フォーマット文字列 引数(printfなどの第一引数)には常に定数文字列しか与えないようにする のが正しい。

*2 これがまたPerlが対象だといかにもそれっぽく聞こえてしまうのが 不幸だ。

*3 ちなみに、2006-01-12 のもの は翻訳ではないようだ。cert.org の元の文書には、「Programs written in Perl that contain format string vulnerabilities should be changed to not include user data in format strings.」と、正しい対策方法が書かれている。

本日のリンク元 TrackBacks(100)

2006年01月15日

続・「サニタイズ言うなキャンペーン」とは

「サニタイズ」という言葉はもう死んでいる

というコメントを頂いた。まず、

これは「サニタイズという言葉を使うな」という主張ではありません。「そもそもサニタイズしなくて済むようにすべきだ」という主張です。言い方を変えると、「サニタイズせよと言うな」という主張になります。

「サニタイズ言うなキャンペーンがわかりにくい理由」, 水無月ばけらのえび日記, 2006年1月5日

とある。「サニタイズせよと言うな」キャンペーンでもよいのだが、 その場合は次の展開が予想される。

「サニタイズせよと言うな」を主張する際の具体例として、XSSやSQLインジェ クションのケースを挙げた場合、正しいコーディングは、「その場の文脈でメ タ文字となる文字をエスケープすること」となるのだが、そうすると、

それをサニタイズと言うのだと思っていました。

のように言われるのがオチだ。「サニタイズせよと言うな」では、有効なキャ ンペーン効果は得られそうにないのだ。

つまり、「サニタイズ」という用語が、各人の都合でどんな意味にも解釈され るという、「汚れた言葉」になっており、専門用語として使い物にならなくなっ ているのだ。もはや、「サニタイズする」は「セキュリティ対策する」と同義 でしかない。そういう言葉には存在価値がない。加えて、特定の意味を指して 使っても別の意味で解釈されてしまうのだから、有害である。

ここで「sanitize」の原語の意味を頼りに、サニタイズを何を指す言葉とする べきか再定義しようとしても、先月31日の日記に頂いたトラックバックのように、次のような展開になってしまうようだ。

Web アプリケーションの出力処理とは、基本的に「他のアプリケーションにデータを渡す」処理だと思っています。(略)

なので私は、「消毒する」という言葉についても、

自分が扱っているうちに汚染されてしまったかもしれないデータを、消毒して から他のアプリケーションに渡す。

と受け取っているので、特に違和感はなかったりします。(略)

自分にとって害が無く、放っておいた場合でも、他のアプリケーションに渡す ときには、そのアプリケーションにとって害があるかもしれません。渡す相手 のアプリケーションにとって害があることが判っているのであれば、それを消 毒してから渡してあげましょう。

サニタイズの語感, Teny’s log 1月8日

このように不毛な話*1になっ てしまう。もうどうしようもない状況なので「サニタイズ」という言葉自体を 捨てたほうがいい。

なお、個人的には「サニタイズせよと言うな」という主張にはかなり 共感できます。この日記を処理している hatomaru.dll というプロ グラムでは、HTMLの出力をサニタイズする処理を一切書いていません。すべてが DOM で処理されている (そして InnerXml に値を直接セットしない と決めている) ので、サニタイズを意識する必要がないの です。これは非常に気が楽でした。

「サニタイズ言うなキャンペーンがわかりにくい理由」, 水無月ばけらのえび日記, 2006年1月5日

この文を見ても、「サニタイズ」が何を指しているのかが不明である。読んだ 人それぞれが勝手にいろいろな意味で読むだろう。

「サニタイズ」が拡大解釈されてきた原因

次に、「サニタイズ」の概念が普及してきた経緯を探ってみる。

先月31日の日記に頂いた別のトラックバック では、次のように主張されていた。

高木浩光さんのところで以前から盛りあがっている「サニタイズ言うなキャン ペーン」に密かに賛同しているのですが、やはり入力段階でHTML実体参照への 書換処理をやっているCGIが多く存在していた事が、「サニタイズは入力段で やるべきもの」という誤解を助長してしまったのが背景としてあるのではない かと思っています。

サニタイズ処理, めもおきば, 2006年1月1日

というよりも、過去に「入力段階でHTML実体参照への書換処理をやっている CGIが多く存在していた」という時代があり、その処理のことを「サニタイズ」 と呼んでいた。そこまではよかった(用語の使い方として)。それが、「CGI の入力段階での処置ではだめだ」という考え方が普及していったときに、なぜ か、正しい処置(HTML出力時のエスケープ処理)のことも「サニタイズ」と呼 ぶ輩がいて、それが現在までその種の「誤解」を引きずらせる原因となってし まったということだ。

こうした流れは、日経システム構築12月号の記事にも見られる。

最新の攻撃手法に適応する(略)

例えば,「セカンドオーダーSQLインジェクション」という攻撃は,自前のテ ストではテスト項目として挙がりづらい。この攻撃は,一般的に言われている 「SQLインジェクション対策」では防げない特徴がある。

クラッカは,ユーザーからの入力値をサニタイジングするという, “正しい”とされるSQLインジェクション対策を逆手に取る。(略)

セカンドオーダーSQLインジェクションは,これらの対策をくぐりぬける。こ の攻撃を防ぐにはさらに,(4)「変数を使ってSQL文を組み立ててい るすべての個所でサニタイジングする」(ラックシステムソリュー ション5部部長倉持浩明ことが欠かせない。

緊急点検! Webアプリ・セキュリティ 多層の防衛ラインでシステムを守る, 日経システム構築2005年12月号

一般に、マスコミは物事を大袈裟に言いたがる。正しい対策をしていれば普通 に防げる話でも、あたかも「新しい攻撃」であるかのように言いたい*2ため、 間違った対策のことを「一般的に言われている“正しい”対策」と言わざるを 得ないわけだ。

「入力でサニタイズ」することが大間違いなのだが、そう言ってしまうと、 「一般的に言われている“正しい”対策」と言ったことと矛盾してしまうため、 「サニタイズ自体は誤りでない」ことにして辻褄を合わせようとする。

その結果、「サニタイズは誤り」という本当のことを書けなくなり、「SQL文 を組み立てているすべての個所でサニタイジングする」と言わざるを得なくなっ ている。

こうやって「サニタイズ」の用法は節操なく拡大されてきた。そして、誤解す る者をいつまでも残す結果となった。

まだまだ残る誤解

次に、「サニタイズ言うなキャンペーン」をはってもまだ残る誤解の事例を挙 げてみる。


「サニタイズ」を「エスケープ」に置き換えればよいと誤読した事例

  • 「サニタイズ言うなキャンペーン」, Notes, 2005年12月29日

    つまり、あって然るべきエスケープ処理(PHPならhtmlspecialchars())を通していないからこそ、「サニタイズ」する必要が出てくるという意味か。(略)

    外部からのパラメータを受け取る部分は、次のように修正した。

    $foo = htmlspecialchars(strip_tags($_GET['bar']), ENT_QUOTES);
    

    (略)HTTP_USER_AGENTやHTTP_ACCEPTを受け取る部分も同様に修正している。

    $baz = htmlspecialchars(strip_tags($_SERVER['HTTP_USER_AGENT']), ENT_QUOTES);
    

CGI入力に対するサニタイズのコードになっている。おそらく、変更前のプロ グラムでは、記号の削除をしていたのであろう。「『サニタイズ』= 文字削除」 と理解されているケースと思われる。

ブラックリスト方式ではなくホワイトリスト方式にせよという話だと誤読した事例

  • Re: サニタイズ言うなキャンペーンがわかりにくい理由, zt日記, 2006年1月7日

    危険な文字を削除っていう手法は危険なので使わないようにしているのですが、 本当にその方法が必要なのでしょうか?

    安全な文字だけを通すようにするという手法ではだめなのでしょうか?

    たとえば、データファイルのファイル名の一部をCGIのパラメータと して受け取るようになっているPerlスクリプトなら/^[a-z]+$/のような正規表 現(Rubyなら\A[a-z]+\z/)で期待している文字しか入っていないこと を確認して(Perlの場合はuntaintもこれで出来る)、違っていたらエラーにする というのが「 セキュリティ対策以前に元来本質的に必要な処理」だと思います。

そんなのは「セキュリティ対策以前に元来本質的に必要な処理」ではない。 「/^[a-z]+$/のような正規表現」を使う手法はサニタイズ処理そのものであっ て、まさにセキュリティ対策のための処理である*3


パス名パラメタどどうするか

元に戻ると、

ただし、hatomaru.dll にもサニタイズのルーチンはあります。たとえば、 http://bakera.jp/hatomaru.aspx/ebi という URL の /ebi 部分はパス名とし て処理されるようになっていて、データディレクトリの中の /ebi/ ディレク トリにあるファイルを見に行くようになっています。ここで ../ などを許し てしまうと、サーバ内の任意の XML ファイルが読まれてしまうおそれがあり ますので、これは意識的に「サニタイズ」しています。

(略)これを「サニタイズせよ」と言わなくて済むような解決策ってあるので しょうか。

「サニタイズ言うなキャンペーンがわかりにくい理由」, 水無月ばけらのえび日記, 2006年1月5日

「サニタイズ」が何を指す概念として語られているのかがわからないし、具体 的にどんな処理で対処しているという話なのかがわからないが、パス名パラメ タの取り扱いの「正しい」コーディング手法は次のようになるだろう*4

方法(a): 言語システムのサンドボックス機構を使う。

方法(b): basename() など、パス名からファイル名部分(最後の部分)だけを 取り出す(言語システムが用意している)APIを使い、ファイルを開く処理の ところで、ディレクトリを示す式と basename() を通したファイル名とを連結 してパス名を指定する。

ポイントは、OSや言語システムに頼るようにし、自前で処理しようとしないこ とだ。「../」をチェックすることを「サニタイズ」と呼ぶとすれば、パス名 がどのように解釈されるかは、ファイルを開くときに呼び出す言語システムの APIやその先のOSのAPIに依存してしまうため、「『../』でサニタイズしたの に、OSは『..\』を解釈した」などということが起きてしまう。究極的には、 言語システムやOSのパス名解釈アルゴリズムを完全にエミュレートした上で検 査しない限り、「サニタイズ」は完全な対策とならないのであり、無理がある。

方法(a)を採用すると、パス名の解釈が(言語システムの責任において)最終 段階までresolveされた段階で、文脈上アクセスを許可しているパス名である かのチェックが自動的に入るようになる。しかし、この方法が使えない言語の 場合や、面倒だから(慣れていないから)嫌だという場合もあるだろう。

方法(b)は、パス名という型と、ファイル名という型を区別する考え方である。 CGIパラメタのひとつをパス名として設計するのを避けて、ファイル名として 設計せよということになる。多くの場合はこの方法が採用できると思われる。

しかし、「ebi/topic/2473」がパラメタであるなら、方法(b)は採用できない。 この場合は、ある意味httpdなみのアプリケーションを作っているようなもの なので、対処が複雑になるのは仕方ないと言えるのではないか。ファイルを開 く時点で、言語システムが用意しているパス名の正規化(パス名解釈を resolveする)APIを使って、目的通りのディレクトリ範囲になっているかをチェッ クして開くようにするのがよいだろう。「目的の範囲」は、ファイルを開こう とするプログラム上の文脈で決まるはずだ。

ところで、

ここで ../ などを許してしまうと、サーバ内の任意の XML ファイルが読まれ てしまうおそれがありますので、これは意識的に「サニタイズ」しています。

「サニタイズ言うなキャンペーンがわかりにくい理由」, 水無月ばけらのえび日記, 2006年1月5日

という文から推察するに、もし、「意識的に対処すること」を「サニタイズ」 と呼んでいるのなら、それは単に「セキュリティ対策として処置する」と言え ばよいのであって、「サニタイズ」という言葉を持ち出す必要性がない。

「サニタイズ」に固執する人たち

最後に、「サニタイズ」に固執する人が絶えない原因について探ってみる。

結論からズバリ言えば、Perlのせいだ。

20世紀の時代、CGIプログラミングといえばPerlだった。Perlは、open 関数のように、手軽な書き方を用意しているのがクイックハック*5に便利であった半面、 堅牢なプログラム開発(正常系以外への確実な対処が重要となるプログラム 開発)の場面では、上級者でない限り脆弱なプログラムを書いてしまいがち (そしてそれはとりあえずは動いてしまう)であるという有害性が大きかった。

そうした時代に書かれた脆弱コードが、セキュリティ対策として修正される際、 入力から危険な文字を削除する手法がとられた。これを指す言葉として「サニ タイズ」の概念が定着していった。

新規に開発される場合でも、「ブラックリスト方式は対策漏れが起きて危険だ からホワイトリスト方式で」ということは言われるものの、それも当初の意味 での「サニタイズ」の範疇であった。

shellを通して実行するopenのような使い方はやめるべきだが、使う場合、 「正しい対策」というのはなかなか難しい。エスケープするといっても、何を どうすれば正しいのかが複雑すぎる。そのため、Perlの世界では、「サニタイ ズ」することが「正しい本来の書き方」であるかのように認識されていった。 (それしかやりようがないと考えられたため。)

さらに、Taint機能がこれに拍車をかけた。Taint機能は本来、脆弱なコードが あるとき(あるかもしれないとき)に、仕方なく使うセーフティネットとして の役割であるはずだ。ところが、Taintにずいぶんと頼って書いている人もけっ こういるようで、Taintがセキュリティ上、本質的な役割を果たすものである かのように思い込んでいる人もいるようだ。

例えば次の発言を見てみる。

処理中に外部からデータを受け取ればもう、それは汚染されている 可能性があるものと看倣しますし、動的に生成するデータも、生成方法によっ ては汚染されている可能性があるという訳ですね。

処理中に汚染されたと言っても、自分にとって害が無いなら放っておいて良い 訳です。自分にとっても害があるなら、その場で消毒すべきですが。

サニタイズの語感, Teny’s log 1月8日

「汚染」という概念があると「消毒」という概念がちょうど対応するように見 えるのだろう。

だが、「汚染」という概念は、Taintという自動セーフティネット機構を実現 するにあたって必要となる概念にすぎない。

Taint機構は、自動的に危険な(可能性のある)操作を実行禁止にするために、 データフローを辿る。様々な入力となる処理に依存したデータフローを「汚染 された」ものと名付けた。これはなかなかうまいネーミングであるわけだが、 それは Taint機構を使う場合にとって「うまい」というだけであって、 本来のセキュアプログラミングにとって「汚染」は必要な概念ではない。

Taintを使わざるを得ないようなPerlの世界によって、「汚染」と「消毒」の 概念が育まれ、そうした古きPerl文化の影響が、「サニタイズ」に固執する人 たちをいつまでも残し続けている原因となっているのではないだろうか。

*1 「他のアプリケーションにデータを渡す」とは、 HTML出力や、SQL文の構成のことを指すと思われるが、HTMLを出力するときに 「<」「>」「&」のエスケープが必要であることや、HTMLタグの属 性値を出力するときに「"..."」に埋め込む値には「"」のエスケープが必 要であること、SQL文を構成するときに「'...'」に埋め込む値には「'」のエスケー プが必要であることなどは、セキュリティとは無関係に、正常系の動作として 当然にやるべきことなのであって、消毒だの、汚染だのは関係ない。

*2 正しい対策をしていると思い込んでいる読者のために、そう言いたいのだろう。

*3 セキュリティ以前の 本来的な処理として、「期待している値しか入っていないことを確認」をする 場合もあるが、それはCGIプログラムや関数などの仕様に基づいて行うべきで あり、アルファベットだけから成るという乱暴な正規表現が、ほんとうにその プログラムの仕様なのかは疑わしい。

*4 このあたりは、構築するアプリケーションの仕様として、ディレクトリの扱い をどのように設計するかしだいなので、一概には言えないが。

*5  ハックとは、リーダース英和辞典第2版によれば、次の意味があるという。

hack
4 《口》 コンピューターやプログラミングに一心不乱に取り組む; ずさんなプログラムを(適当に)作る[でっちあげる]; コンピューターシステムに侵入する〈into〉.
[リーダーズ英和辞典第2版]

hacker
2 《何をやっても》うまくいかない人, 不器用なやつ, ダメな人, 並の人; #《俗》 ずさんな[しろうとの](コンピューター)プログラマー.
[リーダーズ英和辞典第2版]

本日のリンク元 TrackBacks(100)

2006年01月21日

しばらく日記をちゃんと書けそうにない

先々週から実家の都合で、東京と実家を行ったりきたりしている。先週と来週 は、打ち合わせや講演や取材をドタキャンさせていただいており、各方面には 大変ご迷惑をおかけしてまことに申し訳ないこととなってしまった。

そんな折、

というコメントを頂いた。しかし、しばらくの間、じっくり日記を書くことは できそうにない。とりあえず、簡単に書けるところだけ書いておく。

JavaScriptによる連続自動POSTをされるようなサイト(悪意があるサイトというより、脆弱なサイト)にセッション継続中に訪問することがある、という前提であるなら、高木氏が4/27に書いた対策法も、対策としては不完全です。

前述の(A)というのは、いわゆるPHPセッションのことだと思われますが、そうであれば以下の方法で破ることができます。

  • セッション固定をしかける
  • そのセッションが生きた状態でユーザがログインしてしまう(セッションIDは変わらない)
  • セッションIDもPOSTにつむCSRFをしかける

PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1, PEAK XOOPS サポート&実験室

一般に、Session Fixation脆弱性のあるサイトに対して、Session Fixation攻 撃が成功すると仮定した場合、攻撃者は当該サイトに対してセッションハイジャッ クができることを意味する。セッションハイジャックによってもたらされ得る 被害の集合 T_hijack と、CSRF (Session Riding)*1攻撃によってもたらされ得る 被害の集合 T_csrf は、任意のWebアプリケーションにおいて T_hijack ⊇ T_csrf の関係にある。したがって、CSRF (Session Riding)攻撃の防止策を語 る際には、Session Fixation脆弱性がないことを前提とするのが当然である*2

また、「(悪意があるサイトというより、脆弱なサイト)」と書かれているが、 何かの誤りだろう。悪意があるサイトは自由に作ることができる。

  • ログインした時点で、セッションIDを変えるようにする。
  • ログインしない限りセッションは開始しない
  • session.use_only_cookies を on にする
いずれかの方法で、この攻撃は防げますが、この4/27の日 記にはどこにも触れられていません。

PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1, PEAK XOOPS サポート&実験室

Session Fixationの防止策については、Internet Week 2004と同2005のチュー トリアルで説明している*3が、CSRFの正しい防止策の検討とは関係がない(先述の通り)。

また、「いずれかの方法で」防げるというのは誤りである(3番目だけでは防 げない場合がある)。

次。

なんらかのプロクシ・キャッシュに残る可能性があるからです(HTTPヘッダに キャッシュ不可と書いてあったとしても)。

PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1, PEAK XOOPS サポート&実験室

まず、cacheは禁止するのが当然であり、cacheを禁止してもcacheに残る場合 というのは、Webアプリケーションの責任ではない。残るような製品の脆弱性 である。

Webアプリケーション以外の構成要素の脆弱性の影響を受けにくいWebアプリケー ションの設計方法について言うならば、セッション追跡用のセッションIDの格 納場所は、cookieよりも、hiddenなパラメタに入れてPOSTで渡す方が安全であ る*4。なぜなら、cookieが漏洩するブラウザの脆弱性が 見つかることによるセッションハイジャックの脅威の方が深刻だからである。 現実には多くのWebアプリケーションがcookie方式を使用しているが、これは、 柔軟な画面設計が可能であることを優先しているためであろう*5

次。

ワンタイムチケット(トークン)のコードなら4/27の時点でも、ちょっと探せ ばいくらでも見つかったはずです。

PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1, PEAK XOOPS サポート&実験室

意味がわからない。

次。

なお、SSLの指摘については、山本氏の書かれたことは特段間違っていません。もしかすると、高木氏は「『警告なんて無視すれば良い』なんて状況を作り上げたら、せっかくのSSLの安全機構が意味をなさない」という主張かもしれませんが、そういう思想的な主張と、書籍の脆弱性を同列に並べると、何を言いたいのか、テーマがぼやけると思います。

PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの2, PEAK XOOPS サポート&実験室

これは、

非商用サイトなどで単に暗号化の目的だけならプライベートCAで発行した証明 書でも問題ありません。

山本勇, PHP実践のツボ セキュアプログラミング編, 九天社, p.213

のことだが、これは技術的に間違いである。「特段間違っていない」などとい うのは技術的に間違いである。認証パスの検証ができない証明書によるSSL通 信は、SSL暗号通信として正しく動作しないのであって、盗聴され得るものな のだということをいいかげん知ってほしい。

今時分になってもまだ、技術者がこの種の誤りを自信げに語って憚らない*6というのは、はなはだ嘆かわしい。これ以上 嘘を広めないでくれ。

(今日は私にはここまでしか書く余裕がない。)

*1 ここでは、セッショ ンを使わないCSRF攻撃の話を除外している。

*2 同様の事例として、「そのCSRF対策はXSS脆弱性があると効果がない」などと 言う人も見かけたことがあるが、XSS脆弱性も同じくセッションハイジャック ができることを意味するのであるから、CSRF (Session Riding)攻撃の防止策 を語る際には、それより先にXSS脆弱性が排除されていることを前提とするの が当然である。

*3 なお、Session Fixationには、(1)使用する アプリケーションサーバによらない一般的な問題(使用ドメイン名による)の 他に、(2)セッション追跡方式としてURL rewriting方式からcookie方式へと自 動切換えする機能を持つアプリサーバ製品固有の問題と、(3)PHP固有の杜撰な 仕組みの問題(セッションIDとして無効な文字列を与えるとそれをセッション IDとして有効なセッションを作ってしまうというPHPの欠陥(設定で回避可能)) の3種類がある。

*4 実際、銀行のWebアプリケーションはこの方法で作られているもの が古くから多かった。

*5 セキュ リティを重視したショッピングサイトでは、パスワードの再入力によるセッショ ンの二重化をはかり、外側をcookie方式、内側をhiddenなPOST方式と、ハイブ リッド構成をとっているところもある。

*6 むしろ非技術者の方が直感として正しく理解するだろう。「警告が出た。 暗号通信に異常があるようだ。」と素直に。「SSL暗号化としては問題ない」 などという誤りを信じ込むのは、技術者ならではである(物事を知っている気 になっている)わけだが、そうした半端な技術者が非技術者にまで誤りを吹聴 して広げている現実がある。

本日のリンク元 TrackBacks(8)

2006年01月29日

おススメの本 その1

実家の件は幸い良い結果で済みそうになったので東京に帰ってきた。 溜まった仕事の処理で引き続き時間がない状況。

病院での夜は何もすることができないので読書した。

この本はなかなかよい。 Webアプリの脆弱性の話が(だいたい)網羅的に紹介されている。CSRFや Session Fixationの話も含まれている。 「入門の入門」というだけあって、詳細な解決策の提示は十分でないにしても、 初心者Webプログラマが、Webのセキュリティがどういうものであるのかの全体 像を大まかに把握するのに効果的そうだ。そのうえ、肝心な論点がたくさんお さえられている。

また、出版社の編集者の経歴を持つ著者だけあって、文体は適切であるし、論 理に飛躍もないし、中途半端な結論を言ったりしていないし、不正アクセスを 助長しかねないような表現もない。

ところで、最近のIT系書籍は、参考文献を挙げないのが主流になってしまった のだろうか。Webで検索すれば済むのだからということなのか?

日記予告

書く予定の日記。時間がないのでメモだけ。

本日のリンク元 TrackBacks(3)

最新 追記

最近のタイトル

2017年07月22日

2017年06月04日

2017年05月13日

2017年05月05日

2017年04月08日

2017年03月10日

2017年03月05日

2017年02月18日

2017年01月08日

2017年01月04日

2016年12月30日

2016年12月04日

2016年11月29日

2016年11月23日

2016年11月05日

2016年10月25日

2016年10月10日

2016年08月23日

2016年07月23日

2016年07月16日

2016年07月02日

2016年06月12日

2016年06月03日

2016年04月23日

2016年04月06日

2016年03月27日

2016年03月14日

2016年03月06日

2016年02月24日

2016年02月20日

2016年02月11日

2016年02月05日

2016年01月31日

2015年12月12日

2015年12月06日

2015年11月23日

2015年11月21日

2015年11月07日

2015年10月20日

2015年07月02日

2015年06月14日

2015年03月15日

2015年03月10日

2015年03月08日

2015年01月05日

2014年12月27日

2014年11月12日

2014年09月07日

2014年07月18日

2014年04月23日

2014年04月22日

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|06|07|08|10|11|12|
2017|01|02|03|04|05|06|07|
最新 追記