Hatena::ブログ(Diary)

ockeghem(徳丸浩)の日記 このページをアンテナに追加 RSSフィード

[PR]WAFの導入はHASHコンサルティング
 |  

2012-02-01 「管理者パスワードは何日ごとに変更すればよいか」に関する質疑応答 このエントリーを含むブックマーク

昨日Webサイトを守るためのセキュリティ講習会の講師を担当しました。講習会の終了後、受講生から「管理者パスワードの定期的変更」に関する質問がありました。備忘の為、質疑内容を以下に記録します。


Q1:上位ポリシーにて、管理者パスワードは定期的に変更するように義務づけられているが、何日毎に変更するのが正しいのか。最近の専門家の見解をお伺いしたい
A1:専門家の見解は分かれているとお答えしました

現在の主流はパスワードを定期的に変更するべしという考え方ですが、それに異論を持つ人もいて、私もその一人です。

一般ユーザのパスワードとは異なり、管理者パスワードは、業務の必要上複数の人が知っている状況があります。その状況では、「定期的に変更」するのではなく、管理者パスワードを知っている人が、他業務に異動、あるいは退職するタイミングで遅滞なく変更するべきです。そうしないと、「管理者でなくなった人が管理者パスワードを知っている」という状況が起きます。

管理者パスワードを定期的に変更するというのは、上記運用ができない(したくない)場合の代替策ととらえることができます。この場合、一定期間「管理者でない人が管理者パスワードを知っている」状態があり得ます。本来避けなければならない状況であり、積極的にそうする必然性はありません。

rootログインやsuコマンドを使っていると、管理者業務をする人にrootパスワードを教えなければなりません。一方、sudoコマンドを使って管理者業務をすると、rootパスワードを教えなくてもすむので、rootパスワードを変更する頻度を少なくすることができます。また、誰が、いつ、どのrootコマンドを実行したかというログも取得できるので、管理レベルが向上する点でおすすめです。


Q2:Windowsなどでは、パスワードポリシーとして、一定回数前までのパスワードを使用できないようにできるが、この点はどうか
A2:管理者パスワードの場合は、一度設定したパスワードを再利用することは禁止すべきとお答えしました

パスワードポリシーとして、例えば3回前までのパスワードは再利用禁止などというものがあります。しかし、これを「4回前のパスワードであれば再利用してもよい」と捉えるべきではありません。管理者パスワードを管理者以外のものが知っている状態は避けなければならないからです。

とはいえ、過去のパスワードをすべて記録して、衝突を防ぐという作業も煩わしく、「パスワード台帳」の管理が困難なため、かえってパスワード漏洩の原因になりそうです。

このため、パスワード乱数などで生成することで、結果として過去のものと衝突しない方法をとればよいと考えます。わざわざ過去のものと照合する必要はありません。


あわせて読みたい

パスワードの定期変更は「神話」なのか? - ockeghem(徳丸浩)の日記
続パスワードの定期変更は神話なのか - ockeghem(徳丸浩)の日記
パスワードの定期変更という“不自然なルール” (1/4):セキュリティ・ダークナイト(6) - @IT


[PR]

安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

2012-01-20

PostgreSQL Conference 2012で講演します PostgreSQL Conference 2012で講演しますを含むブックマーク

PostgreSQL Conference 2012で講演する機会を頂きましたので報告します。

日時:2012年2月24日(金曜日) 14時30分〜17時20分(徳丸の出番は16:30〜17:00

場所:AP 品川東京都港区

費用:3,500円(申し込みはこちら

講演タイトル:安全なSQLの呼び出し方

今回は、IPA安全なSQLの呼び出し方を題材として、SQLインジェクションの発生原理から、安全なSQLの利用方法を基礎から実際までを説明します。

あまりトリッキーな攻撃の方法はしないつもりで、基礎的な話が中心となります。安全なSQLの呼び出し方の作成経緯については、「今夜こそわかる安全なSQLの呼び出し方 〜 高木浩光氏に聞いてみた」を参照下さい。

さて、「安全なSQLの呼び出し方」は以下の五名による執筆となっています。

執筆者 徳丸 浩   永安 佑希允   相馬 基邦   勝海 直人

    高木 浩光 独立行政法人産業技術総合研究所

執筆者に肩書きがないのは、独立行政法人情報処理推進機構IPA)の職員ということです。安全なSQLの呼び出し方の執筆者の一人に、IPAの徳丸浩という人がいる、ということですね。一方、今回の講演は、HASHコンサルティング株式会社代表としての徳丸浩がしゃべります。

ややこしいですが、こうすることで、IPAとしての公式な立場ではなく、徳丸の個人としての意見を自由にしゃべることができます。具体的には、独立行政法人セミナーでは仕込みにくい*ネタ*を取り入れることもできるわけですね(これ、けっこう重要)。

昨年は、PHP ConferenceYAPC::Asia TOKYO(Perlの祭典)で講演する機会を頂きました。今年の講演はじめはPostgreSQL Conferenceということで、オープンソースソフトウェアカンファレンスでしゃべらせていただけることを嬉しく思います。

参加者190名ということですので、お申し込みはお早めに。

[PR]

安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

2011-12-28

今年読まれた人気記事トップ10+10 今年読まれた人気記事トップ10+10を含むブックマーク

今年も残りわずかとなり、今年の○○トップ10というタイトルを目にする機会も増えました。徳丸のブログでも、トップ10を発表したいと思います。今年書いたブログ限定ではなく、今年もっとも読まれたブログエントリのトップ10です。

  1. Apache killerは危険〜Apache killerを評価する上での注意〜
  2. PHP5.3.7のcrypt関数のバグはこうして生まれた
  3. もし『よくわかるPHPの教科書』の著者が徳丸浩の『安全なWebアプリケーションの作り方』を読んだら
  4. SQLのエスケープ再考
  5. EZwebの2011年秋冬モデル以降の変更内容とセキュリティ上の注意点
  6. PHP5.3.7のcrypt関数に致命的な脆弱性(Bug #55439)
  7. 都道府県型JPドメインがCookieに及ぼす影響の調査
  8. モテるセキュ女子力を磨くための4つの心得「SQLインジェクションができない女をアピールせよ」等
  9. evernoteのテキストをevernote社の管理者にも見えないように暗号化する
  10. 私はいかにしてソフトバンク端末60機種のJavaScriptを検証したか

ページビュー数では、1.の「Apache killerは危険〜Apache killerを評価する上での注意〜」がぶっちぎりでした。Apache Killerへの関心の高さが伺われますね。

2位の、PHP5.3.7のcrypt関数バグも大きな話題となりました。この問題への態度を観察していると、PHPerよりも他のクラスタの方が騒いでいる印象を受けました。なんというか、「真のPHPerはこの程度の問題では動じないのだ」という無言のメッセージを感じた気がしました。現実問題として、crypt関数あんまり使われてないような気がしますしね。

4位には、「SQLのエスケープ再考」がランクインしています。3年半前のエントリですが、継続して読んでいただいています。私にとっても思い入れの深いエントリです。

8位の「セキュ女子力」も多くの方に読んでいただきました。本格的なコピペを書いたのは実は2回目でして、1回目は「Webアプリ脆弱性オタがふつーのSEの彼女に脆弱性世界を軽く紹介(ry」なんですが、元ネタ増田で出してきたのまで真似して増田で発表したという行きがかり上今まで匿名にしていました。あれから三年も経つのですね。もうばらしてもいいでしょう。

ちなみに、11位〜20位は以下の通りです。

  1. PHPのイタい入門書を読んでAjaxのXSSについて検討した(1)
  2. ソフトバンクのゲートウェイ型SSLの脆弱性を振り返る
  3. 「SQLインジェクション対策」でGoogle検索して上位15記事を検証した
  4. ぼくがPDOを採用しなかったわけ(Shift_JISによるSQLインジェクション)
  5. CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例
  6. SQLの暗黙の型変換はワナがいっぱい
  7. KDDIの新GWで「かんたんログイン」なりすましの危険性あり直ちに対策された
  8. PHP5.4のhtmlspecialcharsに非互換問題
  9. 「安全なWebアプリケーションの作り方」電子書籍版9月28日(水)販売開始します
  10. 僕が「ホワイトリスト」を採用しなかった訳

今年は、なんと言っても「「徳丸本」を完成させることができ、多くの方に読んでいただいたことに尽きると思います。多くの方に支えられて初めてできたことです。本当にありがとうございました。来年もよろしくお願いいたします。

[PR]

安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

トラックバック - http://d.hatena.ne.jp/ockeghem/20111228

2011-12-26

大垣本を読んで「バリデーションはセキュリティ対策」について検討した 大垣本を読んで「バリデーションはセキュリティ対策」について検討したを含むブックマーク

このエントリでは、セキュリティ観点から、バリデーション実装について検討します。大垣さんの本を読んで「大垣流バリデーション」について勉強した結果を報告します。

はじめに

大垣さんの記事「入力バリデーションはセキュリティ対策」では、「入力バリデーションはセキュリティ対策である」が力説されています。この記事はおそらくid:ajiyoshiさんのブログ記事「妥当性とは仕様の所作 - SQLインジェクション対策とバリデーション」を受けてのことだと思います。id:ajiyoshiさんのエントリでは、「妥当性検証は仕様の問題であってセキュリティ対策ではありません」と明言されています。私はid:ajiyoshiさんに近い考えを持っていますので、大垣さんの主張について、私なりに考えてみました。

記事を書くにあたり、徳丸の立場を明確にしておきたいと思います。

  • バリデーションの基準は仕様の問題
  • バリデーションは本来セキュリティ目的でするものではない
  • バリデーションにはセキュリティ上の効果はある
  • バリデーションについての徳丸の関心は、「基準は何で、何をするか」

以下、順に説明します。

バリデーションの基準は何か

バリデーションの問題を議論する上での最初の(そして最大の)問題は、「何を基準に(正として)バリデーションするか」です。セキュリティの教科書によっては、セキュリティの都合により入力値の制約を定め、その制約を元にバリデーションするように説明しているものがあります。その具体例については、コレコレを参照下さい。

id:ajiyoshiさんのブログでは、バリデーションの基準はアプリケーションの仕様だと明記されています。徳丸も同意で、私の本のP79には「入力値検証の基準はアプリケーション要件」という節があります。

大垣さんの本では、「入力値はポジティブセキュリティモデルを使用して確実に検証する(P171)」などとありますが、「ポジティブセキュリティモデルってなんだ?」と、よく分からないので、大垣さんとtwitterで会話してみました。togetterにまとめましたので参照下さい。結論としては、大垣さんも「バリデーションはアプリケーションの仕様(文書化されているかどうかは別として)に従う」と考えられているようです。

つまり、バリデーションの基準についてはid:ajiyoshiさんと大垣さんの考えは同じということになります。

バリデーションのセキュリティ上の効果

次に、バリデーションのセキュリティ上の効果について検討します。

id:ajiyoshiさんは、バリデーションのセキュリティ上の効果については言及されていないようです。これは実に潔い態度と言えますが、一般的には、バリデーションに一定のセキュリティ上の効果を認める人が多いと思います。このあたりの話題は、稿を改めて書きたいと思っています。

一方、大垣さんは、ご自身の本の中で以下のように書いておられます。

クロスサイトスクリプティング、SQLインジェクションHTTPレスポンススプリッテイングなど、入力さえ厳密に確認していればセキュリティホールとならずにすむ場合が数多くあります。

様々な脆弱性について防御上の効果があるが、常に攻撃を防げるわけではない、ということですね。これはセキュリティ観点から見たバリデーションの特徴です。

「さまざまな脅威に対して効果がある」という、いわば万能性に着目すると、「バリデーションはなんて素晴らしい『セキュリティ対策』なんだ」という評価になります。一方、常に防げるわけではない点に着目すると、「バリデーションで常に防御できるわけではないし、そもそも本質な対策ではない。そのようなものは『セキュリティ対策』とは認めない」という評価になるのでしょう。

つまり、バリデーションにどのような効果があるかについて見解が分かれているわけではなく、どの特徴に着目するかによって、バリデーションとは何かという表現が変わっていることです。「バリデーションはセキュリティ対策か否か」という問題の答えは「セキュリティ対策とは何か」という定義次第で変わるため、私はこの「セキュリティ対策か否か」という議論には興味がありません。

バリデーションの結果何をするのか

次に、バリデーションの結果「基準(=仕様)を満たさない」入力をどう扱うかについて考えます。

id:ajiyoshiさんのエントリには、『それ以外の入力については、「郵便番号を入力してください」というメッセージを表示して再入力を促す』などと例示されているので、入力画面に戻って再入力させるということですね。これは(曖昧な用語を敢えて使いますが)正常系の流れの一部とみなすことができ、「セキュリティ対策なんてもんじゃないよ」というid:ajiyoshiさんの主張もうなずけます。

一方、大垣さんの主張はどうでしょうか。先のエントリを読んでもよく分からなかったので、大垣さんの本から拾ってみました。同書のP168〜P169には、入力値の確認方法の「よい」例として以下のスクリプトが紹介されています。

if (is_number($_GET['int'])) {
  $n = $_GET['int'];
} else {
  trigger_error('数値ではありません。$n=', $n);
}
if ($min >= $n && $n >= $max) {
  trigger_error('数値が範囲外です。$n=', $n);
}

これを見ると、バリデーションの結果仕様外と判定された入力については、trigger_error関数を呼んでエラーとしています。trigger_error関数は、ユーザ定義のエラーを発生させる関数です。このスクリプトの後に、以下の説明が続きます。

trigger_errorで登録されたユーザーエラーハンドラで、無効なリクエストのエラー情報、送信したIPブラウザ、時間などを記録し、必要であればメールで通知したりアクセスを禁止しセッションを破棄するなどの処理を行えば、ほとんどのサイトでは十分でしょう。

かなり物々しいことが書いてありますね。このようなアプリケーションを利用することは、かなりの緊張感を伴いそうです。この前のところには、「人の年齢の場合は-10才などという数値はないはずですし、普通は0〜130くらいまでで十分でしょう」とあります。この文の内容には同意ですが、trigger_errorの処理内容とあわせて考えると、年齢を31と入れようとして手が滑って311と入力した場合でも、セッションが破棄され(結果としてログアウトし)、アクセスを遮断され、(管理者に?)メールで通知されるのでしょうか。

同書のAPPENDIX.Cには、P237からエラーハンドラの実装例が出ています。これを読むと、メール通信やアクセスの遮断はしていませんが、セッション破棄のコードはあります。

if (empty($_SESSION)) {
    $_SESSION = array();
}

empty関数は、変数が空の場合に真を返します。空とは、空文字列、0、NULL、FALSE、空の配列などを指します。このサンプルはプログラムの最初の方でsession_start()を呼んでいますので、$_SESSIONの値はなんらかの配列のはずです。すなわち、上のスクリプトは、$_SESSIONが空配列の場合に、あらためて空配列を代入していることになります。しかし、これは恐らくバグで、$_SESSIONが空でない場合に空にしたいのでしょう*1。以下、私の推定が正しいと仮定して議論を進めます。

エラーハンドラは、セッション破棄の他に、スタックトレース、$_GET、$_POST、$_SESSION、$_SERVERの全ての値をログに生成しています*2

そして、エラーハンドラの最後にexitでアプリケーションを明示的に終了しています。その前には、「//すべてのエラーは致命的なエラーとして処理」とコメントがついています。

これは中々タフなユーザー体験です。年齢や郵便番号などをうっかり間違えただけで、ログアウトしてエラー表示されるわけですから。複数のエラーがある場合、表示されるのは最初の1つのみです。このようなアプリケーションを使うと、かなり「残念な」思いをするように思います。一方、「なるほど、『セキュリティ対策』とはこれを指していたのか」という異様な説得力があります。

しかし、このような「セキュリティ対策」は本当に「世界の常識」なのでしょうか。Googleも、Facebookも、Amazonも「不正な入力」に対してそのような挙動は示さないようです。

現実にはそこまで厳しくしなくても、アプリケーションの安全性は保てると思います。バリデーションの結果、仕様外の入力があった場合は、間違いの理由を明示して再入力を促すのがよいと思います。「そんな対応ではセキュリティ対策とは言えない」ということであれば、バリデーションはセキュリティ対策でなくて結構と思いますし、それで安全性が損なわれるとも思えません。

まとめ

「入力バリデーションはセキュリティ対策」かという命題について検討しました。バリデーションの基準については、アプリケーションの仕様と言うことで一致しているようですが、仕様外の入力があった場合の挙動については、大垣本の教えは独特であることがわかりました*3

私自身は、バリデーションは「セキュリティ対策」の一種ととらえてもよい(どうでもいい)と思いますが、仕様外の入力に際しては利用者に分かりやすいメッセージを表示して、再入力を促すのがよいと考えます。

蛇足

先に引用した数値検証のスクリプトにはバグがあります。

※ このスクリプトは「間違い探し用のコードが手違いで収録されていました」と指摘されていますので、以下はその間違い探しの答えに当たりますね。

  • is_numberという関数PHPには標準で用意されていない。is_numericという関数ならある*4
  • 「数値ではありません」の後の$nは初期化されていない変数を参照している
  • 範囲チェックのif文で等号があるのは間違い
  • 範囲チェックのif文は&&ではなく||にすべき

これらのバグの結果、実行時に未定義関数のエラーになりますが、is_numberをis_numericに置き換えて実行すると、$nの値に関わらず常にチェックを通ることになります。「数値が範囲外です」というエラーメッセージが表示されることはありません。

このスクリプトに続くのは「よい文字列確認」と題されたスクリプトです。以下に引用します。

if (strlen($_GET['name']) > 20) {
  trigger_error('名前が長すぎます');
} else if (strlen($_GET['name']) <= 1) {
  trigger_error('名前が短すぎます');
} else if (strlen($_GET['name']) != strspn('abcdefghijklmnopqrstuvwxyz')) {
  trigger_error('名前には小文字のアルファベットのみが使用できます');
}

ここにstrspnという関数が出てきます。以下の仕様です。

int strspn ( string $subject , string $mask [, int $start [, int $length )

subject : 調べたい文字列。

mask : 許可する文字の一覧。

start : subject の中で調べ始める位置。

length : subject 内で調べる部分の長さ。

返り値 : subject の中で、全て mask の中の文字からなる最初のセグメントの長さを返します。

http://php.net/manual/ja/function.strspn.php

すなわち、第1引数の文字列の中から英小文字だけからなる部分を探しその長さを返すということなのですが、残念ながら第1引数('$_GET['name'])が抜けているので、実行時にエラーになります。これもバグですね。書きっぱなしで、テストはしなかったのでしょうね。

そもそも、strspnをバリデーションに用いるのはどうなのでしょうね。aからzを漏れなく入力しているか不安で仕方ありませんし、プログラムが読みにくく、なにか意図しない動作をしてしまいそうです。その懸念は、次のサンプルで現実のものとなります。

次のバリデーションサンプルは、入力文字列がSHA1ハッシュの要件(16進数40桁)を満たしていることを確認するものです。以下に主要部分のみ引用します。

// hex形式のsha1値は0-9, a-fまでの40文字
$error = (40 != strspn($str, '1234567890abcdef'));

40桁の16進数であることを確認したつもりなのでしょうが、このスクリプトだと、*先頭40文字が16進数* であることのチェックになります。要件を満たすには、文字列長が40であることも確認しなければなりません。

この結果、41文字目以降に攻撃文字列がある場合も、バリデーションをすり抜けます。以下に例を示します。

<?php
$str = "0123456789012345678901234567890123456789'or'a'='a";
$error = (40 != strspn($str, '1234567890abcdef'));
var_dump($error);
【実行結果】
bool(false)

$errorがfalse、すなわちエラーなしという結果になります。これはまずい。SQL呼び出し部分にSQLインジェクション脆弱性がある場合、任意のハッシュ値でチェック処理を通過できるなどの攻撃が考えられます。

脆弱性診断で上記が確認できた場合を考えましょう。SQLインジェクション脆弱性があればもちろん高危険度の脆弱性ですが、危険な脆弱性が発見されず、バリデーションの不備のみである場合、私なら低危険度、あるいは単なる指摘(Information)とします。

しかし、大垣さんのお考えですと、「入力バリデーションは非常に重要なセキュリティ対策の第一番目」ということですので、その「非常に重要なセキュリティ対策」に欠陥があるということは、上記は重大な脆弱性ということでしょうか。

この蛇足から導ける教訓は以下の通りです。

  • プログラムを書いたら必ずテストしよう
  • トリッキーな書き方は脆弱性の元なので平明な書き方にしよう

訂正(2011/12/26 8:36)

タイトルが「パリデーション」となっていたのでバリデーションに修正しました。本文も同様に2カ所修正しました。

[PR]

安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

*1:私が同じことをしたい場合は、if文なしに問答無用で空配列を代入してしまうと思います。

*2:もっとも、$_SESSIONはログデータを作る前に破棄しているので、意味がないように思えます。

*3:但し5年前に発行された本ですので、大垣さんの現在のお考えは変わっているかもしれません。

*4:is_numberをGoogle検索すると、「次の検索結果を表示しています: is_numeric」と表示されます

yohgakiyohgaki 2012/01/17 09:35 入力エラーの処理の為のエラー処理とセキュリティ処理の為のバリデーション(入力チェック)を混同してますね。入力エラーの処理もしないでバリデーションで致命的エラーで終了するようなアプリケーションを書く人がいますか?居るわけないです。エラー処理とバリデーションはセキュリティ対策、というのはISOなどの用語の定義からセキュリティ対策である、という話をしています。セキュリティ対策なのにセキュリティ対策ではない、というおかしなことをいう人がいるので初心者がセキュリティは難しい、何をセキュリティ対策というのか分からない、なっているのだと思います。

ockeghemockeghem 2012/01/20 14:54 コメントありがとうございます。
ISOの定義など私のブログの読者は関心がないと思います。大垣さんの主張が具体的にどうせよということか分からないから、皆混乱しているのだと思います。
「入力エラーの処理の為のエラー処理とセキュリティ処理の為のバリデーション(入力チェック)を混同」ということですが、どうやって区別するのですか?私も分からないので、大垣さんのサンプルプログラムからリバースエンジニアリングしました。それが本意でないのであれば、明確に「この基準で、こうすべし」というをお示しいただきたいと思います。

2011-12-19

「徳丸本をブロガーに差し上げちゃうキャンペーン」当選者のお知らせ 「徳丸本をブロガーに差し上げちゃうキャンペーン」当選者のお知らせを含むブックマーク

徳丸本をブロガーに差し上げちゃうキャンペーン」ですが、先週末に選考を行い、当選者には個別に連絡させていただきました。当選表明のブログが出そろいましたので発表いたします。当選者は以下のブロガーの皆様です。

本日より順次書籍を発送致します。徳丸本は重い(約1kg)ので、3冊ずつ発送するつもりです。しばらくお待ち下さい。クリスマスには間に合うと思いますw

土日にいそいそと宛名書きをしていましたら、こんな指摘が

@ockeghem 今回のイベント、なんだかプレゼントの送り手が一番しあわせそうですね (^^)

https://twitter.com/#!/tt4cs/status/148325070501191680

おっと、これは図星でした。贈り物というのは、送り手が幸せになる為にするのですね。私の為に付き合って下さった皆様ありがとうございました。

選に漏れた方、ゴメンナサイ。徳丸の勘でテキトーに選んでおりますので、優劣を決めたものではないことを申し添えます。

それでは、当選者の皆様、感想のブログをお待ちしております。

読むのに時間が掛かると思いますので、焦って書く必要はありませんよ。

[PR]

安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

 |  
Google
Connection: close