正しい出力とは
何を出力するかでエスケープしなければならない文字は変わるが、すべての変数でエスケープ処理するという点では変わりがない。また、この変数はエスケープしなくて良い、などという例外も作るべきではない。メンテナンス性や拡張性が低くなるためだ。また、何をもって例外とするのか実装者に判断させることとなりヒューマンエラーを誘発してしまう。
HTMLの出力
HTMLの仕様を考えれば、変数の値を挿入する個所によって必要なエスケープ処理が分かる。HTMLの要素の内容(正確ではないが、一般に開始タグと終了タグの間に挟まれる個所)として変数の値を出力することを考えると、「<」「>」「&」をエスケープする必要がある。
これは、「<」「>」がそのまま出力されてしまうと自由にタグを挿入することができるからであり、また「&」はHTMLエンティティや実体参照に利用される特殊文字だからだ。
また、属性の値として出力するときは「"」と「&」をエスケープするのが原則だ。その際、属性の値を「"」で括ることが前提となる。これも理由は単純で、「"」で括っている中に「"」が出力されてはHTMLの構造が崩れてしまうからだ。「&」のエスケープが必要なのは要素中の場合と同様となる。
なお、HTMLを出力するのだから、HTMLの仕様は知っておく必要があるだろう。詳しくは、W3Cのウェブサイトを参照してほしい。
SQL文の出力
SQL文での考え方もHTMLの時と同様だ。ただしSQL文の場合は、プリペアードステートメントやバインドメカニズムと呼ばれる機能を用いることで、独自実装を避け、安全なSQL文を出力することができる。
これが最善の手法だが、これが利用できない場合はSQL文に相応しいエスケープ処理を行うことになる。データベース全般でエスケープが必要な文字は、「'」や「\」(バックスラッシュ)があるが、SQLエンジンごとにさらに特殊文字があるので、それぞれのエンジンごとの特殊文字を忘れずエスケープする必要がある。
今回のまとめ
今回のまとめとして、ポイントは次の2つ。
- 正しい設計、コーディングを行えば脆弱性は生じない。
- 正しいコーディングとはいかなる入力がなされても意図通りの出力がなされるものである。
ここまで読んで、拍子抜けする読者も多いのではないだろうか。それは、当たり前のことしか書いていないからだ。しかし、実際にXSSやSQLインジェクションによる被害は相変わらず続いており、これらが実施できていないことを示している。また、実施したつもりでもそれができていない可能性もあるだろう。
次回は、今回までの内容をふまえて、セキュアプログラミングを「実施したつもり」から「実施できた」ことを確認するためのチェック方法について紹介したい。
■著者プロフィール
酒井喜彦テクマトリックス/シニア・エンジニア
プロフィール:2003年よりWatchfireのウェブアプリケーション脆弱性評価ツール「AppScan」専任エンジニアとしてウェブアプリケーションの診断、Web Application Security Forumへの参加など、ウェブアプリケーションセキュリティに特化して活動している。
■関連ホワイトペーパー
・WEBアプリケーションのセキュリティ:自動スキャンと手動による侵入テストの比較
・WEB アプリケーションにおける権限拡張の自動テスト