(57)【要約】【課題】  ソースコードの書き換えをせずにインジェクション脆弱性のあるプログラムを安全に実装できるようにする。【解決手段】  プログラム実行監視部１０が対象プログラム２の実行を監視し，置換箇所検出部１１がコマンド文の初期化で文字列追加箇所を検出し，置き換えの範囲を特定する。データ判定部１３が，ＳＱＬ文に追加される部分が不変であるかを判定する。定型文構築部１２は，不変の追加部分の文字列をコマンドの定型文に追加し，可変の追加部分の文字列をパラメータ候補蓄積部１５へ蓄積し，この追加部分を示すパラメータ位置を定型文に追加する。プログラム実行監視部１０が，プログラムの実行からコマンド文の呼出しを検出すると，定型文実行部１６がコマンド文を取得し，パラメータ位置にパラメータ候補蓄積部１５の該当する文字列を挿入した定型文を実行する。【選択図】  図１
2009129128.tif 000002
【特許請求の範囲】
【請求項１】
プログラムコードの実行を監視する実行監視処理と，
前記プログラムコードの実行から，コマンド文の初期化における文字列の追加操作を行う文字列追加箇所を検出する初期化時追加箇所検出処理と，
前記文字列追加箇所が検出された場合に，当該文字列追加箇所で追加される部分を抽出し，当該抽出された追加部分が不変であるかを判定する追加部分判定処理と，
前記不変であると判定された追加部分ｂｎの文字列を前記コマンド文として準備された定型文に追加して定型コマンド文字列を生成し，前記不変であると判定された追加部分以外の追加部分の文字列をパラメータ記憶部へ格納するとともに当該定型コマンド文字列に当該追加部分を示すパラメータを設定する定型コマンド文構築処理と，
前記プログラムコードの実行から，前記コマンド文の呼出しを行う呼出し箇所を検出する呼出し箇所検出処理と，
前記呼出し箇所が検出された場合に，前記定型コマンド文字列を取得し，当該定型コマンド文字列に設定された各パラメータに前記パラメータ記憶部に格納された対応する文字列を挿入し，当該呼出し箇所の引数であるコマンド文として前記取得した定型コマンド文字列を実行する定型コマンド文実行処理とを，
コンピュータに実行させるためのプログラム変換プログラム。
【請求項２】
プログラムコードの実行を監視する実行監視過程と，
前記プログラムコードの実行から，コマンド文の初期化における文字列の追加操作を行う文字列追加箇所を検出する初期化時追加箇所検出過程と，
前記文字列追加箇所が検出された場合に，当該文字列追加箇所で追加される部分を抽出し，当該抽出された追加部分が不変であるかを判定する追加部分判定過程と，
前記不変であると判定された追加部分の文字列を前記コマンド文として準備された定型文に追加して定型コマンド文字列を生成し，前記不変であると判定された追加部分以外の追加部分の文字列をパラメータ記憶部へ格納するとともに当該定型コマンド文字列に当該追加部分を示すパラメータを設定する定型コマンド文構築過程と，
前記プログラムコードの実行から，前記コマンド文の呼出しを行う呼出し箇所を検出する呼出し箇所検出過程と，
前記呼出し箇所が検出された場合に，前記定型コマンド文字列を取得し，当該定型コマンド文字列に設定された各パラメータに前記パラメータ記憶部に格納された対応する文字列を挿入し，当該呼出し箇所の引数であるコマンド文として前記取得した定型コマンド文字列を実行する定型コマンド文実行過程とを，
コンピュータが実行するプログラム変換処理方法。
【請求項３】
プログラムコードの実行を監視する実行監視部と，
前記プログラムコードの実行から，コマンド文の呼出しを行う呼出し箇所，または前記コマンド文の初期化における文字列の追加操作を行う文字列追加箇所を検出する該当箇所検出部と，
前記文字列追加箇所が検出された場合に，当該文字列追加箇所で追加される部分を抽出し，当該抽出された追加部分が不変であるかを判定する追加部分判定部と，
前記不変であると判定された追加部分の文字列を前記コマンド文として準備された定型文に追加して定型コマンド文字列を生成し，前記不変であると判定された追加部分以外の追加部分の文字列をパラメータ記憶部へ格納するとともに当該定型コマンド文字列に当該追加部分を示すパラメータを設定する定型コマンド文構築部と，
前記不変であると判定された追加部分以外の追加部分の文字列を格納するパラメータ記憶部と，
前記呼出し箇所が検出された場合に，前記定型コマンド文字列を取得し，当該定型コマンド文字列に設定された各パラメータに前記パラメータ記憶部に格納された対応する文字列を挿入し，当該呼出し箇所の引数であるコマンド文として前記取得した定型コマンド文字列を実行する定型コマンド文実行部とを備える
プログラム変換処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は，インジェクション攻撃に対して脆弱な既存のアプリケーションプログラムなどを安全に実行するためにプログラムを変換する処理技術である。より詳しくは，インジェクション脆弱性のあるプログラムを，ソースコードの変更を行わずに，プログラムの実行を監視して，インジェクション攻撃に対して脆弱な箇所を変換して実行することができる処理技術に関する。
【背景技術】
【０００２】
適切なインジェクション攻撃対策を行わずに開発されたＷｅｂアプリケーションプログラムには，ＳＱＬインジェクションやＯＳコマンドインジェクションに対する脆弱性がある場合が多い。
【０００３】
インジェクション攻撃の一つである，ＳＱＬインジェクションの例を次に示す。
【０００４】
図５に，Ｗｅｂアプリケーションの構成例を示す。クライアントマシン上のＷｅｂブラウザ９１で利用者が操作を行うと，利用者の操作をもとに生成されたデータがサーバに送信される。サーバプログラム９０では，Ｗｅｂブラウザ９１からの送信データを入力し，この入力データを使用して，データベースやＯＳ，シェルなどに対するＳＱＬやＯＳコマンドなどのコマンド文を組み立て（Ｓ１），そのコマンド文を引数にデータベースやＯＳを呼出して処理を実行する（Ｓ２）。
【０００５】
図６に，ＩＤ・パスワード認証処理におけるＳＱＬコマンドの呼出しの例を示す。Ｗｅｂブラウザ９１で利用者のＩＤ（ｕｓｅｒ）,パスワード（ｐａｓｓ）が入力されると，それらの値を検索条件に負荷したＳＱＬコマンドがサーバプログラム９０上で組立てられ，実行される。
【０００６】
図６（Ａ）に示すＳＱＬ文は，特定のＩＤ（ｕｓｅｒ）とパスワード（ｐａｓｓ）の組のデータを取得するものである。ところが，図６（Ａ）に示すように，ｐａｓｓに“‘ＯＲ‘Ａ＝Ａ’”のような値が入力されている場合に，単純なＳＱＬ文の組み立てでは，プログラムが意図しているＳＱＬコマンドとは構文的には異なるＳＱＬ文が組み立てられてしまう。図６（Ｂ）に示すように，入力データによって組み立てられたＳＱＬ文では，Ａ＝Ａが常に真になり，ｐａｓｓへの入力が任意のデータであっても認証条件を満たしてしまい，ＩＤ・パスワード認証処理が行われないことになる。
【０００７】
前記のように，このような不正な入力を行う(インジェクション攻撃)ことによって，呼び出されるコマンド文(ここではＳＱＬ文)の構文が変化し，サーバプログラム９０が意図していない処理が実行されることよって，なりすましや盗聴，データ改竄など様々な被害を被る危険がある。
【０００８】
図７に，ＳＱＬインジェクションの原因となる脆弱なＪａｖａ（登録商標）プログラムの例を示す。図７に示すプログラムが危険である原因は，次の２点である。
【０００９】
(a)  呼び出し関数(メソッド。ここではStatement.executeQuery())が，インジェクションに対して何も対処していない危険な状態の関数である。
【００１０】
(b)  上記関数の呼び出しの引数であるＳＱＬ文の組み立ての際に，入力される値と元々決まっている値(固定値)とが区別されずに追加されるため，最終的に完成したＳＱＬ文は，プログラムが意図したものかどうか判断できなくなってしまっている。
【００１１】
また，特許文献１に開示されているように，インジェクション攻撃に対する防御として，Ｗｅｂサーバ側でパラメータを含むメッセージのチェックポリシーを用意し，脆弱性を生じる入力値を含むメッセージがチェックポリシーに合致するかを判定し，合致するメッセージのみを有効として扱う処理手法もある。
【特許文献１】特開２００７−４６８５号公報
【発明の開示】
【発明が解決しようとする課題】
【００１２】
例えばＪａｖａでは，安全な関数(PreparedStatement.executeQuery())が用意されている。
【００１３】
図８に，PreparedStatementの仕組みを説明する図を示す。
【００１４】
図８に示すように，PreparedStatementを利用する場合に，プログラマによって，プログラム上で固定の定型文があらかじめ準備される。準備される定型文では，パラメータが挿入される構文上の位置があらかじめ定められている。また，パラメータに入力される値の中にＳＱＬの構文要素が含まれていた場合でも，その値はあくまでもパラメータとして扱われる。そのため，図８に示すように，ユーザによって不正な入力が実行されても，ＳＱＬ文の全体の構文が変化することはない。
【００１５】
図９に，PreparedStatementを使用したプログラムの例を示す。
【００１６】
図９のプログラムでは，パラメータへの値設定で，入力値は決められた場所にしか代入されない。図７のプログラムを，図９のPreparedStatementを使用したプログラムに書き換えれば，インジェクション攻撃を防御することができ安全なものとなる。
【００１７】
しかし，図７に示すStatementを用いた既存プログラムのソースコードを，図９に示すソースコードに書き換えることは，コード書き換え作業の手間がかかるうえ，プログラムの再コンパイルや再テストが必要になり，負担が大きい。
【００１８】
さらに，PreparedStatementによるプログラムの書き換えでは，別の問題もある。
【００１９】
図１０に示すプログラムのように，クライアントの入力条件などによって呼び出されるＳＱＬ文が変化する場合である。
【００２０】
図１０のプログラムでは，keys.lengthの値によってＳＱＬ文中の条件文の長さが変化する。このような場合に，事前に動的に変化するパターン数に対応させてPreparedStatementの定型文を用意することは不可能ではないが，大きな負担を生じさせる。すなわち，パターン数に対応する多くの定型文を用意しなければならず，コードの書き換えも複雑になり，保守性も低下する。
【００２１】
さらに，Ｊａｖａでは，Statementクラスを別のクラスに置き換えることによって，ソースコードを変更することなくStatement呼び出しをPreparedStatement呼び出しに変更する一般的な手法が知られている。
【００２２】
しかし，図１０に示すようなプログラムの場合には，呼出し箇所だけでなく，文字列の追加部分も置き換えに関係するため，単純なクラスの置き換えだけでは対応することができない。
【００２３】
本発明の目的は，これらの問題を解決するため，インジェクション脆弱性のあるプログラムを，ソースコードを書き換えることなく，プログラムパッチ的処理を施すことによって，インジェクション脆弱性に対して安全なプログラムとして実装できるように変換することである。
【課題を解決するための手段】
【００２４】
上記課題を解決するプログラムは，１）プログラムコードの実行を監視する実行監視処理と，２）前記プログラムコードの実行から，コマンド文の初期化における文字列の追加操作を行う文字列追加箇所を検出する初期化時追加箇所検出処理と，３）前記文字列追加箇所が検出された場合に，当該文字列追加箇所で追加される部分を抽出し，当該抽出された追加部分が不変であるかを判定する追加部分判定処理と，４）前記不変であると判定された追加部分の文字列を前記コマンド文として準備された定型文に追加して定型コマンド文字列を生成し，前記不変であると判定された追加部分以外の追加部分の文字列をパラメータ記憶部へ格納するとともに当該定型コマンド文字列に当該追加部分を示すパラメータを設定する定型コマンド文構築処理と，５）前記プログラムコードの実行から，前記コマンド文の呼出しを行う呼出し箇所を検出する呼出し箇所検出処理と，６）前記呼出し箇所が検出された場合に，前記定型コマンド文字列を取得し，当該定型コマンド文字列に設定された各パラメータに前記パラメータ記憶部に格納された対応する文字列を挿入し，当該呼出し箇所の引数であるコマンド文として前記取得した定型コマンド文字列を実行する定型コマンド文実行処理とを，コンピュータに実行させることを要件とする。
【００２５】
前記プログラムが実行されるコンピュータは，以下のように作用する。
【００２６】
まず，処理対象となるプログラムコードの実行を監視し，コマンド文の初期化でコマンド文に文字列の追加操作を行う文字列追加箇所を検出する。続いて，検出した文字列追加箇所で追加される部分を抽出し，抽出された追加部分が不変であるかを判定する。
【００２７】
そして，追加部分が不変であれば，この不変の追加部分の文字列を前記コマンド文として準備された定型文に追加し，追加部分が可変であれば，この可変の追加部分は動的に生成された値であるので，その文字列をパラメータ記憶部へ蓄積し，さらに，この追加部分を示すパラメータ位置を前記定型文に設定し，定型コマンド文を構築する。
【００２８】
続いて，前記プログラムコードの実行から，前記コマンド文の呼び出しを検出すると，呼び出しの引数として前記定型コマンド文を取得し，パラメータ位置にパラメータ記憶部に格納された対応する文字列を挿入し，パラメータに文字列が挿入された定型コマンド文を実行する。
【００２９】
これにより，インジェクション脆弱性のあるプログラムコードの実行において，引数のコマンド文での条件文の長さが変化する場合でも，追加される引数文字列をリテラルに扱うコマンド文を動的に構築かつ呼出し時に実行することができるため，インジェクション攻撃を防御することができる。
【発明の効果】
【００３０】
前記プログラムが実行されるコンピュータによれば，プログラムのソースコードを書き換えることなく，汎用的な書き換え処理（パッチ処理）を適用することによって，インジェクション脆弱性があるコマンド文を，安全なコマンド文として実装させることができる。
【００３１】
さらに，従来の例えば固定的な定型文では適用が困難な，条件文の長さが変化するプログラムの場合でも，プログラムの実行時に動的に条件を付加してコマンド文を生成することができ，条件ごとに固定された定型文パターンを事前に用意しておく必要がなくなる。
【００３２】
よって，低コストかつ効率的にインジェクション攻撃を防御することが可能となる。
【発明を実施するための最良の形態】
【００３３】
以下，本発明の実施の最良の形態を，コンピュータのソフトウェアのＪａｖａプログラムとして実施する場合を例に説明する。
【００３４】
まず，本発明にかかるプログラムの特徴は次の点である。
【００３５】
１．以下の汎用の置き換え処理(パッチ処理)を定義する。
【００３６】
・プログラムコードの中で，コマンド文実行箇所と，その引数の文字列変数の初期化を検出し，検出した箇所をもとに置き換え対象になる範囲を抽出する。
【００３７】
・前記で検出した文字列の追加操作で，追加される部分（文字列）を抽出し，その部分が，固定的な文字列であるか（不変かどうか）を判定する。
【００３８】
・前記追加部分の不変かどうかの情報をもとに，パラメータ化した定型コマンド文を動的に作成し，コマンド文実行時に，元の関数呼び出しを，定型コマンド文を使った関数呼び出しで置き換える。
【００３９】
２．上記パッチ処理により，対象プログラムのバイトコードを書き換えて実行する。
【００４０】
次に，本発明の具体的な実現手段を概説すると，以下のとおりである。
【００４１】
(1)  プログラムのバイトコード上から，以下の3つの実行ポイントを検出するマッチングパターンを記述する：
(1-a)  コマンド文の実行(Statement.execute*)のポイント，
(1-b)  コマンド文の初期化(コンストラクタ実行)のポイント，
(1-c)  コマンド文の構築(文字列の追加処理)のポイント，
(2)  対象とするプログラムのコンパイル時またはロード時に，以下のコードを元のプログラムのバイトコードに追加する：
(2-a)  上記実行ポイントを対象実行時に検出するコード，
(2-b)  コマンド文変数の型に，準備しておいた定型文（prepared statement）の文字列とパラメータを蓄積するデータフィールドを追加定義するコード，
(2-c)  実行ポイントを検出した際に，以下の処理を実行するコード：
(2-c1)  コマンド文変数への追加処理：prepared statementの文字列の構築とパラメータの蓄積，
(2-c2)  呼出し文実行処理：蓄積された上記prepared statementとパラメータとを使い，PreparedStatementを構築し，Statement.execute()の代わりにPreparedStatement.executeQuery()を実行。
【００４２】
図１は，本発明の実施の形態における構成例を示す図である。
【００４３】
本発明にかかるプログラム変換処理装置１は，コンピュータプログラムとして実施されるプログラム実行監視部１０，置換箇所検出部１１，定型文構築部（PreparedStatement構築部）１２，データ判定部１３，部分文字列格納部１４，パラメータ候補蓄積部１５，定型文実行部（PreparedStatement実行部）１６を備える。
【００４４】
プログラム実行監視部１０は，対象プログラム２の実行を監視し，特定の実行ポイントを検出し，データの取得，または定型文構築部（PreparedStatement構築部）１２や定型文実行部（PreparedStatement実行部）１６の処理を実行する処理部である。特定の実行ポイントとして，コマンド文の実行(Statement.execute*)のポイント(1-a)を検出する。
【００４５】
置換箇所検出部１１は，対象プログラム２中の特定の実行ポイントを検出する処理部である。置換箇所検出部１１は，コマンド文の初期化(コンストラクタ実行)のポイント(1-b)，コマンド文の構築(文字列の追加処理)のポイント(1-c)を検出し，定型のＳＱＬ文で置き換える範囲を特定する。
【００４６】
定型文構築部（PreparedStatement構築部）１２は，定型文のＳＱＬ文（PreparedStatement)を構築する処理部である。
【００４７】
データ判定部１３は，ＳＱＬ文に追加されるデータが，不変であるか（固定的な文字列であるか）を判定する処理部である。
【００４８】
部分文字列格納部（PreparedStatementの部分文字列）１４は，構築処理の途中のPreparedStatement（定型文)を格納するデータフィールドである。
【００４９】
パラメータ候補蓄積部（パラメータリスト）１５は，PreparedStatement呼出しにおいて使用されるパラメータ候補を格納するデータフィールドである。パラメータリスト１５では，定型文のパラメータ部に設定するパラメータが順番に保持される。
【００５０】
定型文実行部（PreparedStatement実行部）１６は，PreparedStatementの部分文字列１４に格納された定型文と，パラメータリスト１５に格納されたパラメータにもとづいて，PreparedStatementによる呼出し(executeQuery())を実行する処理部である。
【００５１】
図２および図３に，本発明の実施の形態における処理フローを示す。
【００５２】
ステップＳ１０：  対象プログラム２が実行されると，プログラム実行監視部１０は，対象プログラム２の実行を監視する。
【００５３】
ステップＳ１１：  置換箇所検出部１１が，実行ポイントとして，対象プログラム２のＳＱＬ文の文字列を追加している箇所（文字列追加箇所）を検出する。
【００５４】
ステップＳ１２：  プログラム実行監視部１０は，文字列追加箇所から，追加する文字列の型，値を取得する。
【００５５】
ステップＳ１３：  PreparedStatement構築部１２に，ステップＳ１２で得たデータを渡して実行する。
【００５６】
ステップＳ１４：  PreparedStatement構築部１２では，データ判定部１３を用いて，追加されるデータが固定かどうか判定する。
【００５７】
ステップＳ１５：  データ判定部１３で追加されるデータが固定（不変）であると判定された場合に（ステップＳ１４のＹＥＳ），PreparedStatement構築部１２は，そのデータをPreparedStatementの部分文字列１４に追加する。
【００５８】
ステップＳ１６：  データ判定部１３で追加されるデータが固定ではない（パラメータ）と判定された場合に（ステップＳ１４のＮＯ），PreparedStatement構築部１２は，そのデータをパラメータリスト１５に追加する。
【００５９】
ステップＳ１７：  さらに，PreparedStatement構築部１２は，PreparedStatementの部分文字列１４に，プレースホルダ（定型文中でパラメータが追加される位置を示す文字“？n”）を設定する。
【００６０】
ステップＳ２０：  プログラム実行監視部１０は，置換箇所検出部１１を用いて，対象プログラム２の実行時にStatementクラスの呼出し(executeXXX())を検出する。
【００６１】
ステップＳ２１：  プログラム実行監視部１０は， PreparedStatement実行部１６を実行する。
【００６２】
ステップＳ２２：  PreparedStatement実行部１６は，PreparedStatementの部分文字列１４から，完成した定型文（文字列）を取得する。
【００６３】
ステップＳ２３：  PreparedStatement実行部１６は，パラメータリスト１５からパラメータの一覧を取得する。PreparedStatementの定型文のプレースホルダに対応するパラメータを挿入する。
【００６４】
ステップＳ２４：  対象プログラム２のStatementの呼び出しを，PreparedStatement（定型文）による呼び出しに置き換えて実行する。
【００６５】
図４に，前述の処理を図７のプログラムに適用した例を示す。
【００６６】
プログラムのＳＱＬ文に対する文字列追加箇所において，
「query = "SELECT FROM utable WHERE user="」と「query+="AND pass="」は，不変の文字列であるので，PreparedStatementの部分文字列１４に順に格納される。
【００６７】
一方，「query += request.getParameter("user")」と「query += request.getParameter("pass")」は，関数の戻り値（可変）であるので，その値（文字列）である"dummy"，"'OR A=A"をプレースホルダ‘?0’‘?1’に対応づけられてパラメータリスト１５に格納される。
【００６８】
図７のプログラムでは，ＳＱＬ文の構築時には入力値と固定値とが区別できるように構成されていなかった。しかし，本発明によれば，対象プログラム２の実行時に，追加される文字列が固定かどうかの判定を行い，PreparedStatementに変換するために必要なパラメータとそれ以外の部分とを分類することができる。
【００６９】
さらに，別の実施の形態として，本発明は，ＯＳのコマンド文についても適用することができる。ＳＱＬインジェクションだけでなく，ＯＳコマンドのインジェクションも同様の構造を持つことから，本発明を適用することにより，同様のプログラム変換処理を実現することができる。
【００７０】
すなわち，以下の処理を行う。
【００７１】
(1)  ＳＱＬ文のPreparedStatementと同様のPreparedStatementの構築処理
(2)  コマンド呼出しを，(1)で作成されたPreparedStatementの呼出しに変更する処理
【図面の簡単な説明】
【００７２】
【図１】本発明の実施の形態における構成例を示す図である。
【図２】本発明の実施の形態における処理フローを示す図である。
【図３】本発明の実施の形態における処理フローを示す図である。
【図４】本発明の処理をプログラムに適用した例を説明する図である。
【図５】Ｗｅｂアプリケーションの構成例を示す図である。
【図６】ＩＤ・パスワード認証処理におけるＳＱＬコマンドの呼出しの例を示す図である。
【図７】ＳＱＬインジェクションの原因となる脆弱なプログラムの例を示す図である。
【図８】PreparedStatementの仕組みを説明する図である。
【図９】PreparedStatementを使用したプログラムの例を示す図である。
【図１０】入力条件などによってＳＱＬの構文が変化する場合のプログラム例を示す図である。
【符号の説明】
【００７３】
１  プログラム変換処理装置１
１０  プログラム実行監視部
１１  置換箇所検出部
１２  定型文構築部（PreparedStatement構築部）
１３  データ判定部
１４  部分文字列格納部（PreparedStatementの部分文字列）
１５  パラメータ候補蓄積部（パラメータリスト）
１６  定型文実行部（PreparedStatement実行部）
２  対象プログラム
【図１】
2009129128.tif 000003
【図２】
2009129128.tif 000004
【図３】
2009129128.tif 000005
【図４】
2009129128.tif 000006
【図５】
2009129128.tif 000007
【図６】
2009129128.tif 000008
【図７】
2009129128.tif 000009
【図８】
2009129128.tif 000010
【図９】
2009129128.tif 000011
【図１０】
2009129128.tif 000012