SQL インジェクションとは

【参考資料】
Oracle Direct Seminar PDF - SQLインジェクションを防ぐPL/SQLの書き方 (PDF)

(上記資料から引用)
SQL 文内で クライアントから提供されるデータを使用する アプリケーションを悪用し、それによって、制限付きデータを 表示または操作するためにデータベースにアクセスする方法。

SQL インジェクションの回避

SQL インジェクションは 動的に SQL を作成するときに 入力値に SQL の構文を混ぜられてしまうことで発生します。

なので回避するには・・・

  • できるだけ静的 SQL を使用する
  • バインド変数を使用する
    (動的SQLでもバインド変数を利用可能)
  • 入力値を検査する
  • 日付や数値などの型を自動ではなく TO_CHARAなどを使って明示的に変換する
  • オブジェクト名は USER_TABLES などのデータディクショナリから取得する

といったことが必要になります。

DBMS_ASSERT パッケージ

DBMS_ASSERT という入力値を検査するための 関数を提供してくれるパッケージがあります。 これを使って 動的 SQL を構成する文字列を検査できます。

【参考サイト】
DBMS_ASSERT - Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス 11g リリース1(11.1)

DBMS_ASSERT には次のような関数があります。

関数名 説明
ENQUOTE_LITERAL文字列リテラルを引用符で囲む
ENQUOTE_NAME名前を二重引用符で囲む
SIMPLE_SQL_NAME入力文字列が単純 SQL であることを検証
QUALIFIED_SQL_NAME入力文字列が修飾 SQL であることを検証
SCHEMA_NAME入力文字列が既存のスキーマ名であることを検証
SQL_OBJECT_NAME入力文字列が既存の SQL オブジェクトの修飾 SQL 名であることを検証

単純 SQL 名とは "ABC" のような普通の名前で、 修飾 SQL 名とは "A.B" のように 単純 SQL 名を "."(ドット) や "@" で 接続した名前です。

DBMS_ASSERT には、条件が満たされていない場合は 例外を発生し 条件が満たされていれば 戻り値として、入力値や安全な形へ変更した値を返してくれます。