webのお仕事を普段させていただいていますが、セキュリティ周りは大切だと思っていても、実際どんな脆弱性があってどんな対策をしないといけないのかを忘れてしまうことがあります。繰り返し学びなおす必要があると感じています。今回は、そんな脆弱性とセキュリティ実装のうち、SQLインジェクションについてIPAが出してくれているドキュメントを見かけたのでそちらを参考におさらいしてみます。
SQLインジェクション
SQLインジェクションは、データベースの脆弱性をついた攻撃です。多くのWebアプリケーションは利用者からの入力情報をもとにSQL文を組み立てますが、SQL文の組み立て方に問題がある場合に、不正に利用されてしまう可能性があります。
発生し得る脅威
SQLインジェクション攻撃で以下の問題が発生する可能性があります。
- データベースの非公開情報の閲覧
個人情報の漏洩 等 - データベースの情報の改竄、消去
ウェブページの改竄、パスワードの変更、システム停止 等 - 認証回避による不正ログイン
ログインしたユーザーに許可されている操作を不正に利用される - ストアドプロシージャ等を利用したOSコマンドの実行
システムの乗っ取り、他への攻撃の踏み台としての悪用 等
注意が必要なウェブサイトの特徴
MySQLやPostgresSQL等のデータベースを利用するウェブアプリケーションは注意が必要です。個人情報などの重要情報をデータベースに格納しているウェブサイトは特に注意が必要です。
根本的解決
- SQL文の組み立ては全てプレースホルダで実装する
SQLが通常もっているプレースホルダを用いてSQLを組み立てる仕組みを利用します。SQL文のひな型の中に変数の場所を示す記号(プレースホルダ)を置いて、後で実際の値を機械的な処理で割り当てる(バインド)ものです。後からバインドすることでSQLインジェクションの脆弱性を解消できます。 - SQL文の組み立てを文字連結により行う場合は、エスケープ処理などを行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する
SQL文の組み立てを文字連結で行う場合は、SQL文中で可変となる値を定数(リテラル)の形で埋め込みます。値を文字列型として埋め込む場合は、特別な意味をもつ文字列のエスケープ処理をし、数値として埋め込む場合は、数値型であることを確実にする処理をしてから埋め込みを行います。
また、この処理は外部から入力に影響を受ける値のみならず、SQL文を構成するすべての定数で行うべきです。 - ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない
例えば、formのhiddenパラメータ等にSQL文をそのまま指定したりするのは避けなければいけません。
保険的対策
- エラーメッセージをそのままブラウザに表示しない
データベースのエラーメッセージの内容をそのままウェブアプリケーションの画面上に表示すると、悪用するための有益な情報源となってしまいます。 - データベースのアカウントに適切な権限を与える
ウェブアプリケーションがデータベースに接続する際に使用するアカウントの権限が必要以上に高い場合、攻撃による被害が深刻化する可能性があります。必要な命令文を洗い出し、命令文の実行に必要な最小限の権限をアカウントに付与します。
今回はセキュリティの復習としてSQLインジェクションを取り上げました。
詳しい内容は以下のサイトで見ることができます。