IPAの「安全なSQLの呼び出し方」が安全になっていた


IPAは「安全なSQLの呼び出し方」(PDF)を以下のURLから公開しています。

http://www.ipa.go.jp/security/vuln/websecurity.html

「安全なSQLの呼び出し方」は危険である、とするエントリを書こうかと思い、久しぶりに内容を確認すると改定されていました。

古い「安全なSQLの呼び出し方」は基本中の基本である「正確なSQL文の組み立て」によるセキュリティ対策を解説していませんでした。Webセキュリティの向上を目指しているのがIPAですが、SQLを安全に利用する為に必要な基本中の基本を無視していました。はっきり言うと有害でした。

しかし、今の「安全なSQLの呼び出し方」は基本中の基本である「正確なテキストの組み立て」によるセキュリティ対策も解説しており、安全な解説書になっています。

しばらく前の話になりますが「安全なSQLの呼び出し方」の執筆に参加されている徳丸氏に「基本であるエスケープの解説が無いから追加すれば完璧」と指摘したのですが「エスケープは入れるつもりはない」との回答だったので、てっきり今でもエスケープ処理による正確なSQL文の組み立てによるセキュリティ対策は解説されていないと思っていました。

しかし、現在のIPAの文書はエスケープによるSQLインジェクション対策がメインと言って良いような内容になっており、全ての開発者にお薦めできる内容になっています。”日本語版(2010年3月18日公開)”となっているので随分前に改定されていたようです。

元々SQLはテキストベースのインターフェースを持つシステムです。SQLはインターフェースというより4GL(第四世代言語)です。言語であるためテキストを利用してどのようにデータを取得するのか、その手順を記述しデータを取得します。

テキストインターフェースを持つシステムを安全に利用する基本中の基本は、誤作動を起こさせない「正確なテキスト」を出力する事です。(参考:Webアプリセキュリティの基本ルール

テキストインターフェースを持つシステムでも、エスケープ処理を省略できるAPIが用意されている場合があります。実務ではこれらのAPIの利用を推奨して構わないです。APIを利用した方が効率よく実行できる場合も多いです。

しかし、プリペアードクエリも常に効率が良いとは限りません。(参考:SQLのエスケープ)プリペアードクエリは完全にテキストの組み立てによるクエリ作成を排除する仕組みでもありません。(参考:SQLの識別子のエスケープ

一時期「SQLインジェクション対策にはプリペアードクエリ(プレイスホルダ)さえ使えば良い」と誤った認識が広がった為、マイクロソフトなどはエスケープAPIを削除するという間違いまで犯してしまう状況になりました。

マイクロソフトは「テキスト文の組み立てによるSQLクエリの作成」を「プリペアードクエリに置き換えさせたい」という意図でエスケープAPIを作らなかったのだと思われます。しかし、私がソースコード検査をさせて頂いた.NETアプリケーションではレガシーなシステムで作成されたSQL文が多数利用されていました。これらのアプリケーションは独自にエスケープAPIを作成しエスケープ処理をするという、セキュリティ対策としては本末転倒のような状況になっていました。

現在のIPAの文書は文字リテラルのエスケープを解説していますが、識別子とSQL語句についてはまだ解説されていません。これらの解説を追加すれば”本当に”「安全なSQLの呼び出し方」になると思います。

多少追記が必要ですが、エスケープを詳しく解説しているので文脈から「正確なテキスト管理」が必要であることは理解できると思います。古いIPAの「安全なSQLの呼び出し方」は「危険である」と考えていましたが、今は「安全である」と思います。

関係者の皆様、改定版の公開ありがとうございました。次回の改定では是非、基本中の基本である正確なテキスト作成、識別子のエスケープ、SQL語句のバリデーションにも言及して頂けると有難いです。

データベースの開発に関わっている方にはリテラルのエスケープAPIは勿論、識別子のエスケープAPIもネイティブクライアントライブラリに用意して頂きたいです。PostgreSQLは随分前からAPIを提供しています。

参考

 


コメントを残す

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


二 × 3 =

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">