(57)【特許請求の範囲】
【請求項１】
部分文字列情報記憶部を備えるコンピュータに，
所定のプログラムにおいて使用される，外部プログラムを読み出すためのコマンド文に追加される部分文字列を取得する部分文字列取得処理と，
前記コマンド文の静的要素として複数の単語からなる文字列を定義した定数情報をもとに，前記追加される部分文字列が定数であるかを判定する定数部分判定処理と，
前記部分文字列の値，当該部分文字列が追加される結合位置，および前記定数部分判定処理の判定結果をもとに前記部分文字列が定数または非定数のいずれかを示す属性を含む部分文字列情報を生成して前記部分文字列情報記憶部に格納する部分文字列情報生成処理と，
前記コマンド文を構築する場合に，前記部分文字列情報記憶部から前記コマンド文の部分文字列情報を取得し，前記部分文字列の属性が定数の場合に当該部分文字列の値を結合位置に従って前記コマンド文の所定のテンプレート文字列に追加する処理と，または前記部分文字列の属性が非定数の場合に当該部分文字列の値をパラメータリストに保持し，当該部分文字列に対応するプレースホルダを結合位置に従って前記テンプレート文字列に追加し，当該テンプレート文字列に追加したプレースホルダに前記パラメータリストに保持した当該部分文字列の値を設定する処理とを行うことによって，前記実行コマンド文を構築するコマンド文構築処理とを
実行させるためのコマンド文構築プログラム。
【請求項２】
前記コマンド文構築処理において，前記属性が非定数の部分文字列について，前記プレースホルダを前記テンプレート文字列の結合位置に追加し，当該非定数の部分文字列の値をパラメータリストに格納し，前記パラメータリストの部分文字列の値を前記プレースホルダに設定する処理を行うことによって，前記実行コマンド文を構築する処理を，
前記コンピュータに実行させるための請求項１に記載のコマンド文構築プログラム。
【請求項３】
前記コマンド文構築処理において，前記コマンド文が情報出力を行うものである場合に，前記プレースホルダに前記パラメータリストの部分文字列の値の代わりに所定の表示文字列を設定する処理を，
前記コンピュータに実行させるための請求項２に記載のコマンド文構築プログラム。
【請求項４】
前記コマンド文構築処理において，前記コマンド文が情報出力を行うものである場合に，前記属性が非定数の部分文字列について，当該部分文字列の値の代わりに所定の表示文字列を結合位置に追加する処理を行うことによって，前記実行コマンド文を構築する処理を，
前記コンピュータに実行させるための請求項１に記載のコマンド文構築プログラム。
【請求項５】
ユーザによって指示された部分文字列の属性を定数とする定数化指定処理を，
前記コンピュータに実行させるための請求項３または請求項４に記載のコマンド文構築プログラム。
【請求項６】
前記出力コマンド文構築処理において，任意の数列または文字列である乱数を生成し，前記表示文字列として用いる
ことを特徴とする請求項３または請求項４に記載のコマンド文構築プログラム。
【請求項７】
部分文字列情報記憶部を備えるコンピュータが実行する処理方法であって，
所定のプログラムにおいて使用される，外部プログラムを読み出すためのコマンド文に追加される部分文字列を取得する部分文字列取得過程と，
前記コマンド文の静的要素として複数の単語からなる文字列を定義した定数情報をもとに，前記追加される部分文字列が定数であるかを判定する定数部分判定過程と，
前記部分文字列の値，当該部分文字列が追加される結合位置，および前記定数部分判定処理の判定結果をもとに前記部分文字列が定数または非定数のいずれかを示す属性を含む部分文字列情報を生成して前記部分文字列情報記憶部に格納する部分文字列情報生成過程と，
前記コマンド文を構築する場合に，前記部分文字列情報記憶部から前記コマンド文の部分文字列情報を取得し，前記部分文字列の属性が定数の場合に当該部分文字列の値を結合位置に従って前記コマンド文の所定のテンプレート文字列に追加する処理と，または前記部分文字列の属性が非定数の場合に当該部分文字列の値をパラメータリストに保持し，当該部分文字列に対応するプレースホルダを結合位置に従って前記テンプレート文字列に追加し，当該テンプレート文字列に追加したプレースホルダに前記パラメータリストに保持した当該部分文字列の値を設定する処理とを行うことによって，前記実行コマンド文を構築するコマンド文構築過程とを，
備えるコマンド文構築処理方法。
【請求項８】
所定のプログラムにおいて使用される，外部プログラムを読み出すためのコマンド文に追加される部分文字列を取得する部分文字列取得部と，
前記コマンド文の静的要素として複数の単語からなる文字列を定義した定数情報をもとに，前記追加される部分文字列が定数であるかを判定する定数部分判定部と，
前記部分文字列の値，当該部分文字列が追加される結合位置，および前記定数部分判定処理の判定結果をもとに前記部分文字列が定数または非定数のいずれかを示す属性を含む部分文字列情報を生成して部分文字列情報記憶部に格納する部分文字列情報生成部と，
前記コマンド文を構築する場合に，前記部分文字列情報記憶部から前記コマンド文の部分文字列情報を取得し，前記部分文字列の属性が定数の場合に当該部分文字列の値を結合位置に従って前記コマンド文の所定のテンプレート文字列に追加する処理と，または前記部分文字列の属性が非定数の場合に当該部分文字列の値をパラメータリストに保持し，当該部分文字列に対応するプレースホルダを結合位置に従って前記テンプレート文字列に追加し，当該テンプレート文字列に追加したプレースホルダに前記パラメータリストに保持した当該部分文字列の値を設定する処理とを行うことによって，前記実行コマンド文を構築するコマンド文構築部とを
備えるコマンド文構築処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は，コンピュータのアプリケーションプログラムのインジェクション系の攻撃や情報漏洩などの脆弱性を防止するため，プログラム開発において，当該脆弱性に対処した安全なコマンド文の実装および確認を行う処理に関する。
【背景技術】
【０００２】
Ｗｅｂアプリケーションプログラムでは，ＳＱＬやＯＳコマンドへのインジェクション攻撃やデータ表示時の情報漏洩などの危険性がある。インジェクション攻撃，情報漏洩の脆弱性ついて，プログラム開発時から適切な対策が必要である。
【０００３】
インジェクション攻撃とは，サーバプログラムがクライアントから入力されたデータにもとづいて外部プログラムに何かのコマンドを送信する際に，攻撃者が入力データにコマンドの一部を挿入することにより，外部プログラムに意図しない動作をさせる攻撃をいう。
【０００４】
外部プログラムがリレーショナルデータベースである場合に，コマンドはＳＱＬであり，ＳＱＬ文を利用した攻撃はＳＱＬインジェション攻撃と呼ばれる。同様に，外部プログラムがＯＳ（オペレーティングシステム）で，コマンドがＯＳコマンドの場合には，ＯＳコマンドインジェクション攻撃と呼ばれる。
【０００５】
なお，一般的には異なる分類とされているクロスサイトスクリプティング（ＸＳＳ）攻撃も，外部プログラムをＨＴＭＬレンダラ（ブラウザ），コマンドをＨＴＭＬと考えれば，本質的な構造はインジェクション攻撃と同じである。
【０００６】
ＳＱＬインジェクション攻撃の典型例を説明する。以下のＳＱＬ文は，サーバプログラムが，認証時にデータベースに問い合わせを行い，ユーザＩＤ，パスワードに一致するデータが存在するときにデータを返すことを想定して構築されたクエリである。
【０００７】
SELECT * FROM utable WHERE user="(userid)" AND pass="(password)"
上記の(userid)，(password)の部分には入力データが入る。攻撃者が文字列「" or "a"="a」をパスワードとして入力させると，サーバプログラムが発行するクエリの構文は以下のように変更される。
【０００８】
SELECT * FROM utable WHERE user="dummy" AND pass="" OR "a"="a"
この変更の結果，「a=a」が常に真になり，(password)への入力が任意データであっても認証条件を満たすため，パスワード認証処理が無意味となってしまう。
【０００９】
このインジェクション攻撃の防御手法として，バインドメカニズムが知られている。バインドメカニズムでは，動的な値を埋めこむ位置があらかじめ指定された固定のテンプレート（クエリ文字列）を事前に準備しておき，動的な値は，指定位置のパラメータにバインドさせて文字列に組み込む手法である。
【００１０】
Ｊａｖａ（登録商標）のＰｒｅｐａｒｅｄＳｔａｔｅｍｅｎｔ，ＰｅｒｌのＤＢＩ，ＰＨＰ，ＰｙｔｈｏｎのＡＤＯｄｂ，ＶｉｓｕａｌＢＡＳＩＣ（登録商標）のＳＱＬＣｏｍｍａｎｄなどがこれに相当する。
【００１１】
図２０に，バインドメカニズムによるインジェクション攻撃防止の仕組みを示す。
【００１２】
図２０に示すように，予め準備されたＳＱＬ文（PreparedStatement）には，予めパラメータ入力位置が設定されている。そして，パラメータを全て入力文字列として扱うサニタイジング（無害化処理）を行い，パラメータによって構文が変化してしまうという脆弱性に対処している。
【００１３】
このバインド処理によって，攻撃者が「" or "a"="a」のような不正な値を入力した場合でも，準備されたＳＱＬ文の構文が変更せず，安全なクエリであることが保証される。
【００１４】
また，インジェクション攻撃に対する防御として，特許文献１に開示されているように，Ｗｅｂサーバ側でパラメータを含むメッセージのチェックポリシーを用意し，脆弱性を生じる入力値を含むメッセージがチェックポリシーに合致するかを判定し，合致するメッセージのみを有効として扱う処理手法もある。
【特許文献１】特開２００７−４６８５号公報
【発明の開示】
【発明が解決しようとする課題】
【００１５】
しかし，従来のバインドメカニズムによる対策には次のような２つの問題点がある。
【００１６】
（ａ）パラメータのバインドメカニズムを利用しないプログラミングが脆弱性を生じる：  ＪａｖａのPreparedStatementのクエリ文字列を構築する際に，図２１に示すように，入力値をパラメータとして指定せずに，通常のクエリの部分（文字列）として構築すると，その部分は，入力値であるにもかかわらずバインドされず，無害化処理が機能しないことになる。その結果，入力値がそのままクエリの一部となり，ＳＱＬインジェクション攻撃が可能になるおそれがある。
【００１７】
以下に，このような脆弱性を生じるＪａｖａプログラムの例を示す。
【００１８】
String query = “SELECT * FROM user_info WHERE 
user=\”” + userid + “\” AND pass=\”” + password + “\””;
PreparedStatement pstmnt = con.prepareStatement(query);
ResultSet rs = pstmnt.executeQuery();
（ｂ）クエリが動的に変化する場合に静的テンプレートの用意が困難になる：  条件分岐，ループなどによって発行され，その実行ごとに動的に変化するクエリである場合に，分岐やループの組み合わせ数だけ静的クエリのテンプレートを用意しなければならない。そのため，コーディング量とバグ発生率の増加を招き，保守性が低下するという問題が生じる。
【００１９】
以下のＪａｖａプログラムはキーワード検索の例であるが，キーの種類が６種類であると仮定すると，１から５までのキー組み合わせ総数６２通りのＳＱＬクエリのテンプレートを用意する必要がある。
【００２０】
Statement stmnt = con.createStatement();
String query = "SELECT * FROM user_info ";
Set keyset = map.keySet();
Iterator iter = keyset.iterator();
boolean first = true;
while (iter.hasNext()) {
String key =(String) iter.next();
String[] value = (String[]) map.get(key);
if(value[0] != ""){
if(!first) {
query+= " OR ";
} else {
query+= " WHERE ";
}
query+= key + "=\"" + value[0] + "\"";
first = false;
}
}
ResultSet rs = stmnt.executeQuery(query);
（ｃ）情報出力用のコマンドによって出力するべきではない情報の漏洩が生じる：  例えばデータベースから取得した情報を画面に表示するような場合に，取得情報には開示してもよい情報と秘匿すべき情報とが混在していることがあり，これらの情報は区別して扱う必要がある。しかし，不注意やプログラムミスなどによって，表示するべきでない情報（値）が表示され，情報漏洩を生じるおそれがある。このような脆弱性を生じるＪａｖａプログラムの例を下記に示す。
【００２１】
StringX sx;
sx.add(OutConst.userid); //userID = 
sx.add(userid);
sx.add(OutConst.password);// password = 
sx.add(password);
String outstr = "userid = " + userid + "password = " + password; 
outHTML(outstr);
しかし，システムは，どの情報を秘匿するべきかを判断できないため，プログラムミスによる情報漏洩をシステム的に防止することは困難であった。
【００２２】
本発明は，プログラム上で外部プログラム呼び出しのコマンド文（コマンド文字列）を構築する場合に，コマンド文に含まれる動的な値によって生じる脆弱性を排除した安全なコマンド文の構築処理をコンピュータに実行させるためのプログラム，または，コンピュータが当該コマンド文構築処理を行う処理方法，または，当該コマンド文構築処理を実行する処理装置を提供することを目的とする。
【課題を解決するための手段】
【００２３】
本プログラムを実行するコンピュータは，所定のプログラムにおいて使用される，外部プログラムを読み出すためのコマンド文を作成する場合に，部分文字列取得処理として，プログラムのコマンド文に追加される部分文字列を取得する。そして，定数部分判定処理として，コマンド文の静的要素（定数）として複数の単語からなる文字列を定義した定数情報をもとに，コマンド文に追加される部分文字列が定数であるかを判定する。
【００２４】
次に，部分文字列情報生成処理として，追加される部分文字列の値，部分文字列が追加される結合位置，および定数部分判定処理の判定結果をもとに部分文字列の属性（定数／非定数）を含む部分文字列情報を生成し，部分文字列情報記憶部に格納する。
【００２５】
その後，前記プログラム実行時など，コマンド文構築が必要になった場合に，コマンド文構築処理として，部分文字列情報記憶部からコマンド文の部分文字列情報を取得し，部分文字列の属性が定数の場合には，部分文字列の値を結合位置に従ってコマンド文の所定のテンプレート文字列にそのまま追加する。または，部分文字列の属性が非定数の場合には，部分文字列に対応する所定の文字を結合位置に従ってテンプレート文字列に追加する。これらの追加処理を行うことによって，前記実行コマンド文を構築する。
【００２６】
そして，前記コマンド文構築処理において，部分文字列の属性が非定数の場合に，前記プレースホルダをテンプレート文字列の結合位置に追加する。さらに，この非定数の部分文字列の値をパラメータリストに格納し，パラメータリストに格納した部分文字列の値をプレースホルダに設定する処理を行って，前記実行コマンド文を構築する。
【００２７】
本プログラムでは，コマンド文の作成時に，不定の要素が全てパラメータとして扱われる安全なコマンド文を生成することができるため，パラメータ以外の文字列部分に動的な値が組み込まれることによってバインドメカニズムによる無害化処理をすり抜ける部分を持つコマンド文を排除することができる。
【００２８】
また，プログラム上で動的にコマンド文を構築するため，バインドメカニズムによる対応が困難な構成のコマンド文であっても定数部分と非定数部分とを区別して構築することができ，プログラム実行時のインジェクション攻撃に対する脆弱性を除去することができる。
【００２９】
また，本プログラムでは，前記コマンド文構築処理において，コマンド文が情報出力を行うものである場合に，プレースホルダにパラメータリストの部分文字列の値の代わりに所定の表示文字列をバインドする処理を，前記コンピュータに実行させることができる。
【００３０】
また，本プログラムは，前記コマンド文構築処理において，コマンド文が情報出力を行うものである場合に，属性が非定数の部分文字列について，この部分文字列の値の代わりに所定の表示文字列を結合位置に追加する処理を行うことによって，実行コマンド文を構築する処理を，前記コンピュータに実行させることができる。
【００３１】
さらに，表示文字列として，乱数を発生させて用いてもよい。
【００３２】
これにより，プログラムミスがある場合でも，出力するべきでない情報が所定の定数値（表示文字列）で設定され，外部プログラムに渡されるため，明示的に定義されない限り非定数の部分はパラメータとみなされて隠蔽される。よって，プログラムミスによる情報漏洩を防止する処理が優先的に行われる安全なコマンド文を構築することができる。
【００３３】
また，本プログラムは，さらに，ユーザによって指示された部分文字列の属性を定数とする定数化指定処理を，前記コンピュータに実行させることができる。
【００３４】
これにより，ユーザ指示などによる明示的な設定によって，パラメータの出力または隠蔽を任意に設定することができるため，情報漏洩の防止を図りつつ柔軟なプログラミングを支援することができる。
【００３５】
なお，本プログラムは，コンピュータが読み取り可能な可搬媒体メモリ，半導体メモリ，ハードディスクなどの適当な記録媒体に格納することができ，これらの記録媒体に記録して提供され，または，通信インタフェースを介して種々の通信網を利用した送受信により提供される。
【発明の効果】
【００３６】
本発明によれば，プログラム開発においてコマンド文を生成する場合に，コマンド文に追加される部分文字列の定数／非定数の属性を判断し，部分文字列の属性に応じて異なる処理を行ってコマンド文構築のための情報を生成し，コマンド文構築が必要になった場合に，プログラム上で非定数の部分文字列をパラメータとしてコマンドのテンプレート文に追加することができる。これにより，コマンド文に含まれる動的な値によって生じるインジェクション攻撃に対する脆弱性に対処した安全なコマンド文構築を行うことができる。
【００３７】
また，コマンド文が外部からの取得値を出力するものである場合に，取得値を非定数の属性を持つ部分文字列として扱うため，表示用の定数値で置き換えて出力することができる。よって，プログラムミスなどによる情報漏洩の危険性を排除した安全なコマンド文構築を行うことができる。
【発明を実施するための最良の形態】
【００３８】
以下，本発明の最良の実施形態を，コンピュータ・ソフトウェアのＪａｖａプログラムによって実施するコマンド文構築処理装置を例に説明する。
【００３９】
コマンド文構築処理装置は，次の特徴を備える。
【００４０】
（１）コマンド文構築処理装置は，処理手段として，外部プログラム呼び出し用のインタフェースを具備する手続きライブラリを用意する。ここで，外部プログラム呼び出しに，表示画面への表示処理も含む。
【００４１】
なお，プログラミングにおいて，外部プログラム呼び出しでは，コマンド文構築処理装置で用意された手続きライブラリのみを用い，他の手段は用いないというルールのもとで行われる。
【００４２】
（２）コマンド文構築処理装置の各処理手段としての手続きライブラリは，手続き実行の引数として，下記の機能を具備するデータ構造型を受け付ける。
【００４３】
（ａ）コマンド文への部分文字列追加のための手続きインタフェースを具備する。
【００４４】
（ｂ）前記（１）のインタフェースの実行時に受け付けた部分文字列が「定数かどうか」を判定し，その判定結果と共に部分文字列の値をそのまま格納する。この時点で，受け付けた部分文字列の結合操作を行う必要がない。
【００４５】
（３）前記（１）の各手続きライブラリは，前記（１）のインタフェース実行時に，各部分文字列の構成要素が定数または非定数の場合に分けて，それぞれに応じた処理をコンテキスト（文中の前後関係）に応じて行い，プログラムを実行する。
【００４６】
これにより，インジェクション防止，情報漏洩防止などが図られ，安全なプログラム実行が実現できる。
【００４７】
図１は，コマンド文構築処理装置１の構成例を示す図である。
【００４８】
コマンド文構築処理装置１は，文字列生成部１０，部分文字列情報記憶部２０，コマンド文構築部３０，および乱数生成部４０を備える。
【００４９】
文字列生成部１０は，利用者のプログラム４において，外部プログラム５を呼び出すためにコマンド文を作成する場合に，コマンド文に追加される文字列を受け付けるインタフェースを備え，追加される部分文字列の定数／非定数の属性を判断し，部分文字列情報を部分文字列情報記憶部２０に格納する処理手段である。
【００５０】
また，文字列生成部１０は，利用者のプログラム４で使用されるコマンド文の静的要素である定数を定義した定数情報を保持しているものとする。
【００５１】
文字列生成部１０は，文字列追加部１１，定数部分判定部１３，部分文字列情報生成部１５，定数化設定部１７を備える。
【００５２】
文字列追加部１１は，利用者のプログラム４で外部プログラム５の呼び出し用のコマンド文が作成される時に，コマンド文に追加される部分文字列を受け付ける処理部である。
【００５３】
定数部分判定部１３は，定数情報をもとに，文字列追加部１１が受け付けた部分文字列が静的要素（定数）であるかを判定する処理手段である。部分文字列が定義情報に定義された静的要素であれば，その属性を定数と判断する。一方，部分文字列が静的要素でなく動的な値であれば，その属性を非定数と判断する。
【００５４】
部分文字列情報生成部１５は，部分文字列の部分文字列情報を生成し，部分文字列情報記憶部２０に格納する処理手段である。
【００５５】
部分文字列情報は，追加された部分文字列の値，その部分文字列がコマンド文に追加される位置（結合位置），定数／非定数の属性などを含む。
【００５６】
定数化設定部１７はユーザによって指定された部分文字列について，その属性を定数に設定する処理手段である。この設定によって，部分文字列が定数情報に該当しない要素であっても，部分文字列情報の属性に定数が設定される。
【００５７】
部分文字列情報記憶部２０は，部分文字列情報を記憶する記憶部である。
【００５８】
コマンド文構築部３０は，外部プログラム５の呼び出しコマンドの実行時など，コマンド文の構築が必要になったときに，コマンドのコンテキストに対応して具備する処理部を起動する処理手段である。
【００５９】
コマンド文構築部３０は，ＳＱＬ呼び出し部３１，ＯＳコマンド呼び出し部３３，ＨＴＭＬ生成部３５，出力情報生成部３７，バインド処理部３９を備える。
【００６０】
ＳＱＬ呼び出し部３１は，コマンドがＳＱＬである場合に，外部プログラム５（リレーショナルデータベースなど）への呼び出しに対応するコマンド文を構築する処理部である。ＳＱＬ呼び出し部３１は，部分文字列情報にもとづいて，コマンドのテンプレート文（ＳＱＬ文）に対し，定数の部分文字列を結合位置にそのまま追加する。また，非定数の部分文字列に対応するプレースホルダ（？）を結合位置に追加する。さらに，非定数の部分文字列の値を，パラメータとしてパラメータリスト３１０に保持する。
【００６１】
ＳＱＬ呼び出し部３１によって，ＳＱＬインジェクション攻撃へ対処することができる。
【００６２】
ＯＳコマンド呼び出し部３３は，コマンドがＯＳコマンドである場合に，外部プログラム５（ＯＳなど）への呼び出しに対応するコマンド文を構築する処理部である。ＯＳコマンド呼び出し部３３は，部分文字列情報にもとづいて，ＯＳコマンドのテンプレート文に対し，定数の部分文字列を結合位置にそのまま追加する。また，非定数の部分文字列に対応するプレースホルダを結合位置に追加する。さらに，非定数の部分文字列の値をパラメータリスト３１０に保持する。
【００６３】
ＯＳコマンド呼び出し部３３によって，ＯＳコマンドインジェクション攻撃へ対処することができる。
【００６４】
ＨＴＭＬ生成部３５は，コマンドがＨＴＭＬ生成である場合に，外部プログラム５へのＨＴＭＬ出力に対応するコマンド文を構築する処理部である。ＨＴＭＬ生成部３５は，ＨＴＭＬのテンプレート文に対し，定数の部分文字列を結合位置にそのまま追加する。また，非定数の部分文字列に対応するプレースホルダを結合位置に追加する。さらに，非定数の部分文字列の値を，パラメータリスト３１０に保持する。
【００６５】
ＨＴＭＬ生成部３５によって，クロスサイトスクリプティング攻撃へ対処することができる。
【００６６】
出力情報生成部３７は，コマンドが情報出力（例えば，出力画面の生成など）を行うものである場合に，外部プログラム５（例えば，表示装置など）へのコマンドに対応するコマンド文を構築する処理部である。出力情報生成部３７は，情報出力コマンドのテンプレート文に対し，定数の部分文字列を結合位置にそのまま追加する。また，非定数の部分文字列の代わりとして所定の表示文字列（例えば，アスタリスク文字列）を結合位置に追加する。
【００６７】
出力情報生成部３７によって，情報漏洩を防止することができる。
【００６８】
バインド処理部３９は，ＳＱＬ呼び出し部３１，ＯＳコマンド呼び出し部３３，またはＨＴＭＬ生成部３５によって，コマンドなどのテンプレート文に追加された非定数の部分文字列に対応するプレースホルダへ，パラメータリスト３１０に記憶された部分文字列の値をパラメータとして設定する処理部である。
【００６９】
乱数生成部４０は，表示文字列として用いられる乱数を生成する処理手段である。
【００７０】
図２に，コマンド文構築処理装置１の処理フローを示す。
【００７１】
コマンド文構築処理装置１は，利用者のプログラム４の作成処理中に，外部プログラム５への呼び出しコマンド文を作成しようとすると（ステップＳ１のＹＥＳ），文字列生成部１０が，コマンド文に追加される部分文字列を受け付け，部分文字列の属性判定および部分文字列情報作成などを行う処理（部分文字列作成処理）を実行する（ステップＳ２）。
【００７２】
その後，外部プログラム５の呼び出し実行によってコマンドの構築が必要になると（ステップＳ３のＹＥＳ），コマンド文構築部３０が，呼び出す外部プログラム５に対応するコマンド文の構築および実行を行う処理（コマンド文構築処理）を実行する（ステップＳ４）。
【００７３】
［部分文字列作成処理］
図３は，部分文字列作成処理（ステップＳ２）の処理フローを示す図である。
【００７４】
文字列生成部１０の文字列追加部１１は，利用者のプログラム４において，コマンド文が作成されるときに，コマンド文に追加される部分文字列を順に受け付ける（ステップＳ２０）。ここで，利用者のプログラム４において，図４に示すＳＱＬのコマンド文（select）が作成されるものとする。
【００７５】
定数部分判定部１３は，予め保持している定数情報（コマンドの静的要素（定数）の定義）をもとに，追加された部分文字列が定数であるかを判定する（ステップＳ２１）。追加された部分文字列が定数情報に該当する場合は（ステップＳ２１のＹＥＳ），その部分文字列に定数の属性を付与し（ステップＳ２２），定数情報に該当しない場合は（ステップＳ２１のＮＯ），その部分文字列に非定数の属性を付与する（ステップＳ２３）。
【００７６】
そして，部分文字列情報生成部１５は，追加される部分文字列ごとに，部分文字列の値，部分文字列が追加される位置（結合位置），定数／非定数のいずれかの属性を含む部分文字列情報を生成し，部分文字列情報記憶部２０に格納する（ステップＳ２４）。
【００７７】
ここで，図４に示すコマンド文として，追加された文字列のうち，ユーザＩＤ（id）とパスワード（password）についてユーザ入力された部分文字列（okubo）と（pass）は，定数情報に定義されていないので，非定数の文字列と判定される。
【００７８】
図５に，部分文字列情報の例を示す。
【００７９】
部分文字列情報として，文字列追加部１１が受け付けた部分文字列のすべてについて，文字列の値，定数部分判定部１３で判定された属性情報，結合のための位置情報が記録される。
【００８０】
例えば，１行目の部分文字列「SELECT * FROM utable WHERE id=“」は，定数情報に定義された要素（定数）であり，テンプレート文の第１番目の文字位置から第３１番目の文字位置に結合されることを示す。また，２行目の部分文字列「okubo」は，定数情報に定義された要素ではないので，属性が非定数であり，部分文字列がテンプレート文の第３２番目から第３６番目の文字位置に結合されることを示す。
【００８１】
［ＳＱＬコマンドのコマンド文構築処理］
利用者のプログラム４で外部プログラム５の呼び出しコマンドの構築が必要となった場合に，コマンド文構築部３０は，呼び出しコマンドのコンテキストに対応する呼び出し部を選択して起動する。
【００８２】
呼び出しコマンドがＳＱＬに関するものである場合に，ＳＱＬ呼び出し部３１が起動される。
【００８３】
図６に，コマンドがＳＱＬ呼び出しである場合のコマンド文構築処理（ステップＳ４）の処理フローを示す。
【００８４】
ＳＱＬ呼び出し部３１は，部分文字列情報記憶部２０から，該当するコマンド文の部分文字列情報を取得し（ステップＳ４００），部分文字列を１つずつ取り出す（ステップＳ４０１）。
【００８５】
そして，部分文字列の属性を調べて（ステップＳ４０２），部分文字列の定数が属性であれば（ステップＳ４０２のＹＥＳ），コマンドのテンプレート文に部分文字列の値をそのまま追加する（ステップＳ４０３）。
【００８６】
一方，部分文字列の属性が非定数であれば（ステップＳ４０２のＮＯ），部分文字列の値をパラメータリスト３１０に追加し（ステップＳ４０４），コマンドのテンプレート文に非定数の部分文字列に対応する文字としてプレースホルダ（？）を追加する（ステップＳ４０５）。
【００８７】
例えば，図５に示す部分文字列情報では，２番目の部分文字列「okubo」と４番目の部分文字列「pass」は，ユーザ入力値であり非定数と判定される。したがって，ＳＱＬ呼び出し部３１は，２，４番目の非定数の部分文字列に相当する位置にプレースホルダ「？０」，「？１」を設定し，パラメータリスト３１０に部分文字列の値を記録する。
【００８８】
図７に，パラメータリスト３１０の例を示す。パラメータリスト３１０には，プレースホルダのインデックスと部分文字列の値が記録される。
【００８９】
部分文字列情報の部分文字列すべてについてステップＳ４０１〜Ｓ４０５の処理を行い，全ての部分文字列に対する処理が終了したら（ステップＳ４０６のＹＥＳ），部分文字列を追加したテンプレート文で，実行コマンド文（PreparedStatement）を初期化する（ステップＳ４０７）。
【００９０】
次に，バインド処理部３９は，図８に示すように，初期化されたコマンド文のプレースホルダにパラメータリスト３１０の部分文字列の値を設定する（ステップＳ４０８）。
【００９１】
そして，コマンド文構築部３０によって，部分文字列の値がバインドされたＳＱＬコマンド文（PreparedStatement）が実行される（ステップＳ４０９）。
【００９２】
［ＯＳコマンドのコマンド文構築処理］
利用者のプログラム４の外部プログラム５の呼び出しコマンドがＯＳコマンドに関するものである場合には，ＯＳコマンド呼び出し部３３が起動される。本例では，利用者のプログラム４で，図９（Ａ）に示すＯＳコマンド（ファイル情報表示および検索）が作成されるとする。
【００９３】
図３の処理フローに示すように，文字列追加部１１によってＯＳコマンドに追加される部分文字列が受け付けられ，定数部分判定部１３によって受け付けた部分文字列の属性が判定され，文字列生成部１０によって，図９（Ｂ）に示す部分文字列情報が生成され記憶されているとする。
【００９４】
図１０に，コマンドがＯＳコマンドである場合のコマンド文構築処理（ステップＳ４）の処理フローを示す。
【００９５】
図１０に示す処理フローのステップＳ４１０〜Ｓ４１９の処理は，図６のステップＳ４００〜Ｓ４０９の各処理に対応する。ＯＳコマンド呼び出し部３３が，ステップＳ４１０〜Ｓ４１７の処理を行い，図１１（Ａ）に示すパラメータリスト３１０が保持される。そして，バインド処理部３９が，ステップＳ４１８の処理を行い，図１１（Ｂ）に示すようにプレースホルダに部分文字列をバインドする。これにより，図９（Ａ）のＯＳコマンドの実行が可能となる。
［ＨＴＭＬのコマンド文構築処理］
利用者のプログラム４において外部プログラム５へ出力するＨＴＭＬが生成される場合に，ＨＴＭＬ生成部３５が起動される。本例では，図１２（Ａ）に示すＨＴＭＬが記述され，図３に示す処理フローにしたがって，図１２（Ｂ）に示す部分文字列情報が生成され記憶されているとする。
【００９６】
図１３に，ＨＴＭＬ生成の場合のコマンド文構築処理（ステップＳ４）の処理フローを示す。
【００９７】
図１３に示す処理フローのステップＳ４２０〜Ｓ４２９の処理は，図６のステップＳ４００〜Ｓ４０９の各処理にほぼ対応する。そして，ＨＴＭＬ生成部３５が，ステップＳ４２０〜Ｓ４２７の処理を行い，バインド処理部３９がステップＳ４２８の処理を行う。
【００９８】
ただし，ステップＳ４２８の処理において，ステップＳ４０８の処理と同様に，プレースホルダに部分文字列の値をバインドするが，さらに，既知の手法によって，パラメータのサニタイジング（無害化処理）を行う。
【００９９】
また，ステップＳ４２９の処理では，コマンド文構築部３０が，バインドされたＨＴＭＬを外部プログラム５へ出力する。
【０１００】
［情報出力のコマンド文構築処理］
利用者のプログラム４において，外部プログラム５へ情報出力を行う場合には出力情報生成部３７が起動される。
【０１０１】
例えば，表示装置にデータベースから取得した情報を表示させる場合に，データ表示コマンドに，データベースからの取得値が組み込まれる。データベースから「氏名」「年齢」のデータ項目について「（大久保 隆代）」「（２８）」を得たときに，通常では，以下のとおり情報がすべて表示される。
【０１０２】
氏名＝（大久保 隆代）；年齢＝（２８）
プライバシー保護の観点などから，データ項目の情報を非表示／代替表示とするプログラミングが必要な場合でも，プログラムミスによって表示させてしまうおそれがある。
【０１０３】
文字列生成部１０では，データベースから取得した情報（値）は定数情報に定義されていないため，属性が非定数となり，図１４に示す部分文字列情報を生成する。
【０１０４】
そこで，利用者のプログラム４で外部プログラム５（表示装置）へデータベースの取得値を表示するコマンドが実行される場合に，出力情報生成部３７は，コマンドのテンプレート文に対し，定数の部分文字列の値「氏名」「年齢」を結合位置でそのまま追加し，非定数の部分文字列の値「（大久保 隆代）」「（２８）」の代わりに，表示文字列（アスタリスク文字列）を追加する。
【０１０５】
また，出力情報生成部３７は，乱数生成部４０によって生成された乱数を，表示文字列として使用することができる。
【０１０６】
これにより，データベースの情報が図１５（Ａ）に示すように表示され，プログラムミスによる不用意な表示処理から生じる情報漏洩を防止することができる。
【０１０７】
さらに，アプリケーションによっては，データベースからの取得情報に，表示対象と非表示の対象とが混在する場合がある。一例として，「氏名」の情報を表示し「年齢」の情報を非表示とする場合がある。
【０１０８】
この場合に，定数化設定部１７によって出力対象とする取得値を設定することができる。定数化設定部１７はインタフェースを備え，ユーザ指示によって出力対象として部分文字列情報の２番目の部分文字列「大久保 隆代」が指定されると，この部分文字列の属性を非定数から定数へ変更する。
【０１０９】
この属性変更によって，出力情報生成部３７が，属性が定数の部分文字列の値（大久保 隆代）をそのままコマンドのテンプレートに追加するので，図１５（Ｂ）に示すように，データベースの「氏名」の情報（大久保 隆代）が表示され，また，それ以外の非定数の部分文字列の値は，表示文字列（アスタリスク文字列，乱数）が表示される。
【０１１０】
図１６に，コマンドが情報出力である場合のコマンド文構築処理（ステップＳ４）の処理フローを示す。
【０１１１】
出力情報生成部３７は，部分文字列情報記憶部２０から表示対象となる部分文字列情報（データベースのデータ）を取得し（ステップＳ４３０），各項目（部分文字列）を１つずつ取り出す（ステップＳ４３１）。
【０１１２】
そして，部分文字列の属性を判定し（ステップＳ４３２），部分文字列の定数が属性であれば（ステップＳ４３２のＹＥＳ），情報出力コマンドのテンプレート文に部分文字列の値をそのまま追加する（ステップＳ４３３）。
【０１１３】
一方，部分文字列の属性が非定数であれば（ステップＳ４３２のＮＯ），表示文字列を生成し（ステップＳ４３４），コマンドのテンプレート文に生成した表示文字列を追加する（ステップＳ４３５）。
【０１１４】
部分文字列情報の部分文字列すべてについてステップＳ４３１〜Ｓ４３５の処理を行い，全ての部分文字列に対する処理が終了したら（ステップＳ４３６のＹＥＳ），部分文字列を追加したコマンドのテンプレート文を引数とした外部プログラム５の呼び出しを実行する（ステップＳ４３７）。
【０１１５】
以下，本発明のより具体的な実施例を示す。
【０１１６】
実施例において，コマンド文構築処理装置１は，文字列生成部１０，およびＳＱＬ呼び出し部３１を備えるコマンド文構築部３０を備えるものとする。コマンド文構築処理装置１は，Ｊａｖａプログラムとして実装される。
【０１１７】
［実施例１］
実施例１において防御対象となるインジェクション攻撃を説明する。攻撃の一例として，攻撃者が，ユーザ入力でなく，一旦メモリ上やデータベースに格納された値を利用してインジェクション攻撃（セカンドオーダーＳＱＬインジェクション攻撃）を行う場合が考えられ，以下のような状態が想定される。
【０１１８】
まず，攻撃者が，ユーザ登録時に「’admin’--」というユーザＩＤで登録しておく。
【０１１９】
ここで，パスワード変更時に以下のＳＱＬ呼び出しを実行するようにプログラムが書かれているとする。
【０１２０】
sql="select * from users where username='" + username + "' 
and password='" + oldpassword"'";
sql="update users set password='" 
+ newpassword + "' where username='" + rso("username") + "'";
すると，登録されたユーザIDにより，上記コードの３，４行目のＳＱＬは以下のように変えられ，“admin”のパスワードが攻撃者によって変更されてしまう。
【０１２１】
update users set password='passwd2' where username='admin'--'
したがって，ユーザ入力値のみを対象としてサニタイズやバインドメカニズムの適用を行っていると，セキュリティ対策の対象外となっているような値，過去に入力された値やデータベースに格納されている値など，を利用されて攻撃されるおそれがある。前述のコード例では，ＳＱＬ呼び出しの下段（３，４行目）のＳＱＬの"username"が，データベースに格納された値であるために，サニタイズやバインドメカニズムの対象から漏れてしまうことが原因となっている。
【０１２２】
このような攻撃に対処できるコマンド文構築処理装置１の構成と動作を説明する。
【０１２３】
（１）文字列生成部１０は，以下に示すＳＱＬの静的構文要素を定義する定義情報を備える。
【０１２４】
- select * from users where username=
- and password=
- update users set password=
- where username=
また，文字列生成部１０は，以下のインタフェース（文字列追加部１１に相当する機能）を持つ。
【０１２５】
public class StringX {
public void add(Object o){
}
}
（２）プログラマが，文字列生成部１０のインタフェースを用いて，ＳＱＬクエリを構築する文字列を以下のように記述する。
【０１２６】
StringX sx;
...
sx.add{QCOnst.SELECT}; //select * from users where username=
sx.add(username);
sx.add(QConst.AND); //and password=
sx.add(oldpassword);
....
sx.add(QCOnst.UPDATE); //update users set password=
sx.add(newpassword);
sx.add(QConst.WHERE); // where username=
sx.add(username);
（３）前記StringX#add()，すなわち文字列生成部１０のインタフェースが実行された場合に，add()内部では以下の処理が実行される。
【０１２７】
（３ａ）add()の引数(Object)が，定数かどうかを判定する（定数部分判定部１３に相当する機能）。本実施例では，定数かどうかは，そのObjectが指定されたenum型(QConst)であるかどうかで判断する。
【０１２８】
（３ｂ）定数のものには定数フラグを付与し，部分文字列情報記憶部２０に格納する。上記（２）の最後４行のコードが実行された時点で，部分文字列情報記憶部２０に格納されている部分文字列情報は，図１７（Ａ）に示すとおりになる。
【０１２９】
（４）プログラマは，コマンド文構築処理装置１の一部として用意された，安全なＳＱＬ実行インタフェースSqfeExec#execSQL()を，sxを引数として実行するプログラム４を記述する。そして，execSQL実行時には以下の処理が行われる。
【０１３０】
（４ａ）部分文字列を順に調べ，部分文字列が定数であれば，PreparedStatementの構成文字列ｑに追加する。
【０１３１】
（４ｂ）部分文字列が定数でなければ，部分文字列の値をパラメータリスト３１０に追加し，上記文字列ｑにはプレースホルダ（？）を追加する。
【０１３２】
（４ｃ）前記（４ａ），（４ｂ）の処理が完了すると，図１７（Ｂ）に示すPreparedStatementの初期化文字列と，図１７（Ｃ）に示すパラメータリスト３１０が得られる。
【０１３３】
（４ｄ）次に，得られた初期化文字列を用いてPreparedStatementの初期化が行われ，プレースホルダにパラメータリスト３１０の値（パラメータ）がバインドされる。そして，PreparedStatement.executeQuery()によりＳＱＬ実行が行われる。
【０１３４】
以上の処理が実行された場合に，攻撃者によって過去に登録されたユーザＩＤ「admin'--」は，値そのものがパラメータとして扱われるため，「'--」（以降を無視する）が構文を変更する要素として機能しない。これにより，セカンドオーダーＳＱＬインジェクション攻撃を防御することができる。
【０１３５】
また，利用者が定数として定義すべき箇所を誤ってそのまま入力させた場合，例えば，前記コードにおいて「update users set...」の部分を定数として定義しない場合には，その部分文字列が，非定数すなわちパラメータとみなされ，生成されるPreparedStatementの初期化文字列は以下のとおりになる。
【０１３６】
?? and where userid=?
このようなコードは，PreparedStatementの構文として不正であってエラーとなるため，プログラムミスとして検出が可能になる。
【０１３７】
［実施例２］
さらに，実施例２として，プログラマがプログラムミスにより，データベースから取得した非表示とするべき情報を誤って表示させてしまう場合を想定する。例えば，プログラマが，本来表示すべきでないユーザＩＤ，パスワードを誤って表示させるプログラムを書くとする。
【０１３８】
コマンド文構築処理装置１では，出力に，コマンド構築部３０の各手段として用意した出力ライブラリを必ず用いることになる。そこで，プログラマは以下のように記述する。
【０１３９】
StringX sx;
sx.add(OutConst.userid); //userID = 
sx.add(userid);
sx.add(OutConst.password);// password = 
sx.add(password);
SafeExec.outHTML(sx);
前記のコードにおいて，sx.add()では実施例１と同様に，追加された部分文字列が定数かどうかの判別が行われるので，最終的に生成される部分文字列の構造は，図１８に示す部分文字列情報のとおりとなる。
【０１４０】
また，SafeExec.outHTML()（ＨＴＭＬ生成部３５のインタフェースに相当）の実行時において，部分文字列が非定数の場合には実際の部分文字列の値（文字）の代わりに「＊」が出力される。その結果，ＨＴＭＬに出力される文字列は下記の通りとなる。
【０１４１】
user ID = *****    password = *****
これにより，非表示とする情報を誤って表示させるというプログラムミスがあっても，情報漏洩を防止することができる。
【０１４２】
さらに，データベースからの取得値の一部だけを隠蔽する場合には，部分文字列の追加時に，明示的に「定数」とみなす部分文字列を特定する機能（定数化設定部１７に相当）によって，データベースからの取得値のうち表示させる情報を特定することができる。
【０１４３】
一例として，パスワードは隠したいが，ユーザＩＤはそのまま表示させたい場合に，プログラマは前記のコードの代わりに下記のように記述する。
【０１４４】
StringX sx;
sx.add(OutConst.userid); //userID = 
sx.addConst(userid);
sx.add(OutConst.password);// password = 
sx.add(password);
SafeExec.outHTML(sx);
String#addConst()（定数化設定部１７のインタフェース，文字列追加部１１に相当）は，文字列が追加された時に，それを強制的に定数とみなして部分文字列に追加する。
【０１４５】
この結果，生成される部分文字列情報は，図１９に示すとおりとなり，以下のようなＨＴＭＬ出力となる。
【０１４６】
user ID = admin    password = *****
以上，本発明をその実施の形態により説明したが，本発明はその主旨の範囲において種々の変形が可能であることは当然である。
【図面の簡単な説明】
【０１４７】
【図１】本発明の実施の形態におけるコマンド文構築処理装置の構成例を示す図である。
【図２】本発明の実施の形態におけるコマンド文構築処理装置の処理フローを示す図である。
【図３】本発明の実施の形態における部分文字列作成処理の処理フローを示す図である。
【図４】本発明の実施の形態において，作成されるＳＱＬコマンド文の例を示す図である。
【図５】本発明の実施の形態における部分文字列情報の例を示す図である。
【図６】コマンドがＳＱＬ呼び出しである場合のコマンド文構築処理の処理フローを示す図である。
【図７】コマンドがＳＱＬ呼び出しである場合のパラメータリストの例を示す図である。
【図８】コマンドがＳＱＬ呼び出しである場合のバインド例を示す図である。
【図９】ＯＳコマンドが作成される場合に，作成されるＯＳコマンドおよび部分文字列情報の例を示す図である。
【図１０】コマンドがＯＳコマンド呼び出しである場合のコマンド文構築処理の処理フローを示す図である。
【図１１】コマンドがＯＳコマンド呼び出しである場合のパラメータリストおよびバインド例を示す図である。
【図１２】ＨＴＭＬが作成される場合に，作成されるＨＴＭＬおよび部分文字列情報の例を示す図である。
【図１３】ＨＴＭＬが作成される場合のコマンド文構築処理の処理フローを示す図である。
【図１４】コマンドが情報出力の場合に，作成される部分文字列情報の例を示す図である。
【図１５】コマンドが情報出力の場合の情報出力の例を示す図である。
【図１６】コマンドが情報出力である場合のコマンド文構築処理の処理フローを示す図である。
【図１７】コマンドが情報出力である場合の部分文字列情報，情報出力のコマンド，パラメータリスト例を示す図である。
【図１８】実施例１における部分文字列情報の例を示す図である。
【図１９】実施例２における情報出力の例を示す図である。
【図２０】バインドメカニズムによるインジェクション攻撃防止の仕組みを説明するための図である。
【図２１】バインドメカニズムが有効でない場合を説明するための図である。
【符号の説明】
【０１４８】
１  コマンド文構築処理装置
１０  文字列生成部
１１  文字列追加部
１３  定数部分判定部
１５  部分文字列情報生成部
１７  定数化設定部
２０  部分文字列情報記憶部
３０  コマンド文構築部
３１  ＳＱＬ呼び出し部
３３  ＯＳコマンド呼び出し部
３５  ＨＴＭＬ生成部
３７  出力情報生成部
３９  バインド処理部
３１０  パラメータリスト
４  利用者のプログラム
５  外部プログラム
【図１】
0005145967.tif 000002
【図２】
0005145967.tif 000003
【図３】
0005145967.tif 000004
【図４】
0005145967.tif 000005
【図５】
0005145967.tif 000006
【図６】
0005145967.tif 000007
【図７】
0005145967.tif 000008
【図８】
0005145967.tif 000009
【図９】
0005145967.tif 000010
【図１０】
0005145967.tif 000011
【図１１】
0005145967.tif 000012
【図１２】
0005145967.tif 000013
【図１３】
0005145967.tif 000014
【図１４】
0005145967.tif 000015
【図１５】
0005145967.tif 000016
【図１６】
0005145967.tif 000017
【図１７】
0005145967.tif 000018
【図１８】
0005145967.tif 000019
【図１９】
0005145967.tif 000020
【図２０】
0005145967.tif 000021
【図２１】
0005145967.tif 000022