完全なSQLインジェクション対策

(更新日: 2017/03/24)

不完全なSQLインジェクション対策だけで、SQLインジェクション対策は万全、と誤解しているケースが少なくないです。

  • プリペアードクエリ/プレイスホルダを使ったSQLインジェクション対策でOK

は誤りです。「とにかくプレイスホルダを使おう」では脆弱性は無くなりません。

前提条件

完全なSQLインジェクションでは入力対策も欠かせません。入力処理では、入力パラメータを厳格にバリデーションします。これは重要なセキュリティ対策ですが、重要でないと誤解しているケースが多々あります。入力処理も重要ですがここでは詳細は省略します。

参考:

OWASPセキュアコーディング – クイックリファレンスガイドにはセキュリティ対策の第一番目の要素として、セキュアに入力をバリデーションする方法が具体的に記載されています。

完全なSQLインジェクション対策では入力処理時に以下のバリデーションがされていることが必須です。

  • 文字エンコーディングのバリデーション
  • 数値パラメータのバリデーション(範囲を含む)
  • その他、当たり前のバリデーションすべて(ヌル文字や制御文字など、不正な文字でおかしな動作をするDBがある)

セキュアなプログラムの基本構造は以下の図のようになります。

セキュアなプログラムの基本構造

 

完全なSQLインジェクション対策 – 出力対策ではコンテクストを考える

前置きが長くなりましたが、本題のSQLクエリをサポートするデータベースシステムに対する完全な対策を紹介します。

入力処理の時点ではデータがどのような出力に使われるか判りません。例えば、ユーザー名はデータベースにも、メール、HTML、JavaScript、XPATHクエリ、LDAPクエリ、IMAPクエリ、コマンド実行にも利用されるかも知れません。

出力のコンテクストが重要です。出力コンテクストによって、安全な出力が方法が異るからです。データベース、ブラウザなど、出力先だけでなく、出力のコンテクストが重要です。

SQLシステムへのインジェクション攻撃を完全に防止するには、以下のような出力コンテクストを考慮した対策が必要です。データベースではSQL言語以外に、正規表現/XML/JSONなど別の言語や表現がサポートされています。以下のどれが欠けても、不正なデータ操作が行われる可能性があります

  • パラメーターの安全化(エスケープ、プリペアードクエリなどのAPI、バリデーション)
  • 識別子の安全化(エスケープ、バリデーション)
  • LIKEクエリの安全化(エスケープ、バリデーション)
  • 正規表現の安全化 (エスケープ、バリデーション)
  • XMLとXMLクエリの安全化 (エスケープ、バリデーション、APIの利用)
  • JSONデータの安全化 (エスケープ、バリデーション、APIの利用)
  • その他、全てのコンテクストの安全化

これらに加えて文字エンコーディングも重要です。出力先(この場合はSQLシステム)が期待する文字エンコーディングを使わないと誤作動する場合があります。通常、文字エンコーディングのバリデーションは入力処理で行うのでここでは省略しています。出力対策としては省略はしていますが、前述の通り、出力対策の前提として”文字エンコーディングが正しい”は必須のセキュリティ要素です。

出力対策では出力先のコンテクストが非常に重要ですが、これを疎かにしているケースは少なくありません。これを理解していないとSQLインジェクション対策として「パラメーターへのインジェクションを防止するプリペアードクエリだけ使えば大丈夫」と誤解します。

完全なSQLインジェクション対策には”エスケープ”と”バリデーション”が欠かせないです。つまり

  • エスケープや入力バリデーションはSQLインジェクションに対するセキュリティ対策ではない

とする主張や考え方は誤りであった、と言えます。

 

プリペアードクエリ/プレイスホルダは一部しか対応できない不完全な対策

プリペアードクエリ/プレイスホルダ(普通はパラメーターにしか対応していない)が不完全なセキュリティ対策であることに議論の余地はありません。

SQL言語の一部である識別子やLIKEクエリのインジェクションでさえ、プリペアードクエリ/プレイスホルダだけでは対応できません。(注:LIKEクエリインジェクションも正規表現インジェクションと同様に不正なデータ取得を許してしまうケースがある)

参考:

正規表現やXML、JSONと言った現在では当たり前のデータベース機能を安全に使うことも出来ません。

 

プリペアードクエリ/プレイスホルダはDoS攻撃にも対応できない

以下のクエリを考えると、プリペアードクエリ/プレイスホルダはインジェクションによるDoS攻撃にも対応できないことが明白です。

limit句以降に10000000000000000が挿入(インジェクション)1されて困るデータベースは数えきれません。

単純なパラメータに対するインジェクション攻撃にもプリペアードクエリ/プレイスホルダは完全に対応できません

参考:

正規表現をサポートするデータベースの場合、ReDoS攻撃に対する対策も欠かせません。これもプリペアードクエリ/プレイスホルダでは対策できません。

 

まとめ

出力処理際にはコンテクストが重要であることはセキュリティ専門家にとっては当たり前のこと2ですが、その当たり前が正しく啓蒙されていない時期が長くありました。今でも勘違いしている方が少くありません。

何が根本的な対策か?と区別するような考え方もあるようですが、この考え方は意味がないどころか、リスク分析の観点から有害でさえあります。

入力、出力、ロジック全てが根本的な対策であるので区別する意味はありません。 入力バリデーションと合わせて、ソフトウェア全体で安全性を高めることが必要です。

SQLシステムに限らず、出力対策は出力セキュリティ対策の三原則で完全に対応できます。

  1. エスケープ
  2. API(エスケープが不必要なAPI)
  3. バリデーション

この3つのうち1つ欠けても完全な対策になりません。この三原則を完全に適用するには、出力先のコンテクスト(多くの場合はそのコンテクストにおけるエスケープ方法、エスケープできない場合はバリデーションでリスクを廃除する方法)を正しく理解する必要があります。

 

 

蛇足

なぜ繰り返し解説していることを解説しているのか?を説明する蛇足なので、興味がない方は読む必要はありません。

「根本的なことが重要で他はオマケ、入力バリデーションはセキュリティ対策としてオマケ」の考え方の出所を知らなかったのですが、徳丸さん(スライド p54)のようでした。セキュリティ対策ではない、から進歩しているのですが、これはいただけません。

バリデーションも重要なセキュリティ対策です。「元々実行すべきモノがセキュリティ対策でない」というロジックも聞いたのですが、出力対策も元々実施すべきモノなのでセキュリティ対策ではない、も成り立ってしまいます。何を言いたいのか理解できません。

言った方が徳丸さんの考えから直接影響を受けたのか判りませんが「元々実施すべきで効果はあってもセキュリティ対策とは違う」と考えていることは、これはこのやり取りからも明らかです。

意味が通らないセキュリティ概念でセキュリティ対策をしていては、何時まで経っても「セキュリティとは何が何だか分らない」と混乱してしまう状況は変わりません。意味が通らない概念だと解らなくて当たり前です。

理由: セキュリティ対策の目的と手段 〜 根本的誤りの元 〜

徳丸さんとの議論は終わっている(標準セキュリティの概念とは全く異る、と結論は出ている)ので、議論するつもりはありませんが、誤りの指摘はしないとならないです。

このエントリは最近作ったと思われる不適切な資料(p53)を見かけたので改めて不十分なSQLインジェクション対策の指摘しておきます。

 

出力のセキュリティ対策は「一部の脆弱性の為に、とにかく◯◯をする」では無く、出力セキュリティの三原則(まとめ参照)がとにかく出力のセキュリティ対策で行うべきことです。

  1. エスケープ
  2. API(エスケープが不必要なAPI)
  3. バリデーション

SQLシステムへの出力だけ

  • パラメーターの安全化(エスケープ、プリペアードクエリなどのAPI、バリデーション)
  • 識別子の安全化(エスケープ、バリデーション)
  • LIKEクエリの安全化(エスケープ、バリデーション)
  • 正規表現の安全化 (エスケープ、バリデーション)
  • XMLとXMLクエリの安全化 (エスケープ、バリデーション、APIの利用)
  • JSONデータの安全化 (エスケープ、バリデーション、APIの利用)
  • その他、全てのコンテクストの安全化

を見ても、出力セキュリティの三原則で考えなければならないことが明らかです。いい加減、ソースコード検査時に「SQLにはプレイスホルダだけ使っていればOK」とするコードが無くなってほしいので、繰り返しになりますが指摘しました。

他の資料にも信頼境界線の考え方、リスク分析の考え方、ソフトウェアセキュリティの概念部分で根本的な誤りも見つけてしまいました。ツイッターで指摘したのですが無駄でした。ソフトウェアの信頼境界線が間違っている(アプリとデータベースが同じ境界内になっている)件を指摘した回答がこれです。

面倒ですが指摘しなければなりません。これも近日中に改めて誤りを指摘します。

 

 


  1. 通常はこのような異常な整数入力は入力処理のバリデーションで廃除されるべき。 
  2.  OWASPセキュアコーディング – クイックリファレンスガイドの7番目 

Comments

comments

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です