徳丸浩のtumblr
データベースのデータを信用してはいけないか?

ネットを見ていたら「問題集 : PHP技術者認定・初級」というのを見つけました。

【セキュリティ対策】

セキュリティ対策について、正しいものを1つ次の記述の中から選択せよ。

  1. 入力のフィルタリングのみ行う。
  2. 出力のエスケープのみ行う。
  3. 少なくとも、入力のフィルタリングと出力のエスケープを行う。
  4. データベースのデータは信頼してよい。

ITトレメ PHP技術者認定・初級 - @IT自分戦略研究所より引用

過去問なのか練習用の想定問題なのかわかりませんが、「問題提供: PHP技術者認定機構」とあります。

PHPアプリケーションの問題ですから、Webアプリケーションセキュリティの問題ですね。茫漠とした問題文ですが、実は正答を得るのは難しくありません。選択肢から技術的な中味を抜いてみると下記になります。

  1. ○○のみ行う。
  2. ○○のみ行う。
  3. 少なくとも、□□を行う。
  4. ○○は信頼してよい。

このように並べてみると、○○の選択肢(1, 2, 4番)は「これだけやっていれば大丈夫」となっているのに対して、□□(3番)は、最低限これだはやるようにと慎重な書き方になっています。よって、技術的なことは知らなくても、3が正答と分かります。

でも、こういう「国語入試問題必勝法」みたいな解き方はよくないですよね。ここからは、技術的な内容を見ていきましょう。1~3も曖昧で良くないとは思うのですが、このエントリでは、「4. データベースのデータは信頼してよい。」について検討します。

データベースのデータを信頼(信用)してよいかは、データベースの置き場所などにも変わってきますが、一般的には信用してよいと扱うと思います。

この問題の出題者は、PHP技術者認定機構顧問の大垣さんだという気がしたので、その線で検索して見ました。例えば以下の記事です。

トラストバウンダリのコンセプトは非常に単純かつ明快です。しかし,この基本が正しく理解されていないことが多いのです。例えば,数年前に某大手ベンダーがセキュアプログラミングの動画を公開し,トラストバウンダリを使ってどのように安全性を確保するか解説していました。その動画ではなんとトラストバウンダリの中にデータベースが含まれており,前提条件無くデータベースが信頼できるシステムとして扱われていました

第28回 あまり語られないセキュリティの基本 ── トラストバウンダリより引用(強調は引用者)

この某大手ベンダーとはどこだろうと思って調べたところ、マイクロソフトのようですね。大垣さんの以下のブログ記事が根拠です。

まだ全部見ていませんが

【セキュリティの脅威を知る レベル 100 シリーズ】

皆様からご要望の多かった開発者が考慮すべきセキュリティの問題点を1つ1つを解説した

【中略】

とメールが来ていました。

【中略】

Trust Boudary(信頼の境界)の説明は私の認識と異なります。プレゼンでは

「特権レベルの替わる場所」

としていますが

「データの受送信でセキュリティ問題が発生する箇所」

と考えています。プレゼンではIISとデータベースが同じ特権レベルであるのでトラストバウンダリの同一領域として「IISとデータベース」が同じ領域として書かれていました。

私の考えではIISとデータベースの間にはトラストバウンダリがあり区別します。区別する理由はセカンドオーダSQLインジェクションやセカンドオーダXSSなどのリスクを考えれば明らかではないでしょうか?

あいにく参照先の記事は今では読むことができないようですが、おそらく以下のような図が掲載されていたのではないでしょうか。

image

Web アプリケーション セキュリティ強化: 脅威とその対策より引用

つまり、マイクロソフト社はデータベースのデータを信頼して良いとしているが、大垣さんの意見は違っていて、データベースのデータは信頼してはいけない、その理由はセカンドオーダーSQLインジェクションなどの脅威があるから、ということのようです。

しかし、SQLインジェクション脆弱性となるのはアプリケーションのバグが原因であり、データが信頼できる・信頼できないは関係ありません。データの中味がSQLインジェクションコードであっても、バグ(脆弱性)がなければ影響を受けないわけです。すなわち、SQLインジェクション対策という文脈では、トラストバウンダリも、「データの信頼性」も関係ない、ということです。

また、大垣さんは以下のような記事も書いておられます。

たとえ内部システムから取得したデータであっても,そのデータの起源や管理状態が不明確な場合はデータを信用してはなりません。実際にあった例ですが,管理システムが動作ログをメールメッセージで送信し,ログ保存システムがそれを受け取ってデータベースサーバにログを保存し,管理用のWebアプリがそのデータベースから取得したログを表示するシステムがありました。ログメッセージにはHTMLタグが含まれる場合があるため管理用のWebアプリはエスケープなしにログを表示していました。ログメッセージの送信先のメールアドレスとメール形式を知っているユーザであれば,誰でも簡単にスクリプトインジェクションを行い管理者のセッションを盗むことが可能な状態でした。

メールサーバから直接ログを取得していたのであればプログラマも危険性を考慮できたかもしれません。別のシステムを経由するとリスクが明白でなくなることがよくあります。本当に信頼できるデータのみ信用できるデータとして扱わなければなりません

【スクリプトインジェクション対策12】データベースなど,内部データを信用しないより引用(強調は引用者による)

データベースのデータをHTMLエスケープなしで表示するケースは確かにあります。CMSやブログシステムなどで、HTML形式のデータを保持している場合は、出力の際にHTMLエスケープしません。この種のシステムでは、SCRIPT要素などが入力されてXSSとなる可能性がありますが、通常は以下のように対処します。

  • CMSなどで、利用者が任意のタグを使う権限を持つ場合、すなわち利用者を信用するケースは、最低限のチェック(閉じタグの対応など)のみで、基本的には利用者の入力をそのまま受け入れる。この場合、ユーザ入力によりJavaScriptが実行できてもXSS脆弱性ではない
  • 掲示板やブログのコメント欄など、第三者が入力するデータについては、使用できるタグを制限することにより、XSS脆弱性を防ぐ、

後者の場合、タグの検証をどの段階でするかですが、通常は入力時、すなわちデータベースに登録する前にチェックするでしょう。そして、いったんチェック済みとしてデータベースに登録した後では、HTML出力時には再チェックしない場合がほとんどではないかと思います。すなわち、データベースのデータは信用しているわけです。

ここで、思い出すのが、『ヤフーにおけるインプットバリデーション「何も信じるな」』という記事です。ヤフー!では「何も信じるな」というセキュア実装方針を採用されているそうですが、この記事の中には「データベースのデータも信じない」とは書いていないのです。すなわち、「何も信じない」という実装ポリシーにおいても、データベースのデータは信用するということだと私は理解しました。

私がそう思う理由の1つとして、HTMLタグのチェックがかなり重たい処理であるという事情もあります。このため、許可されたタグのみであることのチェックは入力時に行い、データベースの内容は「チェック済み」として信用するという実装が一般的です。少なくとも、私はHTML表示の度に許可されたタグであることのチェックをしている実装を見たことがありません。もし、Yahoo!のように負荷の高いシステムでこの出力時のチェックをしているのであればすごいことなので、ぜひ教えていただきたいと思います。ただし、広い世の中には表示の度にHTMLタグの検証をしているWebシステムもあるかもしれませんが、それはアプリケーション要件として実装しているものであって、必ずそうするべしという証拠にはなりません。

ここで、もう一つの問題が浮上します。データによっては「HTMLエスケープしないで表示する」場合があることを認めるとすると、冒頭に紹介した選択肢「3. 少なくとも、入力のフィルタリングと出力のエスケープを行う。」は間違いと言うことになってしまいます。つまり、これも一般的な原則なのであって、例外もあり得るということで、問題としては不適切でしょう。

大垣さんの主張を要約すると、以下のようになるでしょう。

  • トラストバウンダリという考え方はセキュリティの基本であるのに、語られることが少ない
  • マイクロソフト社のような著名・大手企業であっても、トラストバウンダリを間違って説明している
  • 実際にはデータベースのデータは信頼してはいけない
  • その理由はセカンドオーダーSQLインジェクションや、HTMLエスケープしないで表示する場合のXSS等の脅威があるから

私の意見は以下の通りです。

  • トラストバウンダリという考え方では、そもそもWebアプリケーションの脆弱性をうまく説明できない
  • マイクロソフト社のトラストバウンダリの説明自体は間違っていないが、Webアプリケーションの脆弱性をうまくモデル化できていない
  • 多くの場合データベースのデータは信用できるものと想定してアプリケーションを設計・開発する
  • セカンドオーダーSQLインジェクション等はSQLを正しく呼び出すことで解決できるもので、「データの信頼性」とは無関係
  • HTMLエスケープなしで表示するデータについてはデータベースに登録する前に検証することにより、データベースのデータを信用できるようにする

私は大垣さんの記事の熱心な読者なので、冒頭に紹介した問題文を見て、「(出題者であろう)大垣さんは3を正答にしたいのだろうな」とすぐに分かりましたが、同時に、大垣さんの記事をあまり読んだことがない方には、この問題を(国語入試問題必勝法以外の正攻法で)正答するのは難しいだろうなと思いました。この問題が、「世間の大多数が正しく理解しておらずマイクロソフト社のような著名企業でも間違って説明している」という大垣さんの持論を根拠にしているからです。

※追記※ 引用した問題の出題者が大垣さんではないかというのは、あくまでも予想です。しかし、仮に、大垣さんの出題でないとしても、引用した問題文が適切でないという結論は変わりません。

  1. charley-horse-blog reblogged this from ockeghem
  2. saje reblogged this from ockeghem
  3. tommby reblogged this from ockeghem
  4. ngyuki reblogged this from ockeghem
  5. act2012bl reblogged this from atm09td
  6. atm09td reblogged this from ockeghem
  7. sharkpp reblogged this from ockeghem
  8. send-blog reblogged this from ockeghem
  9. dara-j reblogged this from ockeghem
  10. kyomichi-blog reblogged this from ockeghem
  11. meggrim reblogged this from ockeghem
  12. yamato reblogged this from ockeghem and added:
    なせ設問からこんだけのことが解るんだ(笑)。特に個人の特定ww
  13. inchiki reblogged this from ockeghem
  14. bgnori-technology reblogged this from ockeghem
  15. ockeghem posted this
Google