(57)【要約】【課題】検証対象ソースコードを解析する際に必要となるメモリ量を縮小し、低コストでの解析を実現することと、ソースコードの不足部分を含む検証対象ソースコードの解析における解析精度を向上させる。【解決手段】検証対象コード１０７を、モデル化プログラム３０２にて、あらかじめ指定された特徴の明細を記述したモデルを作成し、データフロー解析プログラム３０４にて、モデル化された検証対象ソースコード１０７を基にしてデータフロー解析し、脆弱性検出プログラム３０６にて、データフロー解析の結果として出力したデータパスと脆弱性データベース１０６とを照合することにより、解析したデータパスのうち脆弱経路となるものを検出するにあたり、検証対象ソースコードのデータフローに着目し、上記処理を実行する前に、着目したデータフローを簡易化することにより、検証対象ソースコード１０７を縮小化する。【選択図】図３
2008299723.tif 000002
【特許請求の範囲】
【請求項１】
検証対象プログラムを検証するプログラム検証装置におけるプログラム検証方法において、
前記検証対象プログラムの検証対象ソースコードのデータフローを解析し、前記データフローの開始エッジ及び終了エッジを定めたエッジデータの集合を取得するステップと、
前記エッジデータの集合から、一のエッジデータの開始エッジが他のエッジデータの終了エッジと一致するエッジデータを抽出するステップと、
前記検証対象ソースコードから、前記抽出したエッジデータ以外のエッジデータに係るソースコードの一部または全部を削除することにより簡易化して、検証用の簡易ソースコードを生成するステップと、
を有することを特徴とするプログラム検証方法。
【請求項２】
前記プログラム検証装置は、前記検証対象プログラム、プログラムを検証するときに着目する特性を示した特性情報、及び前記簡易ソースコードを検証用にモデル化するためにあらかじめ指定された特徴を記憶する記憶手段を有し、
前記記憶手段から前記指定された特徴を読み出し、前記読み出した特徴に基づいて、前記簡易ソースコードを検証用にモデル化するステップと、
前記モデル化した簡易ソースコードのデータフローを解析し、前記データフローの開始エッジ及び終了エッジを定めたエッジデータの集合を取得し、前記エッジデータの集合から、一のエッジデータの開始エッジと他のエッジデータの終了エッジとを連結したデータパスを生成するステップと、
前記記憶手段から前記特性情報を読み出し、前記読み出した特性情報に基づいて、前記データパスにおける特性の有無を検出するステップと、
を有することを特徴とする請求項１に記載のプログラム検証方法。
【請求項３】
前記エッジデータを抽出するステップにおいて、
前記抽出されるエッジデータには、前記検証対象ソースコードのうち、一または二以上の処理に対応するソースコードから定まる範囲の外部を前記開始エッジとするエッジデータと、前記範囲の外部を前記終了エッジとするエッジデータが含まれることを特徴とする請求項２に記載のプログラム検証方法。
【請求項４】
前記範囲は、前記検証対象ソースコードをJava（登録商標）言語で記述した場合には、クラスとして定められたものであることを特徴とする請求項３に記載のプログラム検証方法。
【請求項５】
前記プログラム検証装置が、前記検証対象プログラムの検証の指示を入力する入力手段を有し、
前記記憶手段が、前記検証するプログラムの一部分を記憶している場合、
前記入力手段により前記プログラムの検証の指示が入力されるとき、前記プログラム検証装置の外部からネットワークを介して、前記検証するプログラムの残りであって前記簡易化と同様の簡易化がなされたものを、外部簡易ソースコードとして生成するステップと、
前記入力手段により前記外部簡易ソースコードを入力するステップとを有し、
前記モデル化するステップにおいて、前記検証するプログラムの一部分に対応するソースコード及び前記外部簡易ソースコードをモデル化し、
前記データパスを生成するステップにおいて、前記モデル化した、前記検証するプログラムの一部分に対応するソースコード及び前記外部簡易ソースコードのデータフローを解析し、前記データフローの開始エッジ及び終了エッジを定めたエッジデータの集合を取得し、前記取得したエッジデータの集合から、一のエッジデータの開始エッジと他のエッジデータの終了エッジとを連結したデータパスを生成し、
前記特性の有無を検出するステップにおいて、前記記憶手段から前記特性情報を読み出し、前記読み出した特性情報に基づいて、前記データパスにおける特性の有無を検出する
ことを特徴とする請求項２から請求項４に記載のプログラム検証方法。
【請求項６】
前記プログラム検証装置が、前記検証対象プログラムの検証の指示を入力する入力手段を有し、
前記記憶手段が、前記検証するプログラムの一部分を記憶している場合、
前記入力手段により前記プログラムの検証の指示が入力されるとき、前記プログラム検証装置の外部からネットワークを介して、前記検証するプログラムの残りであって前記簡易化と同様の簡易化がなされ、外部簡易ソースコードとして生成するステップと、
前記プログラム検証装置の外部においてあらかじめ指定された特徴に基づいて、前記外部簡易ソースコードを外部モデル化し、前記入力手段により前記外部モデル化した外部簡易ソースコードを入力するステップとを有し、
前記モデル化するステップにおいて、前記検証するプログラムの一部分に対応するソースコードをモデル化し、
前記データパスを生成するステップにおいて、前記モデル化した前記検証するプログラムの一部分に対応するソースコード及び前記外部モデル化した前記外部簡易ソースコードのデータフローを解析し、前記データフローの開始エッジ及び終了エッジを定めたエッジデータの集合を取得し、前記取得したエッジデータの集合から、一のエッジデータの開始エッジと他のエッジデータの終了エッジとを連結したデータパスを生成し、
前記特性の有無を検出するステップにおいて、前記記憶手段から前記特性情報を読み出し、前記読み出した特性情報に基づいて、前記データパスにおける特性の有無を検出する
ことを特徴とする請求項２から請求項４に記載のプログラム検証方法。
【請求項７】
前記外部簡易ソースコードが前記検証するプログラムの検証対象ソースコードと異なる構文規則で記述されているため、前記外部簡易ソースコードを外部モデル化しても当該外部モデル化した外部簡易ソースコードのデータフローを解析することができない場合、
前記外部簡易ソースコードにおいて、前記外部簡易ソースコードの言語仕様にはないデータの受け渡しを表現する演算子を用いてデータフローであることを示すコードを記述するステップとを有し、
前記外部簡易ソースコードを入力するステップにおいて、前記演算子を含む外部簡易ソースコードを外部モデル化し、前記入力手段により前記外部モデル化した、前記演算子を含む外部簡易ソースコードを入力し、
前記演算子に基づいて、前記外部モデル化した、前記演算子を含む外部簡易ソースコードをモデル変換するステップとを有し、
前記データフローの解析を行うことを特徴とする請求項６に記載のプログラム検証方法。
【請求項８】
請求項１から請求項７までのプログラム検証方法を実行するプログラム検証装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータのセキュリティ、さらに詳細には、セキュリティ・リスクの問題を起こす可能性のあるコンピュータのソースコード内の脆弱性を生じさせるプログラム上の情報の流れの経路を検出するプログラム検証方法等に関する。
【背景技術】
【０００２】
企業の顧客情報管理や社員情報管理など、使用者によりコンピュータ端末から入力されたデータを基に情報管理するソフトウェアにおいて、そのソフトウェアが脆弱性を有する場合、コンピュータ端末から特殊な文字列を入力することでソフトウェアに不正な命令を実行させることが可能となる場合がある。そのようなソフトウェアでは、ソフトウェアの管理下にある情報が漏洩、改竄および消去されたりする問題が生じるおそれがある。このことにより、情報の消失による直接的な損害のみならず、企業の社会責任問題による信頼の失墜を招いてしまう。典型的な脆弱性の例として、クロスサイトスクリプティングやＳＱＬインジェクションが挙げられる。
【０００３】
クロスサイトスクリプティングとは、任意のユーザのローカル環境でプログラムを実行できるという脆弱性である。具体的には、Ｗｅｂサイトへの訪問者の入力内容がＷｅｂサイトに表示されるプログラム（例えば、インターネット掲示板など）において、入力にプログラムコードを含んだ内容を送ることで、その内容がＷｅｂサイトに掲載された場合、そのＷｅｂサイトを訪問した他のユーザにプログラムコードを含んだ情報が送られ、結果的に任意のユーザのローカル環境でプログラムを実行できるという脆弱性である。
【０００４】
また、ＳＱＬインジェクションとは、任意のユーザにデータベースを改竄または消去されるという脆弱性である。具体的には、データベースと連携したＷｅｂサイトにおいて、ユーザからの入力をデータベースへの命令の一部として使っている場合、ユーザからの入力によりデータベースに含まれる情報が改竄または消去されるという脆弱性である。
【０００５】
これらの脆弱性はいずれも、ソフトウェアの機能に関する問題というよりもむしろ、予期しない入力が与えられた場合に発生するソフトウェアの利用時に発生する問題である。このように、ソフトウェアの利用時に発生する問題の場合、ソフトウェアが利用される前の開発過程で事前に脆弱性の存在を検知、検出できることが、プログラムの品質を向上させ、将来起こりうる危険因子を排除する上で重要である。そして、このような脆弱性を無くすためには、ソフトウェアを構成するプログラム自体を、その中でやり取りされるデータの流れ（経路）に従って、脆弱性に関して検証し、脆弱性を生じさせるデータの流れ（以下、「脆弱経路」という。）が存在するか否かを確認する必要がある。
【０００６】
一般的に、検証の対象にしようとするプログラムのソースコード（以下、「検証対象ソースコード」と呼ぶ。）は人間が理解しやすい形（言語）で記述されている。この検証対象ソースコードを、脆弱性を検出する機能を有するプログラム（以下、「検出ソフトウェアプログラム」と呼ぶ。）により解析して脆弱性を検出する場合、当該検出ソフトウェアプログラムにとって扱いやすい形に変換する必要がある。このとき、例えば、特許文献１に示されるように、検証対象ソースコードの各セクションに対し、あらかじめ指定された特徴の明細を記述したモデルに変換する「モデル化」と呼ばれる処理を行う。
【０００７】
特許文献１では、すべての検証対象ソースコードに対しモデル化を行ったモデルファイルを基にデータフローの解析を行う。その解析の結果、データの流れを定めたデータフロー情報とデータの流れ以外の何らかの特徴について定めた情報を取得する。そして、取得したデータフロー情報と予め準備しておいた脆弱性を発生させ得る情報の発生点および情報の使用点を関連付けて格納したデータベースとから、それらの発生点と使用点を含んだデータフロー、すなわち脆弱経路の検出を行う。
【０００８】
なお、本明細書において、上記情報の「発生点」という用語は、検証対象ソースコードのセクションのことであって、そのソースコードに係るプログラムを実行した場合、情報の外部入力を受け取るセクションを指す。また、上記情報の「使用点」という用語は、検証対象ソースコードのセクションのことであって、そのソースコードに係るプログラムを実行した場合、情報を外部出力するセクションを指す。
【特許文献１】特表２００６−５２３８９８号公報
【発明の開示】
【発明が解決しようとする課題】
【０００９】
一般的に、プログラムのソースコードを解析する場合、ソースコードのソースコードサイズに比例して、解析に必要となるメモリ量は大きくなり、かつ、プログラム全体の解析時間は長くなる傾向にある。そのため、ソースコードを解析することができるソースコードサイズには上限がある。プログラムの検証対象ソースコードの解析から脆弱経路の検出を行う場合、特許文献１のように、検証対象ソースコードをすべて解析する必要があるが、検証対象ソースコードのソースコードサイズが大きいほど、必要となるメモリ量が大きくなり、かつ、解析時間が非常に多くかかってしまう。このため、実際利用されているような比較的大規模なソースコードに対しては、上記の検証対象ソースコード解析による脆弱経路の検出手法を適用することが難しい。
【００１０】
また、一般には、近年のプログラムの大規模化、モジュール化によって、対象となるプログラムの一部が外部からバイナリ形式で与えられるようになったため、その一部のプログラムを外部から入手できず、対象となるプログラム全体のソースコードを得られないことがある。もし、解析する検証対象ソースコードが部分的に手に入らなかった場合、従来技術ではその手に入らない不足部分を無視する、若しくは、その不足部分を何らかの仮定のもとに近似することで解析が行われる。しかし、このような方法では、プログラムの検証対象ソースコードの解析精度が低下してしまう。
【００１１】
上記事情を鑑みて、本発明の目的は、検証対象ソースコードを解析する際に必要となるメモリ量を縮小し、低コストでの解析を実現することと、ソースコードの不足部分を含む検証対象ソースコードの解析における解析精度を向上させることにある。
【課題を解決するための手段】
【００１２】
上記目的を達成するため、本発明は、検証対象ソースコードのデータフローに着目し、簡易化する工程を備えることにより、検証対象ソースコードを縮小する手段を設けている。また、本発明は、検証対象ソースコードが一部または全部存在せず、不足の状態にある場合において、その検証対象コードをデータフローに着目して簡易的に記述したファイルを追加する工程を備えることにより、不足した検証対象ソースコードを補う手段を設けている。詳細は後記する。
【発明の効果】
【００１３】
本発明によれば、検証対象ソースコードを解析する際に必要となるメモリ量を縮小し、低コストでの解析を実現することができる。また、ソースコードの不足部分を含む検証対象ソースコードの解析における解析精度を向上させることができる。
【発明を実施するための最良の形態】
【００１４】
以下、本発明を実施するための最良の形態（以下、「実施の形態」という。）について説明する。説明する際には、本明細書と同時に提出する図面を適宜参照する。
【００１５】
１．実施の形態１
実施の形態１は、プログラムの特性としての脆弱性を解析する検証対象ソースコードのデータフローに着目し、そのデータフローのうち、当該検証対象ソースコードにおいて定められる所定範囲において、データが外部から入力し、外部へ出力される箇所を定めたデータフローとなる部分とそうでない他のデータフローを区別し、当該他のデータフローを削除して、検証対象ソースコードを簡易化するものである。なお、本実施形態において、説明するソースコードは、Java（登録商標）言語で記述するものとする。また、前記所定範囲とは例えば、Java（登録商標）言語におけるクラスファイルのことを指す。以下、実施の形態１について詳細に説明する。
【００１６】
１．１．コンピュータの構成
図１は、本実施形態のプログラム検証方法を実行するコンピュータ（プログラム検証装置）の構成の一例を図示したものである。
コンピュータ１００は、制御手段として機能するプロセッサ１０１と、記憶手段のうち外部記憶装置として機能するメモリ１０２と、プロセッサ１０１が直接読み込む主記憶装置として機能する記憶装置１０３と、本実施形態のプログラム検証方法の実行を指示する入力手段として機能するキーボード１１０および表示手段として機能するディスプレイ１０９から構成されている。
【００１７】
メモリ１０２は、本発明の特徴である検出ソフトウェアプログラム１０４と、本発明の特徴である簡易ソースコード１０５と、脆弱性データベース１０６および検証対象となる検証対象ソースコード１０７から構成されている。また、メモリ１０２は、脆弱性データベース１０６以外にも、後記する各種データベースを記憶する。
【００１８】
検出ソフトウェアプログラム１０４は、検証対象ソースコード１０７を解析し、解析結果１０８を得る。得られた解析結果１０８は、記憶装置１０３とディスプレイ１０９のいずれか、または両方に出力される。検出ソフトウェアプログラム１０４の実行はキーボード１１０により命令される。検出ソフトウェアプログラム１０４は、プロセッサ１０１が実行するが、このプロセッサ１０１は、集積回路化するなどしてハードウェアで実現することもできる。
【００１９】
簡易ソースコード１０５は、後記する簡易化プログラムにより、検証対象ソースコード１０７から不要部分を削除したソースコードである。また、脆弱性データベース１０６は、脆弱性の発生点および使用点を登録したデータベースである。詳細は、後記する。
【００２０】
以下、説明を簡単にするため、検出ソフトウェアプログラム１０４をプロセッサ１０１が実行することで実現される処理部を、処理の主体として説明する。
【００２１】
１．２．検出ソフトウェアプログラムの概要
図２は、検出ソフトウェアプログラム１０４においてなされるデータの入出力の概要を、ブロック図として図示したものである。検出ソフトウェアプログラム１０４は、検証対象となる検証対象ソースコード１０７を入力して解析し、脆弱性データベース１０６に登録されている発生点および使用点を読み出し、それらを基に検証対象ソースコード１０７（検証対象ソースコード１０７を簡略化した簡易ソースコード１０５）に存在する脆弱経路を検出し、検出した脆弱経路を解析結果１０８として、記憶装置１０３若しくはディスプレイ１０９のいずれか、または両方に出力する。
【００２２】
１．３．プログラム検証方法の処理手順
次に、本実施形態で実行されるプログラム検証方法の処理手順について詳細に説明する。
【００２３】
図３は、検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。検出ソフトウェアプログラム１０４は、簡易化プログラム３０１、モデル化プログラム３０２、データフロー解析プログラム３０４、および脆弱性検出プログラム３０６から構成されている。
【００２４】
検出ソフトウェアプログラム１０４は検証対象ソースコード１０７を入力し、簡易化プログラム３０１において、その不要部分を削除して簡易ソースコード１０５を出力する工程がなされる。削除対象となる不要部分の認定については後記する。
【００２５】
次に、モデル化プログラム３０２において、簡易ソースコード１０５をモデル化する工程がなされる。簡易ソースコード１０５をモデル化したデータは、メモリ１０２が有するモデルデータベース３０３に登録される。モデル化する方法は特許文献１のものを用いることにする。
【００２６】
次に、データフロー解析プログラム３０４において、モデルデータベース３０３に登録されたデータに基づいて、モデル化した簡易ソースコード１０５についてデータフロー解析を行う工程がなされる。この解析により、モデル化した簡易ソースコード１０５におけるデータの流れ（経路）が定められる。この定められたデータの流れは後記するデータパスとして、メモリ１０２が有するデータパスデータベース３０５に登録される。
【００２７】
最後に、脆弱性検出プログラム３０６において、データパスデータベース３０５に登録されたデータパスを、脆弱性データベース１０６に登録された脆弱性の発生点及び使用点と照合して、脆弱性を生じさせる脆弱経路を検出する工程がなされる。検出した結果は、解析結果１０８として出力する。
【００２８】
なお、図３以下に示すブロック図およびフローチャートにおいて、実線矢印で示したものを制御のフローとし、破線矢印で示したものをデータのフローとする。図３のブロック図に基づいて、検出ソフトウェアプログラム１０４の各工程における動作の詳細を説明する。
【００２９】
１．３．１．簡易化プログラムにおける処理
簡易化プログラム３０１は、ソースコードのうちデータフローに着目して不要部分を削除し簡易化するプログラムである。検証対象ソースコード１０７について、データフローに必要となる部分（コード）のみを抽出し、抽出されなかったコードは不要部分であると認定し、その不要部分を削除することで検証対象ソースコード１０７の簡易化、つまり、ソースコードサイズの縮小化を実現する。
【００３０】
その詳細を図４のブロック図を参照しつつ説明する。図４は、簡易化プログラム３０１の処理手順の一例をブロック図として図示したものである。簡易化プログラム３０１は、構文解析プログラム４００、データフロー解析プログラム４０１、データフロー抽出プログラム４０３、および不要部分削除プログラム４０５から構成されている。
【００３１】
１．３．１．１．構文解析プログラム及びデータフロー解析プログラムにおける処理
まず、検証対象ソースコード１０７を構文解析プログラム４００により構文解析し、構文解析した検証対象コード１０７に対して、データフロー解析プログラム４０１によりデータフロー解析を行う。その解析結果として、あるデータフローを構成するエッジを取得する。エッジには、あるデータフローの開始点である開始エッジと、そのデータフローの終端点である終了エッジとがあり、開始エッジと終了エッジを関連付けたデータを「エッジデータ」と呼ぶ。例えば、検証対象ソースコード１０７として、図５に示すような、簡易化の対象となるJava（登録商標）言語で記述したソースコード５００を採りあげる場合、構文解析プログラム４００により構文解析し、データフロー解析プログラム４０１によりデータフロー解析したとき、その解析結果として図６に示すようなエッジ集合６００（エッジデータの集まり）を得ることができる。エッジ集合６００は、メモリ１０２が有するエッジデータベース４０２（図４参照）に登録される。
【００３２】
図６のエッジ集合６００は、numフィールド６０１、toフィールド６０２、to＿lineフィールド６０３、fromフィールド６０４、from＿lineフィールド６０５、及びclassフィールド６０６の６つのフィールドからなるエントリで構成されている。
【００３３】
Numフィールド６０１はデータフローを構成するエッジの番号を登録する。ここで、データフローを構成するエッジとは、fromフィールド６０４に登録されるノード（具体的には、図５のソースコード５００において記述されているコードであって、代入する変数を定めた開始エッジとして定められるもの）からtoフィールド６０２に登録されるノード（具体的には、図５のソースコード５００において記述されているコードであって、代入される変数を定めた終了エッジとして定められるもの）への方向付きエッジである。図５のソースコード５００においては６つのエッジが定められ、Numフィールド６０１において、順次番号が付される。
【００３４】
to＿lineフィールド６０３、from＿lineフィールド６０５は、それぞれtoフィールド６０２、fromフィールド６０４に登録されるノードが存在する行番号であり、具体的には、図５のソースコード５００においてコードの左側に記した番号を指す。
【００３５】
classフィールド６０６は、toフィールド６０２に登録されるノードとfromフィールド６０４に登録されるノードのどちらか、もしくは両方が存在するクラス名である。図５のソースコード５００は「Sample」というクラスファイルにおいて実行される命令が記述されるコードであるので、エッジ集合６００を構成する各エッジのclassフィールド６０６には、「Sample」と登録される。
【００３６】
toフィールド６０２またはfromフィールド６０４の値は、次のようにして定める。まず、その値がローカル変数の場合、その変数名を「.（ドット）」の前に属するメソッド名で表す。例えば、図６においては、「getUserValue」、「true」等のメソッド名で表し、toフィールド６０２およびfromフィールド６０４に登録される。また、その値がインスタンス変数の場合、メソッド名の変わりに「instance」とし、手続き呼び出しの場合、「.（ドット）」の後にそのメソッド名を付けて表す。例えば、図６においては、「val」、「flag」等がインスタンス変数であり、「instance.val」、「instance.flag」等として表し、toフィールド６０２およびfromフィールド６０４に登録される。
【００３７】
また、図６において、toフィールド６０２およびfromフィールド６０４には、「out＿of＿class」という値が登録される場合がある。この「out＿of＿class」とは、toフィールド６０２およびfromフィールド６０４それぞれに登録され、互いに対になるノードが存在するクラス（図６でいえば「Sample」というクラスに相当）とは異なるクラスにノードが存在することを意味する。このため、out＿of＿classの行番号は０とし、そのときのclassフィールドはout＿of＿classでは無い方のノードが属するクラス名とする。
【００３８】
例えば、図６において、Numフィールド６０１におけるエッジの番号が「２」のレコードの場合、toフィールド６０２に登録されるノード「getUserValue」（ソースコード５００（図５）の５行目の「getUserValue」に相当）に代入される値は、「Sample」というクラスとは異なるクラス（つまり、外部）から入力されるため、fromフィールド６０４には「out＿of＿class」を登録し、from＿lineフィールド６０５には「０」という行番号を登録し、classフィールド６０６には、ノード「getUserValue」が属するクラスである「Sample」が登録される。また、Numフィールド６０１におけるエッジの番号が「６」のレコードの場合、fromフィールド６０４に登録されるノード「instance.val」（ソースコード５００（図５）の１０行目の「val」に相当）に代入された値から出力される値は、「Sample」というクラスとは異なるクラス（つまり、外部）へ出力されるため、toフィールド６０２には「out＿of＿class」を登録し、to＿lineフィールド６０３には「０」という行番号を登録し、classフィールド６０６には、ノード「instance.val」が属するクラスである「Sample」が登録される。
【００３９】
このエッジ集合６００を基に、データフロー抽出プログラム４０３は、（「Sample」という）クラスの外部からの入力からクラスの外部への出力まで繋がったデータフローを抽出し、抽出したデータフローを、メモリ１０２が有するデータフローデータベース（以下、「ＤＦＤＢ」と呼ぶ。）４０４に追加する（図４参照）。図７を参照して、抽出したデータフローをＤＦＤＢ４０４に追加する処理について詳細に説明する。図７は、データフロー抽出プログラム４０３により実行される処理の一例をフローチャートとして図示したものである。
【００４０】
１．３．１．２．データフロー抽出プログラムにおける処理
図７の処理では、まず、処理７０１で処理を開始し、処理７０２において、図６で示したエッジ集合６００の中から、classフィールド６０６が同一のエッジ集合を変数Ｓに求め、判定処理７０３に制御を移す。
【００４１】
判定処理７０３では変数Ｓが空集合か否かを判定する。変数Ｓが空集合である場合（判定処理７０３でＹｅｓ）、処理すべきエッジ集合が存在しないため、制御を処理７０９に移し終了する。もしＳが空集合で無いなら（判定処理７０３でＮｏ）、制御を処理７０４に移す。
【００４２】
処理７０４では、変数Ｓのfromフィールド６０４が「out＿of＿class」となるエッジ集合を変数Ｃに求め、制御を処理７０５に移す。処理７０５では、まず、変数Ｒを空集合として定義し、制御を繰り返し処理７０６に移す。
【００４３】
繰り返し処理７０６は、変数Ｃに含まれるすべてのエッジに対し、各エッジを変数ｃに求め、処理７０７を繰り返す。処理７０７では、図８に示すサブルーチンgetPath()８０１を呼び出す。サブルーチンgetPath()８０１はエッジｃを開始点（開始エッジ）とするエッジ集合のうち、終了エッジのtoフィールド６０２が「out＿of＿class」となるようなエッジ集合を返す。このとき、サブルーチンgetPath()８０１の戻り値を変数Ｒに結合する。
【００４４】
繰り返し処理７０６が終了すると、制御を処理７０８に移す。処理７０８では、変数ＲをＤＦＤＢ４０４に追加し、制御を再び処理７０２に移す。この処理により、各クラスに対して各クラスの外部からの入力から外部への出力まで連結したエッジの集合が求まり、ＤＦＤＢ４０４に追加される。
【００４５】
図８は、図７のフローチャート内で利用したサブルーチンgetPath()８０１のフローチャートの一例を図示したものである。
【００４６】
図８の処理では、まず、処理８０１で処理を開始する。getPath()の第一引数ｎはエッジであり、第二引数pathはエッジ集合で、第三引数Ｘはエッジデータベース４０２（図４参照）のclassフィールドが等しいエッジ集合を表している。処理８０２では、局所変数Ｐを定義し、空集合で初期化し、制御を処理８０３に移す。処理８０３では、エッジ集合Ｘの内、fromフィールドがエッジｎのtoフィールドに等しいエッジ集合を変数Ｅに求め、制御を繰り返し処理８０４に移す。
【００４７】
繰り返し処理８０４は変数Ｅに含まれるすべてのエッジに対し、各エッジを変数ｅに求め、処理８０５〜８０７を繰り返す。判定処理８０５では、各エッジｅのtoフィールドの値が「out＿of＿class」であるか否かを判定する。もしエッジｅのtoフィールドの値が「out＿of＿class」であるなら（判定処理８０５でＹｅｓ）、処理８０７において、変数Ｐに対して第二引数であるエッジ集合pathを結合し、繰り返し処理８０５を続ける。もし、エッジeのtoフィールドの値が「out＿of＿class」でないなら（判定処理８０５でＮｏ）、処理８０６に進み、第二引数であるエッジ集合pathにエッジｅを追加し、サブルーチンgetPath()を再帰的に呼び出し、その戻り値を変数Ｐに結合する。すべての繰り返し処理８０４が終了すると、制御を処理８０８に移す。処理８０８は、求めた変数Ｐからなるエッジ集合を返却し、処理を終了する。
【００４８】
以上のデータフロー抽出プログラム４０３（図４）の処理により、エッジデータベース４０２（図４参照）に登録されたエッジとして定められたデータフローのうち、クラスの外部から入力されたデータがクラスの内部を経由し、クラスの外部へと出力されるデータフローのみをＤＦＤＢ４０４（図４）に追加できる。図９は、データフロー抽出プログラム４０３（図４）の処理により得られたデータフローをソースコード９００上にマッピングしたものを図示したものである。ソースコード９００は、ソースコード５００（図５参照）と同一のソースコードであるが、データフローをマッピングした点で異なる。なお、マッピングした様子（つまり、矢印及び、その矢印の番号２、３、５、６）を鮮明に見せるためにソースコード５００に対してコードを一部省略してある。図９内の矢印の番号２、３、５、６は、図６のエッジ番号（つまり、numフィールド６０１のエッジ番号）に一致する。このようにマッピングされたデータフローをエッジデータとしてＤＦＤＢ４０４（図４）に登録する。図１０は、ＤＦＤＢ４０４に登録される、図９においてマッピングしたデータフローに相当するエッジデータ１０００のデータ構造を図示したものである。
【００４９】
図１０のエッジデータ１０００は、numフィールド１００１、toフィールド１００２、to＿lineフィールド１００３、fromフィールド１００４、from＿lineフィールド１００５、及びclassフィールド１００６の６つのフィールドからなるエントリで構成されており、各フィールドは、図６に示したnumフィールド６０１、toフィールド６０２、to＿lineフィールド６０３、fromフィールド６０４、from＿lineフィールド６０５、及びclassフィールド６０６の６つの各フィールドと同一の性質を有する。ＤＦＤＢ４０４に登録されたエッジデータ１０００を、エッジデータベース４０２に登録されたエッジ集合６００（図６参照）と比較すると、numフィールド６０１のエッジ番号２、３、５、６のエッジがデータフロー抽出プログラム４０３により抽出された様子が窺える。
【００５０】
１．３．１．３．不要部分削除プログラムにおける処理
次に、上記で構成したＤＦＤＢ４０４（図１０）を基に、検証対象ソースコード１０７から不要部分を削除する、不要部分削除プログラム４０５の動作の詳細を説明する。図１１は、不要部分削除プログラム４０５の処理の一例をフローチャートとして図示したものである。
【００５１】
図１１の処理では、まず、処理１１０１で処理を開始し、処理１１０２において、検証対象ソースコード１０７の１クラス分を読み込み、読み込んだクラスを変数Ｆに格納し、検証ソースコード１０７に含まれるクラスのクラス名を変数Ｃに格納し、変数ｎを定義し、０で初期化し、制御を処理１１０３に移す。処理１１０３では変数Ｆからソースコードを１行読み込み、読み込んだソースコードの１行を変数ｌに格納し、変数ｎに１を足す。この変数ｎは、変数Ｆにおける変数ｌの行番号に一致する。制御を判定処理１１０４へ移す。
【００５２】
判定処理１１０４では、変数Ｃおよび変数ｎがそれぞれＤＦＤＢ４０４のclassフィールド、to＿lineフィールド（または、from＿lineフィールド）に存在するか否かを確認する。ここで、ＤＦＤＢ４０４中のエントリは<num,to,to＿line,from,from＿line,class>の６つの組から構成されるものとする。なお、変数ｎは、ソースコードの行番号を表す変数であるので、前記エントリの３番目の引数「to＿line」及び５番目の引数「from＿line」に格納される値である。また、変数Ｃは、ソースコードの含まれるクラスのクラス名を表す変数であるので、前記エントリの６番目の引数「class」に格納される値である。変数Ｃおよび変数ｎがＤＦＤＢ４０４に存在する場合（判定処理１１０４でＹｅｓ）、制御を判定処理１１０６に移す。
【００５３】
判定処理１１０６では、変数ｌが変数Ｆの最終行であるか否かを確認する。変数ｌが変数Ｆの最終行で無い場合（判定処理１１０６でＮｏ）、制御を再び処理１１０３に移す。変数ｌが変数Ｆの最終行であった場合（判定処理１１０６でＹｅｓ）、制御を判定処理１１０７に移す。
【００５４】
判定処理１１０７では、変数Ｆが検証対象ソースコード１０７の最後のクラスであるか否かを確認する。変数Ｆが最後のクラスでなかった場合（処理１１０７でＮｏ）、制御を再び処理１１０２へ移す。変数Ｆが最後のクラスであった場合（処理１１０７でＹｅｓ）、検証対象ソースコード１０７のうち処理すべきコードが存在しないため、制御を処理１１０８に移し、処理を終了する。
【００５５】
判定処理１１０４で変数Ｃおよび変数ｎに対応するエッジがＤＦＤＢ４０４に存在しない場合（判定処理１１０４でＮｏ）、制御を処理１１０５に移す。対応するエッジが存在しない場合、その行はデータフロー解析には不要であるので、処理１１０５において、変数Ｆのクラスに存在する番号ｎに対応する行を不要部分として削除し、制御を判定処理１１０６へ移す。このフローチャートにより、検証対象ソースコード１０７から、不要部分を削除することができ、簡易化された簡易ソースコード１０５（図３参照）に変形することができる。
【００５６】
図１２は、検証対象ソースコード１０７の一例である図５に示すソースコード５００から不要部分を削除することにより簡易化されたソースコード１２００を図示したものである。ソースコード５００（図５）とソースコード１２００（図１２）とを比較すると、ソースコード５００（図５）のうち、４行目の「count=1;」というコード、及び６行目の「flag=true;」というコードが（ＤＦＤＢ４０４（図１０参照）にエッジデータ１０００として登録されなかったため）不要部分であるとして削除され、２行分削除して簡易化されたソースコード１２００（図１２）が生成される。
以上で、簡易化プログラム３０１における処理の説明を終了する。簡易化プログラム３０１の処理の後にはモデル化プログラム３０２（図３参照）の処理が行われる。
【００５７】
１．３．２．モデル化プログラムにおける処理
次に、モデル化プログラム３０２の処理動作について説明する。
モデル化プログラム３０２は、プログラムの検証として、その特性の一つである脆弱性を検出するために、ソースコードをモデル化するプログラムである。モデル化においては、ソースコードの構文を解析し、ソースコード内の各変数、式および手続き呼び出しに対し、あらかじめ指定された特徴の明細を記述したモデルを作成する。図１３および図１４は、図１２の簡易化されたソースコードをモデル化した結果である。
【００５８】
図１３は、図１２のソースコード１２００のsetStringメソッドの内容「val = getUserValue();」（４行目）をモデル化した結果の一例を図示したものである。図１３に示したように、「val = getUserValue();」といった、変数を代入するプログラムコードをモデル化するにあたり、指定された特徴として、述語（predicate）１３０１を指定し、その述語を「assign」に置き換えることにより明細を記述する。また、その特徴として、コードの左辺値（left value）１３０２を指定して「instance.val」と記述し、コードの右辺値（right value）１３０３を指定して「getUserValue」と記述し、行番号（line）１３０４を指定して４行目にあるので「４」と記述し、メソッド名（method）１３０５を指定して「setString」と記述し、及びクラス名（class）１３０６を指定して「Sample」と記述する。このように記述したモデルは、「predicate」１３０１、「left value」１３０２、「right value」１３０３、「line」１３０４、「method」１３０５及び「class」１３０６をフィールドとしたモデルデータ１３００として、モデルデータベース３０３（図３参照）に登録される。
【００５９】
図１４は、図１２のソースコード１２００のgetStringメソッドの内容「return val;」（８行目）をモデル化した結果の一例を図示したものである。図１４に示したように、「return val;」といったプログラムコードをモデル化するにあたり、指定された特徴として、述語（predicate）１４０１を指定し、そのコードの述語「return」を「ret」という述語に置き換えることにより明細を記述する。また、その特徴として、そのコードの返却値（value）１４０２を指定して「instance.val」と記述し、行番号（line）１４０３を指定して８行目にあるので「８」と記述し、メソッド名（method）１４０４を指定して「getString」と記述し、クラス名（class）１４０５を指定して「Sample」と記述する。このように記述したモデルは、「predicate」１４０１、「value」１４０２、「line」１４０３、「method」１４０４及び「class」１４０５をフィールドとしたモデルデータ１４００として、モデルデータベース３０３（図３参照）に登録される。
【００６０】
これらの例のように、モデル化プログラム３０２では、データフロー解析に必要となるソースコードをすべてモデル化する工程が実行される。また、モデル化するために必要な指定された特徴、及びこの工程で生成されたすべてのモデルはモデルデータとしてモデルデータベース３０３（図３参照）に登録される。モデル化に用いる明細の特徴は、例えば、キーボード１１０等の入力手段により指定される。なお、データフロー解析に求める精度やプログラムの設計の都合上等により、ソースコードのすべてをモデル化しても良いし、一部だけモデル化しても良い。
【００６１】
１．３．３．データフロー解析プログラムにおける処理
次に、データフロー解析プログラム３０４の処理動作について説明する。
この工程のデータフロー解析プログラム３０４では、図１３及び図１４に図示したような、モデルデータベース３０３に登録されたすべてのモデルに対し、データフロー解析プログラム４０１と同様のデータフロー解析を実行する。なお、前記モデルは既に不要部分を削除して簡易化されたものであるので、データフロー抽出プログラム４０３により実行される処理（図７及び図８参照）は不要である。そのため、データフロー解析プログラム３０４による解析の結果、図１０で示すＤＦＤＢ４０４に登録されるエッジデータ１０００と同様のエッジデータ（つまり、numフィールド、toフィールド、to＿lineフィールド、fromフィールド、from＿lineフィールド、及びclassフィールドの６つのフィールドからなるエントリで構成されたエッジデータ）が求められる。そして、当該エッジデータの一のクラスにおいて、toフィールドの値とfromフィールドの値が等しく、その等しい値を以ってエッジデータを連結したときに生成されるエッジの集合を「データパス」と定義する。データパスが定義されたエッジの集合は、データパスデータベース３０５（図３）に登録される。
【００６２】
図１５及び図１６を参照して、データパスについて具体的に説明する。図１５は、簡易化プログラム３０１（図３）による簡易化の処理、及びモデル化プログラム３０２（図３）によるモデル化の処理がなされた解析対象ソースコード１５００の一例を図示したものである。図１６は、解析対象ソースコード１５００に対してデータパスをマッピングした解析対象ソースコード１６００の一例を図示したものである。
【００６３】
この解析対象プログラムコード１５００（又は１６００）内に含まれるgetUserValueメソッド（６行目）およびgetTimeメソッド（５行目）が開始エッジであるとし、writeValue（８行目と９行目の２つ）が終了エッジであるとした場合、データフロー解析プログラム３０４により、図１６に図示した、第１のデータパス（１６０１→１６０２→１６０３→１６０４）と、第２のデータパス（１６０５→１６０６→１６０７→１６０８）が抽出される。これら第１のデータパス及び第２のデータパスを表す一連のエッジの集合がデータパスデータベース３０５（図３）に登録される。
【００６４】
１．３．４．脆弱性検出プログラムにおける処理
次に、脆弱性検出プログラム３０６の処理動作について説明する。
脆弱性検出プログラム３０６では、データフロー解析プログラム３０４により登録されたデータパスデータベース３０５と、メモリ１０２（図１）に記憶され、予め用意していた脆弱性データベース１０６を参照し、データパスに対して脆弱経路の検出の処理が実行される。
【００６５】
図１７は、脆弱性データベース１０６に登録されるデータ構造の一例を図示したものである。脆弱性データベース１０６には、１列目に「predicate」フィールド１７０１、２列目に「method」フィールド１７０２及び３列目に「class」フィールド１７０３から構成された脆弱性データが登録されている。脆弱性データとは、クラスごとに脆弱性の発生点とその発生点となるメソッドおよび脆弱性の使用点とその使用点となるメソッドを関連付けたデータである。
【００６６】
「predicate」フィールド１７０１には、ソースコードのある行に記述されたメソッドが発生点もしくは使用点であるかを表す述語が登録される。図１７の例では、「from」が発生点であり、「to」が使用点である。
「method」フィールド１７０２には、ソースコードに用いられるメソッド名が登録される。図１７の例では、「getUserValue」が発生点を生じさせるメソッドであり、「writeValue」が使用点を生じさせるメソッドである。
「class」フィールド１７０３には、「method」フィールド１７０２に登録されるメソッドが属するクラスが登録される。図１７の例では、「Data」が、メソッド「getUserValue」及び「writeValue」が属するクラスである。
【００６７】
脆弱性データベース１０６を用いて、データパスデータベース３０５に登録されているデータパスの経路上に発生点と使用点が含まれているかを検査し、含まれている場合、そのパスを脆弱経路として検出し、解析結果１０８（図３）として出力する。図１７の脆弱性データベース１０６を参照すると、getUserValue()メソッドが脆弱性の発生点であり、writeValue()メソッドが脆弱性の使用点となっており、図１６の解析対象ソースコード１６００と照合する。すると、第１のデータパス（１６０１→１６０２→１６０３→１６０４）において、発生点「getUserValue()」１６０１が脆弱性データベース１０６の「method」フィールド１７０２に登録された発生点「getUserValue」と一致し、かつ、使用点「WriteValue」１６０４が脆弱性データベース１０６の「method」フィールド１７０２に登録された使用点「writeValue」と一致するので、第１のデータパスは脆弱経路として検出され、解析結果１０８に出力される。一方、第２のデータパス（１６０５→１６０６→１６０７→１６０８）において、使用点「WriteValue(）」１６０８が脆弱性データベース１０６の「method」フィールド１７０２に登録された使用点「writeValue」と一致するが、発生点「getTime()」１６０５が脆弱性データベース１０６の「method」フィールド１７０２に登録された発生点「getUserValue(）」と一致しないため、第２のデータパスは脆弱性を発生させず、脆弱経路として検出されない。
このようにして、検証対象ソースコード１０７におけるプログラムの検証を終了する。
【００６８】
１．４．実施の形態１のまとめ
実施の形態１により、以下の効果を奏する。すなわち、本実施形態のプログラム検証方法は、検証対象コードの脆弱経路を検出するために、検証対象コードを、あらかじめ指定された特徴の明細を記述したモデルを作成する工程、モデル化された検証対象ソースコードを基にしてデータフロー解析を行う工程、及びデータフロー解析の結果として出力したデータパスと脆弱性データベースとを照合することにより、解析したデータパスのうち脆弱経路を検出する工程を含むが、検証対象ソースコードのデータフローに着目し、これらの工程を実行する前に、着目したデータフローを簡易化する工程を備えることにより、検証対象ソースコードを縮小化することができる。検証対象ソースコードを縮小化した簡易ソースコードに置き換えることにより、脆弱経路の検出に影響を与えることなく、プログラム解析の際に必要となるメモリ量が低減され、解析対象とするソースコードサイズを拡大することが可能となる。また、検証対象ソースコードの簡易化により、解析時間を短縮することができる。
【００６９】
２．実施の形態２
上記実施の形態１では、すべての検証対象ソースコードを簡易化しているが、検証対象ソースコードのすべてがコンピュータ１００に備えられているとは限らない。近年のプログラムの大規模化、モジュール化に伴い、一般に外部ライブラリを利用したプログラムが増加しているためである。そこで、コンピュータ１００の外部であらかじめ、ライブラリなどの一部のソースコードのみ簡易化し、モデル化を行い、モデルファイルを予め作成しておき、脆弱性検出の際に、そのモデルファイルをデータフロー解析の工程に入力する形態をとることができる。図１８を参照して、その形態に関する説明をする。
【００７０】
２．１．実施の形態２の構成
図１８は、本実施形態の検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。基本的には図３に図示した処理手順と同様であるので、相違する点についてのみ説明する。
【００７１】
検出ソフトウェアプログラム１０４には、簡易化プログラム３０１（図３参照）が備えられておらず、後記するように外部にて簡易化する。従って、メモリ１０２に記憶されている検証対象ソースコード１０７は、ソースコードとして一部不足しているが元々簡易化することのないものを用いることにし、モデル化プログラム３０２によるモデル化の処理が行われる。
【００７２】
コンピュータ１００の外部には、外部検証対象ソースコード１８００、外部簡易化プログラム１８０１、外部簡易ソースコード１８０２、及び外部モデル化プログラム１８０３を備えたコンピュータ（図示せず）が存在し、コンピュータ１００は、例えば、インターネット等のネットワークを介して外部モデル化プログラム１８０３から所定のデータを入力できるように設定されている。外部検証対象ソースコード１８００は、検証対象ソースコード１０７と同等の性質を有するものであり、検証対象ソースコード１０７の不足部分を補完するソースコードを有している。外部簡易化プログラム１８０１は簡易化プログラム３０１（図３参照）と同等の機能を有するものである。外部簡易ソースコード１８０３は、外部検証対象ソースコード１８００を外部簡易化プログラム１８０１により簡易化されたプログラムである。外部モデル化プログラム１８０３はモデル化プログラム３０２（図３参照）と同等の機能を有しており、外部簡易ソースコード１８０２をモデル化し、モデル化したデータをデータフロー解析３０４及びモデルデータベース３０３に出力する。この出力は、コンピュータ１００において、キーボード１１０から、脆弱性検出の開始の指示が入力された場合に行われる。
【００７３】
データフロー解析プログラム３０４にモデル化されたソースコード（モデル化された検証対象ソースコード１０７及びモデル化された外部簡易ソースコード１８０２）が入力されてから解析結果１０８を出力するまでの処理は、実施の形態１と同様であるので説明を省略する。
【００７４】
２．２．実施の形態２のまとめ
実施の形態２により、以下の効果を奏する。すなわち、検証対象ソースコードが一部（または全部）存在しない場合において、ライブラリなどの外部に存在する検証対象ソースコードに対し、データフローに着目し、簡易化、そして、モデル化したコードをプログラム検証装置として機能するコンピュータに追加する工程を備えるようにした。これにより、不足した検証対象ソースコードを補完し、その部分をなんらかの仮定のもとに近似する場合に比べ、解析精度の低下を防止でき、さらには、解析精度を向上させることができる。
また、既に外部で一部または全部の検証対象ソースコードを簡易化、モデル化しているので、脆弱性の検出の処理時間全体を短縮することができる。
【００７５】
３．実施の形態３
上記実施の形態２では、検出対象ソフトウェアのソースコードの一部が不足している場合、図１８のように簡易的に記述した簡易ソースコードを外部入力として用いた。その簡易ソースコードは、プログラム検証装置としてのコンピュータに備えられている検証対象ソースコードとは異なる構文規則を用いることも可能である。実施の形態３ではその点について詳細に説明する。
【００７６】
３．１．実施の形態３の構成
図１９は、実施の形態３の検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。基本的には図１８に図示した処理手順と同様であるが、簡易ソースコード１９０１、簡易モデル化プログラム１９０２、簡易モデルデータベース１９０３、モデル変換データベース１９０４及びモデル変換プログラム１９０５が追加されている点で相違する。実施の形態３では、簡易モデルデータベース１９０３、モデル変換データベース１９０４及びモデル変換プログラム１９０５は、コンピュータ１００が備えているものとする。以下、その相違する点についてのみ説明する。
【００７７】
簡易ソースコード１９０１は、外部検証対象ソースコード１８００と同等の性質を有しているが、検証対象ソースコード１０７とは異なる構文規則で記述されており、不図示の簡易化プログラムにより簡易化したソースコードである。
【００７８】
簡易モデル化プログラム１９０２は、簡易ソースコード１９０１を読み込み、モデル化するプログラムであり、外部モデル化プログラム１８０３と同等の機能を有する。簡易ソースコード１９０１をモデル化したデータは簡易モデルデータベース１９０３に登録される。簡易ソースコード１９０１に対応するモデルには、Java（登録商標）言語をモデル化した際に現れる述語とは異なる述語が含まれる。
【００７９】
図２０は、簡易ソースコード１９０１の一例であるソースコード２０００を図示したものである。ソースコード２０００は、引数で与えられたchar配列の各要素を連結しStringとして出力するconvertC2Sメソッド（３行目）を簡易化して記述している。ソースコード２０００の４行目にJava（登録商標）言語にはない「<-」という演算子（以下、「受け渡し演算子」という。）がある。本来Java（登録商標）言語の言語仕様ではchar配列がStringと等価であるというデータフローが表現できず、データフローの解析を行うことができないが、この受け渡し演算子により、char配列からStringへのデータの受け渡しが記述できる。受け渡し演算子は、簡易ソースコード１９０１に既に記述されていても良いし、入力手段から簡易ソースコード１９０１を入力して異なる構文規則で記述されているとコンピュータ１００が判断した場合に追加しても良い。
【００８０】
図２１は、簡易モデル化プログラム１９０２により図２０に示した簡易ソースコード１９０１のうち、受け渡し演算子「<-」を含む４行目をモデル化した結果の一例を図示したものである。図２１に示したように、「String str <- c;」といった、非等価のデータを受け渡すコードをモデル化するにあたり、指定された特徴として、述語（predicate）２１０１を記述し、その述語を「exassign」に置き換えることにより明細を記述する。この１列目の述語２００１の「exassign」がJava（登録商標）言語をモデル化した際には、存在しなかった述語である。また、その特徴として、コードの左辺値（left value）２１０２を指定して「convertC2S.str」と記述し、コードの右辺値（right value）２１０３を指定して「convertC2S.c」と記述し、行番号（line）２１０４を指定して４行目にあるので「４」と記述し、メソッド名（method）２１０５を指定して「convertC2S」と記述し、及びクラス名（class）２１０６を指定して「Example」と記述する。このように記述したモデルは、「predicate」２１０１、「left value」２１０２、「right value」２１０３、「line」２１０４、「method」２１０５及び「class」２１０６をフィールドとしたモデルとして、簡易モデルデータベース１９０３（図１９参照）に登録される。
【００８１】
モデル変換プログラム１９０５は、簡易モデルデータベース１９０３に登録されたモデルをモデルデータベース３０３に合う形に変換し、モデルデータベース３０３に登録する。その処理動作を、図２２を参照して説明する。
【００８２】
３．２．モデル変換プログラムにおける処理
図２２は、モデル変換プログラム１９０５の処理の一例をフローチャートとして図示したものである。図２２の処理では、まず、処理２２０１で処理を開始し、制御を処理２２０２に移す。処理２２０２において、簡易モデルデータベース１９０３に登録されたモデルの集合であるモデル集合を変数Ｍに求め、制御を判定処理２２０３に移す。
【００８３】
判定処理２２０３において、変数Ｍが空集合か否かを確認する。変数Ｍが空集合であれば（判定処理２２０３でＹｅｓ）、処理すべきモデルが存在しないため制御を処理２２０８に移し終了する。変数Ｍが空集合で無い場合（判定処理２２０３でＮｏ）、制御を処理２２０４に移す。処理２２０４において、変数Ｍから１つのモデルを取り出し、取り出したモデルを変数ｍに格納する。一方、変数ｍの述語と対応付けされている述語をモデル変換データベース１９０４から読み込み、読み込んだ述語を変数pに格納する。その後、制御を判定処理２２０５に移す。
【００８４】
図２３は、モデル変換データベース１９０４に登録された述語の変換規則を定めたデータのデータ構造の一例を図示したものである。モデル変換データベース１９０４はフィールドとして、keyフィールド２３０１とvalueフィールド２３０２とを持つ。処理２２０４からの問合せに対し、keyフィールド２３０１の値とマッチングするか否かの処理を行い、マッチする場合、そのkeyフィールド２３０１の値（つまり、「exassign」）に対応するvalueフィールド２３０２の値（つまり、「assign」）を返す。その結果、変数ｐはvalueフィールド２３０２の値を持つ。もしマッチしない場合、何も返さず変数pは値を持たない。
【００８５】
判定処理２２０５において、変数pが値を持たない場合（判定処理２２０５でＮｏ）、制御を処理２２０７に移す。処理２２０７において、変数ｍはモデルの変換処理を必要としないため、変数ｍをそのままモデルデータベース３０３に追加し、再び、制御を処理２２０３に移す。判定処理２２０５において、変数ｐが値を持つ場合（判定処理２２０５でＹｅｓ）、制御を処理２２０６に移す。処理２２０６において、変数ｍの述語を変数ｐに置換したモデルをモデルデータベース３０３に追加し、制御を再び処理２２０３に移す。
【００８６】
結果的に、モデル集合Ｍのすべてのモデルｍについて、述語をそのままにしたものをモデルデータベース３０３に追加するかモデル変換データベース１９０４に登録されている述語に置き換えたものｐをモデルデータベース３０３に追加するかが決定されて制御を終了する。
【００８７】
例えば、ソースコード２０００（図２０参照）には受け渡し演算子「<-」があるので、ソースコード２０００についてモデル変換プログラム１９０５の処理を実行すれば、変数ｐは値を持つことになる（判定処理２２０５でＹｅｓ）。よって、述語を置き換えたモデルがモデルデータベース３０３に追加されることになり、既に説明したデータフロー解析等の処理が実行される。
【００８８】
３．３．実施の形態３のまとめ
実施の形態３により、以下の効果を奏する。すなわち、この処理により、Java（登録商標）言語では存在しないデータの受け渡しを表現する演算子「<-」を用いることで、元々実装のないソースコードに対するデータフローの定義を与えることが可能となり、さらに、検証対象ソースコード１０７とは異なる構文規則を用いたソースコード（簡易ソースコード１９０１）でも外部入力に用いることが可能となる。これにより、不足した検証対象ソースコードを補完し、その部分をなんらかの仮定のもとに近似する場合に比べ、実装の存在しないソースコードを簡易的に追加することができ、データフロー解析の解析精度を向上させることができる。
【００８９】
なお、上述した形態は本発明を実施するための最良のものであるが、かかる実施形式に限定する趣旨ではない。従って、本発明の要旨を変更しない範囲内においてその実施形式を種々変形することが可能である。
【００９０】
例えば、実施の形態３において、今回のモデル変換プログラム１９０５では、述語のみの変換であったが、これは述語のみの変換しか出来ないことを表しているわけではない。指定の変換規則をモデル変換データベース１９０４に登録しておくことで、述語以外の指定された特徴の明細の変換も可能である。
【００９１】
また、実施の形態２において、コンピュータ１００の外部において、外部簡易ソースコード１８０２（図１８参照）を外部モデル化プログラム１８０３によりモデル化した。しかし、外部簡易ソースコード１８０２をコンピュータ１００が有するモデル化プログラム３０２に入力して、コンピュータ１００の内部においてモデル化を実行するようにしても良い。
【００９２】
また、本実施の形態では、Java（登録商標）言語を対象ソースコードとした場合を例にとったが、特定のプログラミング言語に限らずに本発明を同様に利用できる。
【００９３】
さらに、以上の説明では、脆弱点および脆弱経路の検出を例にとり説明したが、脆弱性に係わらず、たとえば、プログラム信頼性向上を目的としたプログラム検証などといった、各種のプログラムの特性の検証に対しても応用可能である。この場合、脆弱性データベース１０６（図１参照）の代わりに、そのプログラムの特性について定めた特性情報を登録したデータベースを用いるようにする。
【００９４】
また、本実施の形態では、検証対象ソースコードのうち、データフロー抽出プログラム４０３（図４参照）により抽出されたデータフロー以外のデータフローに対応するソースコードの全部を削除することにようにした。しかし、データフローの解析精度におけるプログラムの設計上の都合等に応じて削除できるソースコードを一部のみとしても良い。
【図面の簡単な説明】
【００９５】
【図１】実施の形態１のプログラム検証方法を実行するコンピュータ（プログラム検証装置）の構成の一例を図示したものである。
【図２】検出ソフトウェアプログラム１０４においてなされるデータの入出力の概要を、ブロック図として図示したものである。
【図３】実施の形態１の検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。
【図４】簡易化プログラム３０１の処理手順の一例をブロック図として図示したものである。
【図５】簡易化の対象となるJava（登録商標）言語で記述したソースコード５００を図示したものである。
【図６】エッジデータベース４０２に登録されるエッジ集合６００のデータ構造を図示したものである。
【図７】データフロー抽出プログラム４０３により実行される処理の一例をフローチャートとして図示したものである。
【図８】図７のフローチャート内で利用したサブルーチンgetPath()８０１のフローチャートの一例を図示したものである。
【図９】データフロー抽出プログラム４０３（図４）の処理により得られたデータフローをソースコード９００上にマッピングしたものを図示したものである。
【図１０】ＤＦＤＢ４０４に登録される、図９においてマッピングしたデータフローに相当するエッジデータ１０００のデータ構造を図示したものである。
【図１１】不要部分削除プログラム４０５の処理の一例をフローチャートとして図示したものである。
【図１２】図５に示すソースコード５００から不要部分を削除することにより簡易化されたソースコード１２００を図示したものである。
【図１３】図１２のソースコード１２００のsetStringメソッドの内容「val = getUserValue();」（４行目）をモデル化した結果の一例を図示したものである。
【図１４】図１２のソースコード１２００のgetStringメソッドの内容「return val;」（８行目）をモデル化した結果の一例を図示したものである。
【図１５】簡易化プログラム３０１（図３）による簡易化の処理、及びモデル化プログラム３０２（図３）によるモデル化の処理がなされた解析対象ソースコード１５００の一例を図示したものである。
【図１６】解析対象ソースコード１５００に対してデータパスをマッピングした解析対象ソースコード１６００の一例を図示したものである。
【図１７】図１７は、脆弱性データベース１０６に登録されるデータ構造の一例を図示したものである。
【図１８】実施の形態２の検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。
【図１９】実施の形態３の検出ソフトウェアプログラム１０４の処理手順の一例をブロック図として図示したものである。
【図２０】図２０は、簡易ソースコード１９０１の一例であるソースコード２０００を図示したものである。
【図２１】簡易モデル化プログラム１９０２により図２０に示した簡易ソースコード１９０１のうち、受け渡し演算子「<-」を含む４行目をモデル化した結果の一例を図示したものである。
【図２２】モデル変換プログラム１９０５の処理の一例をフローチャートとして図示したものである。
【図２３】モデル変換データベース１９０４に登録された述語の変換規則を定めたデータのデータ構造の一例を図示したものである。
【符号の説明】
【００９６】
１０４  検出ソフトウェアプログラム
１０５  簡易ソースコード
１０６  脆弱性データベース
１０７  検証対象ソースコード
１０８  解析結果
３０１  簡易化プログラム
３０２  モデル化プログラム
３０３  モデルデータベース
３０４  データフロー解析プログラム
３０５  データパスデータベース
３０６  脆弱性検出プログラム
４００  構文解析プログラム
４０１  データフロー解析プログラム
４０２  エッジデータベース
４０３  データフロー抽出プログラム
４０４  データフローデータベース（ＤＦＤＢ）
４０５  不要部分削除プログラム
１８００  外部検証対象ソースコード
１８０１  外部簡易化プログラム
１８０２  外部簡易ソースコード
１８０３  外部モデル化プログラム
１９０１  簡易ソースコード
１９０２  簡易モデル化プログラム
１９０３  簡易モデルデータベース
１９０４  モデル変換データベース
１９０５  モデル変換プログラム
【図１】
2008299723.tif 000003
【図２】
2008299723.tif 000004
【図３】
2008299723.tif 000005
【図４】
2008299723.tif 000006
【図５】
2008299723.tif 000007
【図６】
2008299723.tif 000008
【図７】
2008299723.tif 000009
【図８】
2008299723.tif 000010
【図９】
2008299723.tif 000011
【図１０】
2008299723.tif 000012
【図１１】
2008299723.tif 000013
【図１２】
2008299723.tif 000014
【図１３】
2008299723.tif 000015
【図１４】
2008299723.tif 000016
【図１５】
2008299723.tif 000017
【図１６】
2008299723.tif 000018
【図１７】
2008299723.tif 000019
【図１８】
2008299723.tif 000020
【図１９】
2008299723.tif 000021
【図２０】
2008299723.tif 000022
【図２１】
2008299723.tif 000023
【図２２】
2008299723.tif 000024
【図２３】
2008299723.tif 000025