[関連技術]
(セキュリティ検査)
図1は,本実施の形態におけるセキュリティ検査に関連する技術を説明する図の一例である。図1においては,プロセスの流れを模式的に説明している。図1は,換言すれば,ソースコードのルートを模式的に示している。すなわち,図1では,ステップS101,S102で示される第1のルート(符号AR1参照),ステップS101,S103,S104で示される第2のルート,ステップS101,S103,S105で示される第3のルートを示している。
具体的に説明すれば,図1では,プロセスが,第1の判定(S101)を実行する。プロセスが,第1の判定(S101)において偽と判定した場合(S101/偽),プロセスがリソース「a」にアクセスする(S102)。一方,プロセスが,第1の判定(S101)において真と判定した場合(S101/真),第2の判定(S103)を実行する。
プロセスが,第2の判定(S103)において偽と判定した場合(S103/偽),プロセスがリソース「b」にアクセスする(S104)。一方,プロセスが,第2の判定(S103)において真と判定した場合(S103/真),プロセスがリソース「c」にアクセスする(S105)。
プロセスが,リソース「a」,「b」「c」にアクセスすると(S102,S104,S105),セキュリティモジュールは,セキュリティポリシファイルを参照し,このアクセスがセキュリティ面で許可されているか否かを判定する。
このソフトウェアをコンピュータで動作させて,セキュリティ検査を行う場合を想定する。このセキュリティ検査においては,前記したように,このソフトウェアの全処理が実行されるように,検査用データを作成するのは困難である。そのため,前記した第1のルートAR1が実行されるが,第2,第3のルートが実行されない検査用データが作成されたとする。そして,この検査用データに基づいて,セキュリティ検査が実行されたとする。
第2,3のルートが実行されない場合,すなわち,プロセスが,リソース「b」「c」にアクセスしない場合(S104,S105の不実行),セキュリティモジュールは,リソース「b」「c」に対するアクセスがセキュリティ面で許可されているか否か判定できない。その結果,セキュリティ検査における,いわゆる検査抜けが発生し,セキュリティ検査の精度が低下する。
特に,ソフトウェアの規模が大きくなれば,ソフトウェアのソースコードに含まれる条件判定命令,繰り返し命令,分岐命令,実行命令が多くなる。その結果,このソースコードの開始点から終了点までの論理的なルートのパター数が膨大となる。この論理的なルートは,前記した条件判定命令,繰り返し命令,分岐命令,実行命令が実行されるステップであり,図1の例では,第1〜第3のルートである。前記したパターン数が膨大になれば,ソフトウェアの開発過程で全ルートをコンピュータで実行するための,検査用データを作成することは困難である。
仮に,前記した検査用データを作成できたとする。しかし,全ルートをコンピュータで実行して,この全ルートを網羅するセキュリティ検査をソフトウェア開発工程の検査期間内に行うことはソフトウェアのリリーススケジュールの面から困難である。特に,セキュリティ検査により検出されたセキュリティポリシ違反を修正し,再検査を行うことを考慮すると,この全ルートを網羅するセキュリティ検査を行うことは困難である。
したがって,現状は,セキュリティ検査が行われていないルートが存在する状態で,ソフトウェアが出荷されている。ここで,このセキュリティポリシに違反しているルートが実行されると,セキュリティポリシに違反しているため,セキュリティモジュールが,このソフトウェアのプロセスを強制終了することがある。
ここで,このソフトウェアの出荷後,顧客がこのソフトウェアを実行し,セキュリティポリシに違反しているルートが実行されるとする。その結果,このソフトウェアのプロセスが強制終了しシステムが停止し,不測の障害が発生することがある。
このように,実際にソフトウェアをコンピュータで実行させてセキュリティ検査を行った場合,セキュリティ検査を高精度に実行することが困難である。
そこで,以下に説明する第1,第2の実施の形態では,実際にソフトウェアを実行せずに,ソフトウェアのソースコードを対象にしてセキュリティ検査を実行する。なお,ソースコードとは,プログラミング言語(例えば,C言語)の言語仕様に沿ってソフトウェア開発者により記述されたコンピュータ(電子計算機,情報処理装置とも呼ぶ)に対する複数の指示である。また,ソースコードを記憶したファイルは,ソースファイル,ヘッダファイルとも呼ばれる。このファイルは,例えばテキスト形式のファイルである。
(ソースコード)
図2,図3を参照しソースコードについて説明する。以下で説明するソースコードは,C言語の仕様に沿って記述されている。
図2は,従来のソースコードの第1の例を説明する図である。図2のソースコードは,データ読み出し用のアプリケーションプログラミングインタフェース(API:Application Programming Interface)のソースコードである。以下,説明のため,ソースコードの行頭に"行番号:"の文字列を付す。
1行目のAPI"iread (int fd, char *buf, size_t size)"は,2行目の"{"と,10行目の"}"との間で示されたステップを実行するようにコンピュータに指示する。この"iread (int fd, char *buf, size_t size)"は,3つの引数を有する。第1の引数は,int型のファイルディスクリプタ"fd"である。第2の引数は,キャラ型ポインタの"*buf"である。ポインタ"buf"には,読み出されたデータを格納するバッファの先頭ポインタが設定される。第3の引数は,ユーザが予め定義したsize_t型の変数"size"である。変数"size"には,読み出すデータのバイト数が設定される。
3行目の" for (;;)"は,4行目の"{"と,9行目の"}"との間で示されたステップを繰り返し実行する命令文である。5行目の" ssize_t nread;"は,ユーザが予め定義したssize_t型の変数" nread "を定義する。
6行目の"read (fd, buf, size); "は,引数fdで識別される入力元(例えば,ファイルや,ソケット)から,バイト数"size"分のデータをポインタ"buf"で指定されたバッファに読み出すAPIである。そして,この"read (fd, buf, size)"は,6行目に示すように実際に読み出したデータのバイト数を変数" nread"に設定する。
7行目の条件文"if (! (nread < 0))"は,API"read"が読み出したデータのバイト数,すなわち変数"nread"に設定されたバイト数が0未満か判定する。API"iread"は,変数"nread"に設定されたバイト数が0未満でなければ,8行目の" return nread;"を実行してデータの読み出し処理を終了する。なお,"return nread;"は,API" iread "を呼び出したAPI(関数)に" nread "に設定された値を戻り値として渡すことを意味している。
図3は,従来のソースコードの第2の例を説明する図である。図3のソースコードは,データ書き込み用のAPIのソースコードである。
21行目のAPI" iwrite (int fd, char const *buf, size_t size)"は,22行目の"{"と,34行目の"}"との間で示されたステップを実行するようにコンピュータに指示する。この"iwrite (int fd, char const *buf, size_t size)"は,3つの引数を有する。第1の引数は,int型のファイルディスクリプタ"fd"である。第2の引数は,キャラ型ポインタの"*buf"である。ポインタ"buf"は,書き込むデータを格納するバッファの先頭ポインタが設定される。第3の引数は,ユーザが予め定義したsize_t型の変数"size"である。変数"size"には,書き込むデータのバイト数が設定される。
23行目の"size_t total_written = 0;"は,ユーザが予め定義した"size_t"型の変数"total_written"を定義し,この変数に0を設定するステップである。
24行目の"while (total_written < size)"は,条件(total_written < size)を満たす間,25行目の"{"と,32行目の"}"との間で示されたステップを繰り返し実行する命令文である。
26行目の"ssize_t nwritten;"は,ユーザが予め定義したssize_t型の変数" nwritten "を定義する。
27行目の" write (fd, buf + total_written, size - total_written) "は,引数fdで識別される出力先に,下記のメモリ領域に格納されているデータを書き込むAPIである。このメモリ領域は," buf + total_written "で示される先頭のアドレス(ポインタ)から" size - total_written "分加算した末尾のアドレスで指定されたメモリ領域である。この出力先は,例えば,ファイル,ソケット,他のプロセスを含む。
そして,この"write (fd, buf + total_written, size - total_written)"は,27行目に示すように実際に書き込んだデータのバイト数を変数" nwritten"に設定する。
28行目の条件文"if (nwritten < 0)"は,API" write "が書き込んだデータのバイト数,すなわち変数"nwritten"に設定されたバイト数が0未満か判定する。API" iwrite "は,変数" nwritten "に設定されたバイト数が0未満ならば,33行目のreturn total_written;を実行してデータの書き込み処理を終了する。
一方,変数"nread"に設定されたバイト数が0未満でないならば31行目の"total_written += nwritten;"を実行する。この"total_written += nwritten;"は,変数" total_written "と変数" nwritten "とを加算した値を,再度,変数" total_written "に設定するコードである。
さて,26行目から31行目のステップを実行して,24行目の"while (total_written < size)"における条件(total_written < size)を満たすと,API"iwrite"は,33行目の"return total_written; "を実行しデータの書き込み処理を終了する。なお," return total_written; "は,API" iwrite "を呼び出したAPIに" total_written "に設定された値を戻り値として渡すことを意味している。
[第1の実施の形態]
以下に説明する第1,第2の実施の形態における情報処理装置(判定装置)は,ソフトウェアのソースコードを対象にしてセキュリティ検査を実行する。ソースコードを対象にしたセキュリティ検査を行うために,ソフトウェア開発者は,リソースにアクセスするための専用のAPI(以下,専用APIと適宜記す)を利用してソースコードを作成する。この専用APIは,例えば,ソフトウェア開発者により予め作成されたAPIである。
(専用API)
図4,図5を参照して専用APIを含むソースコードについて説明する。図4は,専用APIを含むソースコードの第1の例を説明する図である。図4のソースコードは,引数で指定されたリソースにアクセスしてデータを読み出すAPIのソースコードである。 図4におけるソースコードは,図2のソースコードにおける1行目のAPI" iread (int fd, char *buf, size_t size)"を,41行目のAPI" iread (int fd, int resource, char *buf, size_t size)"に置き換えたソースコードである。
41行目のAPI" iread"は,4つの引数を有する。第1の引数は,int型のファイルディスクリプタ"fd"であり,図2のAPI" iread"の第1の引数と同じである。第2の引数は,int型のリソース種別"resource"である。なお,リソース種別については後記する。第3の引数であるキャラ型ポインタの" *buf"は,図2で説明したAPI" iread"の第2の引数である。第4の引数である,ユーザが予め定義したsize_t型の変数"size"は,図2で説明したAPI" iread"の第3の引数である。
そして,図4におけるソースコードは,図2のソースコードにおける6行目のAPI" read (fd, buf, size)"を,46行目の専用API" !selinux_read (ownpid, fd, resource, buf, size) "に置き換えたソースコードである。このAPIは,引数(リソース種別" resource ")で指定されたリソースにアクセスして,変数"size"で指定されたデータサイズ分のデータを読み出し,ポインタ"buf"で指定されたメモリ領域に格納する専用APIである。
46行目のAPI" !selinux_read (ownpid, fd, resource, buf, size) "は,5つの引数を有する。第1の引数は," ownpid "であり,プロセス識別子である。このプロセス識別子は,コンピュータが図4のソースコードを含むソースファイル群から作成されたソフトウェアを実行すると,このコンピュータで動作するオペレーティングシステムから割り振られるであろうプロセス識別子である。このプロセス識別子は,例えばオペレーティングシステムにセキュリティシステムとして例えばSELinux(Linuxは登録商標)が組み込まれている場合,SELinuxが規定するサブジェクトに相当する。SELinuxは,"Security-Enhanced Linux"の略語である。なお,引数"ownpid"は,API"iread"の引数(図示しない)であってもよく,または,広域変数(グローバル変数とも呼ぶ)であってもよい。
第2の引数は,ファイルディスクリプタ"fd"である。第3の引数は,リソース種別"resource"である。リソース種別は,SELinuxがセキュリティチェックの対象とするリソースの種別を示している。このリソースは,SELinuxが規定するオブジェクトに相当する。引数"resource"は,広域変数であってもよい。
第4の引数"buf"は,図2の6行目におけるAPI"read"の第2の引数"buf"と同じであり,第5の引数"size"は,図2の6行目におけるAPI"read"の第3の引数"size"と同じである。
本実施の形態における情報処理装置は,この専用APIにおけるリソースの種別を示す引数に設定される値を特定すれば,この専用APIを実行するプロセス(以下,プロセス「x」と記す)が,どのリソースにアクセスするか決定できる。ここで,プロセス「x」が,リソース「a」にアクセスするとする。なお,リソース「a」は,例えばシステムファイルである。
本実施の形態における情報処理装置は,プロセス「x」によるリソース「a」に対するアクセスの許可の有無を示す情報を含むセキュリティポリシ(図8参照)を参照して,プロセス「x」が,リソース「a」にアクセスする許可が有るか否かを判定する。情報処理装置は,プロセス「x」によるリソース「a」に対するアクセスの許可がないと判定した場合,その結果を例えば表示出力する。
図5は,専用APIを含むソースコードの第2の例を説明する図である。図5のソースコードは,データ書き込み用の専用APIのソースコードである。
図5におけるソースコードは,図3のソースコードにおける21行目のAPI" iwrite (int fd, char *buf, size_t size)"を,61行目のAPI" iwrite (int fd, int resource, char const *buf, size_t size) "に置き換えたソースコードである。
61行目のAPI" iwrite"は,4つの引数を有する。第1の引数は,int型のファイルディスクリプタ"fd"であり,図3のAPI" iwrite"の第1の引数と同じである。第2の引数は,int型のリソース種別"resource"である。第3の引数であるキャラ型ポインタの" *buf"は,図3で説明したAPI" iwrite"の第2の引数である。第4の引数である,ユーザが予め定義したsize_t型の変数"size"は,図3で説明したAPI" iwrite"の第3の引数である。
そして,図5におけるソースコードは,図3のソースコードにおける27行目のAPI" write (fd, buf + total_written, size - total_written)"を,67行目の専用API"!selinux_write (ownpid, fd, resource, buf + total_written, size - total_written)"に置き換えたソースコードである。このAPIが,変数" size - total_written "で指定されたデータサイズ分のデータをポインタ" buf + total_written "で指定されたメモリ領域から読み出し,引数で指定されたリソース(リソース種別" resource ")にアクセスして書き込む専用APIである。
67行目のAPI"!selinux_write (ownpid, fd, resource, buf + total_written, size - total_written)"第1の引数は," ownpid "であり,プロセス識別子である。なお,引数"ownpid"は,API"iwrite"の引数(図示しない)であってもよく,または,広域変数であってもよい。
第2の引数は,ファイルディスクリプタ"fd"である。第3の引数は,リソース種別"resource"である。
第4の引数" buf + total_written "は,図3の27行目におけるAPI"write"の第2の引数" buf + total_written "と同じであり,第5の引数"size"は,図3の27行目におけるAPI"write"の第3の引数" size - total_written "と同じである。
(ハードウェア構成)
図6は,本実施の形態における情報処理装置(判定装置)1のハードウェア構成を説明するブロック図の一例である。なお,情報処理装置(判定装置)1を情報処理装置1と適宜記す。
情報処理装置1は,バスBに接続された,CPU(処理部)11と,ストレージ(記憶部)12と,RAM13と,外部記憶媒体読み取り装置14とを有する。なお,CPUは,"Central Processing Unit"の略語である。以下,CPU(処理部)11をCPU11,ストレージ(記憶部)12をストレージ12と適宜記す。
さらに,情報処理装置1は,バスBに接続された,ネットワークインターフェイス15と,表示装置インターフェイス16と,入力装置インターフェイス17とを有する。
CPU11は,情報処理装置1の全体を制御する中央演算処理装置である。ストレージ12は,例えばハードディスクドライブ(HDD:Hard Disk Drive)や,ソリッドステートドライブ(SSD:Solid State Drive)などの大容量記憶装置である。ストレージ12は,図7で説明するセキュリティ検査に関連する各種情報,例えば,ソース・ヘッダファイルSHF,システムリソースアクセスAPIハンドラテーブルT1,プロセス-システムリソーステーブルT2,セキュリティポリシSPを記憶する。
RAM(Random Access Memory)13は,CPU11が実行する各ステップにおいて処理されたデータなどを一時的に記憶する。RAM13は,例えばDRAM(Dynamic Random Access Memory)などの半導体メモリである。
RAM13における,検査部100,コンパイラ200,OS300について説明する。検査部100は,セキュリティ検査を実行するソフトウェアである。コンパイラ200は,ソースコードを機械語などの中間言語によるオブジェクトコード(目的コード)に変換するソフトウェアである。なお,コンパイラ200は,オブジェクトコードをリンクして実行ファイルを作成する機能を有する。
OS300は,複数のソフトウェアが共通して利用する基本的機能を提供し,情報処理装置1全体を管理する。なお,この基本的機能とは,例えば,ストレージ12,RAM13,ネットワークインターフェイス15に対するアクセス機能や,表示装置3に対する画像出力,入力装置4からの入力などの入出力機能である。
ストレージ12は,検査部100,コンパイラ200,OS300の実行ファイル(プログラム)を記憶する。CPU11は,情報処理装置1の起動時に,ストレージ12からこの実行ファイルを読み出し,RAM13に展開し,検査部100,コンパイラ200,OS300としての機能を実現する。なお,これら実行ファイルを外部記憶媒体2に記憶してもよい。
外部記憶媒体読み取り装置14は,外部記憶媒体2に記憶されたデータを読み取る装置である。外部記憶媒体2は,例えば,CD-ROM(Compact Disc Read Only Memory),DVD(Digital Versatile Disc)などの可搬型記憶媒体や,USBメモリなどの可搬型の不揮発性メモリである。
ネットワークインターフェイス15は,例えばNIC(Network Interface Card)を有し,ネットワークNに対するインターフェイス機能を提供する。表示装置インターフェイス16は,表示装置3に表示用の画像データを出力するなど,表示装置3に対するインターフェイス機能を提供する。表示装置3は,液晶ディスプレイや有機EL(Electro Luminescence)ディスプレイである。入力装置インターフェイス17は,入力装置4からの操作用の信号を受信し,検査部100に入力する。入力装置4は,例えば,キーボードやマウスである。
(ソフトウェア構成)
図7は,図6に示した情報処理装置1のソフトウェア構成を説明するブロック図の一例である。検査部100は,管理部101と,検索部102と,検出部103と,判定部104と,通知部105とを有する。
管理部101は,セキュリティ検査の管理処理を実行し,例えば検索部102,検出部103,判定部104,通知部105の制御を行う。検索部102は,検査対象となるソフトウェアのソースファイルとヘッダファイルとを検索する。そして,検索部102は,検索したソースファイルとヘッダファイルに含まれる全ソースコードを抽出する。
検出部103は,リソースに対してアクセスするプログラム部品の名前を含む部品情報を参照し,部品情報に含まれるプログラム部品の名前を検索部102が抽出したソースコードから検出する。
プログラム部品は,ソースコードにおいて,コンピュータに対して何らかの機能を実行させるため,コンピュータに対する複数の指示が纏められた単位を意味する。プログラム部品は,例えば,図4,図5で説明した専用APIである。
プログラム部品は,例えば,関数,モジュール,ライブラリ,コンポーネント,APIとも呼ばれる。なお,ライブラリとは,汎用性の高い複数のソフトウェア(プログラム)を再利用可能な形で一纏まりしたものである。コンポーネントとは,ある機能を実現するために部品化されたソフトウェアである。APIとは,ソフトウェアコンポーネントが互いにやりとりするのに使用するインターフェイスの仕様である。
前記した部品情報は,例えば,図9のシステムリソースアクセスAPIハンドラテーブルT1である。
判定部104は,ソースコードに基づくソフトウェア(プログラムとも呼ぶ)からのアクセスを許可するリソースが規定されたセキュリティポリシ情報と,検出された名前のプログラム部品によりアクセスされるリソースとに基づいて,以下の判定を行う。すなわち,判定部104は,このソースコードに基づくプログラムがセキュリティポリシ情報に違反するか否かを判定する。このセキュリティポリシ情報は,例えば,図8のセキュリティポリシSPである。
通知部105は,判定部104が実行した判定の結果を通知する。
ストレージ12は,ソース・ヘッダファイルSHFと,システムリソースアクセスAPIハンドラテーブルT1と,プロセス-システムリソーステーブルT2と,セキュリティポリシSPとを記憶する。以下,ソース・ヘッダファイルSHFは,ソースファイルと,ヘッダファイルとを含む。 ソースファイルは,例えば,図4,図5で説明したソースコードを含む。
(セキュリティポリシ)
セキュリティポリシは,プロセスによるリソースに対するアクセスの許可の有無を示す情報を含む。すなわち,セキュリティポリシは,ソースコードに基づくソフトウェアからのアクセスを許可するリソースが規定された情報を含む。なお,情報処理システムのセキュリティ管理者が,予めこのセキュリティポリシを作成する。
図8は,セキュリティポリシを記憶したテーブルの一例である。セキュリティポリシSPは,プロセスがアクセスできるリソースの種別が記憶されたテーブルであり,いわゆるホワイトリスト形式のテーブルである。換言すれば,セキュリティポリシSPは,アクセスが許可されるリソースの種別とアクセスの種別とが対応付けて規定された情報である。
具体的に説明する。セキュリティポリシSPは,セキュリティコンテキスト欄と,アクセス許可欄とを有する。
セキュリティコンテキスト欄には,あるプロセスがあるリソースにアクセスすることが記憶される。例えば,符号P1に示すセキュリティコンテキスト欄には,プロセス「x」が,リソース「a」にアクセスすることが記憶されている。文字列"リソース"の後の「」内の文字により,リソースの種別を示す。
アクセス許可欄には,セキュリティコンテキスト欄に記憶されているアクセスについて許可する旨が記憶されている。アクセス許可欄には,アクセスについて許可する場合,"許可"が記憶され,さらに,許可されたアクセスの種別が"許可"の後の括弧()内の文字により示されている。
例えば,あるリソースについて読み取りが許可されている場合,セキュリティコンテキスト欄に"許可(read)"と記憶される。例えば,符号P1に示すアクセス許可欄には,プロセス「x」が,リソース「a」(リソースの種別は「」内の"a")にアクセスする場合,このアクセスについては,読み取り(read)が許可されることが記憶される。
さらに,あるリソースについて読み取りおよび書き込みが許可されている場合,セキュリティコンテキスト欄に"許可(read, write)"と記憶される。また,あるリソースについて書き込みが許可されている場合,セキュリティコンテキスト欄に"許可(write)"と記憶される。なお,以下のテーブルにおいて,"…"は,省略を意味している。
(APIテーブル)
図9は,APIテーブルの第1の例を説明した図である。システムリソースアクセスAPIハンドラテーブルT1は,専用APIの名前と,検出用APIの名前とを記憶したテーブルである。
この検出用APIは,専用APIによりアクセスされるリソースの種別とこのアクセスの種別を検出する。なお,検出用APIの名前は,ハンドラモジュールエントリ名とも呼ばれる。
専用API欄は,専用APIの名前を記憶する。なお,専用APIは,図4,図5で説明したように,リソースに対してアクセスするプログラム部品である。
図9において説明する,リソースに対してアクセスするプログラム部品(例えば,専用API)の名前は,アクセスの種別に関連付けられた名前である。例えば,"!selinux_read"は,図4で説明した専用APIの名前を示す。専用APIの名前"!selinux_read"の一部文字列"read"は,この名前がアクセスの種別"read"(読み取り)に関連付けられた名前であることを示す。
"!selinux_write"は,図5で説明した専用APIの名前を示す。専用APIの名前"!selinux_write"の一部文字列"write"は,この名前がアクセスの種別"write"(書き込み)に関連付けられた名前であることを示す。
検出用API欄は,専用API欄に記憶されている名前で特定される専用APIの実行によりアクセスするリソースの種別とこのアクセスの種別を検出する検出用APIの名前を記憶する。
例えば,"ent_selinux_read"は,専用API"!selinux_read"がアクセス("read")するリソースとこのアクセスの種別を検出するAPIである。
"ent_selinux_write"は,専用API"!selinux_write"がアクセス("write ")するリソースとこのアクセスの種別を検出するAPIである。
なお,"!selinux_execute"は,あるリソースを実行するための専用APIを示す。"!selinux_status"は,あるリソースの状態を取得するための専用APIを示す。"!selinux_getattr"は,あるリソースの属性を取得するための専用APIを示す。
(ソースコード)
図7の検査部100の機能を詳細に説明する前に,図4,図5で説明したAPIを呼び出すソースコードについて説明する。
図10は,図4で説明したAPI"iread",図5で説明したAPI"iwrite"を含むソースコードの一例である。なお,図10において,"…"は,説明を簡略化するためソースコードを省略していることを示している。
81行目の関数" AppX()"は,82行目の"{"と,92行目の"}"との間で示されたステップを実行するようにコンピュータに指示する。
なお,int型のファイルディスクリプタの変数fd1,fd2,fd3は,関数" AppX"の中ですでに定義されている。そして,関数" AppX"の実行において,これらの変数には所定の値が設定されている。
また,ユーザが予め定義したsize_t型の変数"size1","size2","size3"は,関数" AppX"の中ですでに定義されている。そして,関数" AppX"の実行において,これらの変数には所定の値が設定される。
また,関数" AppX"の実行開始時(例えば,行番号83の(省略)実行時)において,第1〜第3のメモリ領域が確保される。そして,第1〜第3のメモリ領域の先頭アドレスがCHAR型のポインタ"buf1","buf2","buf3"に設定されている。なお,第1〜第3のメモリ領域のサイズは,少なくとも変数"size1","size2","size3"に設定された各所定の値以上のバイトである。
また,ユーザが予め定義したsize_t型の変数"ret"は,関数" AppX"の中で既に定義されている。
関数"AppX"は,以下の4つの引数を指定して,84行目のAPI"iread"(図4参照)を実行する。この4つの引数とは,ファイルディスクリプタ"fd1",リソース種別" RESOURCE_a ",読み出しデータ格納領域のポインタ"buf1",読み出し指定変数"size1"である。
そして,関数"AppX"は,以下の4つの引数を指定して,86行目のAPI"iread"(図4参照)を実行する。この4つの引数とは,ファイルディスクリプタ"fd2",リソース種別" RESOURCE_b ",読み出しデータ格納領域のポインタ"buf2",読み出し指定変数"size2"である。
そして,関数"AppX"は,以下の4つの引数を指定して,88行目のAPI"iwrite"(図5参照)を実行する。この4つの引数とは,86行目のAPI"iread"(図4参照)と同じである。
そして,関数"AppX"は,以下の4つの引数を指定して,90行目のAPI"iread"(図4参照)を実行する。この4つの引数とは,ファイルディスクリプタ"fd3",リソース種別" RESOURCE_c ",読み出しデータ格納領域のポインタ"buf3",読み出し指定変数"size3"である。
ここで,リソース種別" RESOURCE_a "," RESOURCE_b "," RESOURCE_c "は,アクセス先のリソース種別を示す。例えば,"RESOURCE_a "," RESOURCE_b "," RESOURCE_c "は,それぞれ,アクセスのリソース種別が,リソース「a」,「b」,「c」であることを示す情報である。リソース種別を示す情報(前記例では"RESOURCE_a "など)は,例えば数値として予め定められストレージ12に記憶されている。このリソース「a」,「b」,「c」は,例えば,特定のファイル,特定のポート番号,特定のソケットなどを示す情報である。
(検査部100)
図4〜図11を参照して,第1の実施の形態における検査部100の機能を詳細に説明する。図7の管理部101は,開発者からの検査実行指示を入力装置4,入力装置インターフェイス17を介して,受信する(矢印201参照)。この検査実行指示は,検査対象となるソフトウェアのソースファイルとヘッダファイルを特定する情報を含む。以下,検査対象となるソフトウェアをソフトウェア「x」と適宜記す。
管理部101は,検索部102に検査の実行を指示する。ここで,ソース・ヘッダファイルSHFは,ソフトウェア「x」のソースファイルとヘッダファイルとを含む。
検索部102は,この検査実行指示に応答して,ソフトウェア「x」のソースファイルとヘッダファイルとをストレージ12のソース・ヘッダファイルSHFから検索する(矢印202参照)。ソフトウェア「x」のソースファイルは,例えば,図4,図5,図10で説明したソースコードを含むソースファイルである。
そして,検索部102は,検索したソースファイルとヘッダファイルに含まれる全ソースコードを抽出する。
以下,検索部102が検索した1つ以上のソースファイル,ヘッダファイルに含まれる全ソースコードをソースコード「x」と適宜記す。コンピュータがソフトウェア「x」を実行したときの,ソフトウェア「x」の実行単位をプロセス「x」と適宜記す。以下の説明におけるプロセス「x」は,ソフトウェア「x」と同義である。
ソースコード「x」の中には,プログラム部品(例えば,API)が含まれる。このAPIは,例えば,図4の" !selinux_read (ownpid, fd, resource, buf, size)",図5の" !selinux_write (ownpid, fd, resource, buf + total_written, size - total_written)"である。
このAPIは,引数としてアクセス先のリソースの種別("resource"参照)が入力され,入力された種別に応じたリソースに対して,このAPIの名前に関連付けられたアクセスの種別("read","write"参照)に応じたアクセスを行う。
検出部103は,図9のシステムリソースアクセスAPIハンドラテーブルT1(以下,APIハンドラテーブルT1と適宜記す)を読み出す。そして,検出部103は,ソースコード「x」の中から,ハンドラテーブルT1の専用API欄に記憶されている専用APIを検出する。図4,図5,図10の例では,検索部102は,専用API"!selinux_read","!selinux_write"を検索する。
そして,検出部103は,ソースコード「x」の専用APIがコンピュータ(例えば,情報処理装置1)で実行された場合に,この専用APIがアクセスするリソースの種別およびアクセスの種別を検出する(矢印203_1参照)。
検出部103は,検出した専用APIに対応する検出用API(ハンドラテーブルT1の検出用API欄参照)を実行し,この検出を行う。検出用APIは,専用APIの名前や引数を参照して,この検出を行う。
専用API"!selinux_read"を例示すると,検出部103は,ハンドラテーブルT1に示した"検出用API"ent_selinux_read"を実行して,この検出を行う。
例えば,専用API"!selinux_read"の場合,この第3の引数"resource"からアクセスするリソースの種別を検出できる。そして,専用API"!selinux_read"の場合,この専用APIの名前の一部"read"からアクセスの種別が読み出し("read")であると検出できる。
ここで,引数を参照してリソースの種別の検出を行う場合,この引数に設定される情報(例えば,int型の値)を検出する必要がある。図4の" !selinux_read"の場合,第3の引数"resource"に設定される情報は,専用API"!selinux_read"の呼び出し元の図4のAPI"iread"を呼び出しているソースコード(図10の関数AppX参照)で設定されている。すなわち,図10における84,86,90行目のAPI"iread"において,それぞれ,アクセス先のリソース種別を示す情報" RESOURCE_a "," RESOURCE_b "," RESOURCE_c "が設定されている。この" RESOURCE_a "," RESOURCE_b "," RESOURCE_c "は,図10で説明したように,アクセスのリソース種別が,リソース「a」,「b」,「c」であることを示している。
前記した引数に設定される情報を検出することにより,検出部103は,ソフトウェア「x」が,リソース「a」,「b」,「c」に読み出しのためにアクセス("read")することを検出する。
他にも,専用API"!selinux_write"を例示すると,検出部103は,ハンドラテーブルT1に示した"検出用API"ent_selinux_write"を実行して,前記した検出を行う。
例えば,専用API"!selinux_write"の場合,この第3の引数"resource"からアクセスするリソースの種別を検出できる。そして,専用API"!selinux_write"の場合,この専用APIの名前の一部"write"からアクセスの種別が書き込み("write")であることを検出できる。
ここで,引数を参照してリソースの種別の検出を行う場合,この引数に設定される情報を検出する必要がある。図5の" !selinux_ write "の場合,第3の引数"resource"に設定される情報は,専用API"!selinux_write"の呼び出し元の図5のAPI"iwrite"を呼び出しているソースコード(図10の関数AppX)で設定されている。すなわち,図10における88行目のAPI"iwrite"において,アクセス先のリソース種別を示す情報" RESOURCE_b "が設定されている。この" RESOURCE_b "は,図10で説明したように,アクセスのリソース種別が,リソース「b」であることを示している。
前記した引数に設定される情報を検出することにより,検出部103は,ソフトウェア「x」が,リソース「b」に書き込みのためにアクセス("write")することを検出する。
以上説明したように,検出部103は,ソースコード「x」に含まれる専用APIの引数として入力されるリソースの種別および専用APIの名前に関連付けられたアクセスの種別を検出する。換言すれば,検出部103は,検出した名前(専用APIの名前)の専用APIの引数として入力されるリソースの種別および検出した名前に関連付けられたアクセスの種別を検出する。
そして,検出部103は,検出結果をストレージ12に記憶する(矢印203_2参照)。
(プロセス-リソーステーブル)
図11は,検出結果を記憶するテーブルの一例である。プロセス-システムリソーステーブルT2は,プロセス「x」(ソフトウェア「x」)が,アクセスするリソースとこのアクセスの種別とを記憶する。
具体的には,プロセス-システムリソーステーブルT2は,プロセス名欄と,リソース-アクセス種別欄とを有する。検索部102は,検査対象のソフトウェアの名前(プロセスの名前)をプロセス名欄に記憶する。前記の例では,検出部103は,プロセス名欄に,プロセス「x」を記憶する。
検出部103は,リソース-アクセス種別欄に,検査対象のソフトウェアがアクセスするリソースとこのアクセスの種別とを記憶する。検出部103は,例えば,"リソース「」にアクセス()""と記憶する。ここで,検出部103は,リソース「」の括弧内には,そのリソースの名前(例えば,ファイル名,ポート番号)を記憶する。そして,アクセス()の括弧内には,このアクセスの種別(例えば,"read"や"write")を記憶する。なお,検出部103は,同一リソースに異なる種別のアクセスが専用APIにより実行される場合,そのアクセスの種別を","(カンマ)で区切って記憶する。
前記の例では,検出部103は,プロセス「x」が,リソース「a」,「b」,「c」に読み出しのためにアクセス("read")することを検出した。そして,検出部103は,プロセス「x」が,リソース「b」に書き込みのためにアクセス("write")することを検出した。検出部103は,この検出結果を図11の符号P11〜P13に示したように,プロセス-システムリソーステーブルT2に記憶する。検出部103は,他にも,符号P14から下の行に示したように,検出結果を,プロセス-システムリソーステーブルT2に記憶する。
次に,判定部104は,図11のプロセス-システムリソーステーブルT2と,図8のセキュリティポリシSPとを照合して,プロセス「x」によるリソース「a」〜「i」に対するアクセスがセキュリティポリシSPに違反していないか判定し,判定結果をストレージ12に記憶する(矢印204参照)。
具体的には,判定部104は,図11のプロセス-システムリソーステーブルT2に記憶した検出結果を1行ずつ読み出し,読み出した検出結果とセキュリティポリシSPの全エントリとを照合する。そして,判定部104は,この全エントリにこの読み出した検出結果が定義されていない場合に,読み出した検出結果についてセキュリティポリシに違反しているとの判定結果をストレージ12に記憶する。
図11の例では,符号P11に示す検出結果は,プロセス「x」がリソース「a」に読み出し形式でアクセス(read)である。プロセス「x」がリソース「a」に読み出し形式でアクセス(read)することは,図8の符号P1によれば許可(read)されている。
また,符号P12に示す検出結果は,プロセス「x」がリソース「b」に読み出し形式および書き込み形式でアクセス(read,write)である。プロセス「x」がリソース「b」に読み出し形式および書き込み形式でアクセス(read,write)することは,図8の符号P2によれば許可(read,write)されている。
ここで,符号P13に示す検出結果は,プロセス「x」がリソース「c」に読み出し形式でアクセス(read)である。しかし,図8には,プロセス「x」がリソース「c」に読み出し形式でアクセス(read)することは定義されていない。
符号P14以下の行に示す検出結果は,プロセス「x」がリソース「d」〜「i」にアクセスすることを示している。しかし,図8には,プロセス「x」がリソース「d」〜「i」にアクセスすることは定義されていない。
判定部104は,例えば,セキュリティポリシに違反しているアクセスについての判定結果をストレージ12に記憶する。判定部104は,前記した例では,プロセス「x」がリソース「d」〜「i」にアクセスすることはセキュリティポリシに違反するとの判定結果をストレージ12に記憶する。
以上説明したように,判定部104は,セキュリティポリシSPと,検出部103が検出したリソースの種別およびアクセスの種別とに基づいて,ソフトウェア「x」(プログラム)がセキュリティポリシSPに違反するか否かを判定する。判定部104は,この判定において,セキュリティポリシSPに,検出されたリソースの種別およびアクセスの種別が含まれていないと,プログラムがセキュリティポリシSPに違反すると判定する。
通知部105は,判定部104が記憶した判定結果を表示装置3に表示する(矢印205参照)。図12は,判定結果の表示例を示す図である。通知部105は,図12の表示メッセージMに示すように,"プロセス「x」は,リソース「c」に対して,アクセス制限されます。"など,前記した判定結果を表示装置3に表示する。他にも,通知部105は,この判定結果をログファイルに記憶してもよい。
(処理の流れ)
図13は,セキュリティ検査の処理の流れを説明するフロー図の一例である。なお,ステップS1の実行の前に,既に,ストレージ12は,ソース・ヘッダファイルSHF,ハンドラテーブルT1,セキュリティポリシSPを記憶しているとする。
ステップS1:管理部101は,開発者からの検査実行指示を受信する(図7の矢印201参照)。
ステップS2:検索部102は,検査対象となるソフトウェアのソースファイルとヘッダファイルとを検索部102のソース・ヘッダファイルSHFから検索する(図7の矢印202参照)。
ステップS3:検出部103は,図9のハンドラテーブルT1を読み出し,ステップS2で検索したソースファイルとヘッダファイルとに含まれるソースコードの中からハンドラテーブルT1の専用API欄に記憶されている専用APIを検出する。
ステップS4:検出部103は,ステップS3で検出した専用APIがアクセスするリソースの種別およびアクセスの種別を検出し,検出結果をストレージ12に記憶する(図7の矢印203_1,203_2参照)。
ステップS5:判定部104は,判定部104は,図8のセキュリティポリシSPと,検出部103が検出したリソースの種別およびアクセスの種別(図11のプロセス-システムリソーステーブルT2参照)とに基づいて,検査対象のソフトウェアがセキュリティポリシSPに違反するか否かを判定する。そして,判定部104は,判定結果をストレージ12に記憶する(図7の矢印204参照)。
ステップS6:通知部105は,ステップS5でストレージ12に記憶した判定結果を表示装置3に表示する(矢印205参照)。この判定結果の表示の具体例については,図12を参照。
以上説明した第1の実施の形態によれば,検査対象となるソフトウェアを実際にコンピュータで実行させることなく,検査対象となるソフトウェアの全ソースコードに基づいてソフトウェアのセキュリティ検査を行う。そのため,このソフトウェアの全処理を実行させるための検査用データを作成することが困難であることに起因して,セキュリティ検査の精度が低下することがない。すなわち,本実施の形態によれば,検査対象となるソフトウェアを実際にコンピュータで実行させる場合に比べてソフトウェアのセキュリティ検査を高精度に行える。
また,このソフトウェアの全処理が実行されるように,検査用データを作成する必要がなく,セキュリティ検査の工数,時間を削減できる。
なお,ソフトウェア開発者は,専用APIを利用してソースコードを作成する必要がある。そのため,従来のソースコードの作成に比べると,不便さを感じる可能性がある。しかし,本実施の形態によれば,セキュリティ検査を高精度に行え,その工数,時間をも削減できるので,前記した不便さよりも利点が大きい。
[第2の実施の形態]
第1の実施の形態では,アクセスするリソースの種別を検出する際,専用APIのリソース種別を示す引数("resource")に設定される情報を検出する。かかる情報の検出には,専用APIのリソース種別を設定しているソースコードを検出する必要がある。この専用APIのリソース種別を設定しているソースコードから,この専用APIが記述されているソースコードまでのネストが深い場合,ソースコードを検出するまでの時間が長くなる。その結果,セキュリティ検査の時間が長くなる。
そこで,セキュリティ検査の時間を短縮するため,ソフトウェア開発者は,特定のリソースにアクセスする専用APIを予め作成する。
(ソースコード)
図14〜図16を参照して専用APIを含むソースコードについて説明する。図14は,専用APIを含むソースコードの第3の例を説明する図である。図14のソースコードは,API名と関連して定義されているリソースにアクセスしてデータを読み出すAPIのソースコードである。
図14におけるソースコードは,図2のソースコードにおける6行目のAPI" read (fd, buf, size) "を,106行目のAPI"!selinux_a_read (ownpid, fd, buf, size)"に置き換えたソースコードである。
106行目のAPI"!selinux_a_read"における,第1の引数"ownpid ",第2の引数"fd",第3の引数"buf",第4の引数"size"は,それぞれ,図4の46行目のAPI" !selinux_read"における,第1の引数"ownpid ",第2の引数"fd",第4の引数"buf",第5の引数"size"と同じである。
専用API"!selinux_a_read"は,API名の一部文字列"!selinux"と"read"との間の文字"_"(アンダースコア)で挟まれている文字"a"で識別されるリソース種別「a」に対応するリソースにアクセスする専用APIである。
専用API"!selinux_a_read"の直接の呼び出し元のAPI"a_iread"の実行により,リソース種別「a」に対するアクセス("read")が実行される。
図15は,専用APIを含むソースコードの第4の例を説明する図である。図15におけるソースコードは,図3のソースコードにおける27行目のAPI" write (fd, buf + total_written, size - total_written) "を,126行目のAPI"!selinux_a_write (ownpid, fd, buf + total_written, size - total_written) "に置き換えたソースコードである。
126行目のAPI"!selinux_a_write "における,第1の引数"ownpid ",第2の引数"fd",第3の引数" buf + total_written ",第4の引数" size - total_written "は,それぞれ,図5の67行目のAPI" !selinux_write"における,第1の引数"ownpid ",第2の引数"fd",第4の引数" buf + total_written ",第5の引数" size - total_written "と同じである。
専用API"!selinux_a_write"は,API名の一部文字列"!selinux_"と"_write"との間の文字"_"で挟まれている文字"a"で識別されるリソース種別「a」に対応するリソースにアクセスする専用APIである。
専用API"!selinux_a_write"の直接の呼び出し元のAPI"a_iread"の実行により,リソース種別「a」に対するアクセス("write")が実行される。
図16は,図14で説明したAPI"a_iread",図15で説明したAPI"a_iwrite"を含むソースコードの一例である。
141行目の関数" AppX()"は,142行目の"{"と,148行目の"}"との間で示されたステップを実行するようにコンピュータに指示する。
なお,変数fd1,変数"size1"には,図10で説明したように値が設定されている。また,関数" AppX"の実行開始時(例えば,行番号143の(省略)実行時)において,第1のメモリ領域が確保される。そして,第1のメモリ領域の先頭アドレスがCHAR型のポインタ"buf1"に設定されている。なお,第1のメモリ領域のサイズは,少なくとも変数"size1"に設定された各所定の値以上のバイトである。
また,ユーザが予め定義したsize_t型の変数"ret"は,関数" AppX"の中で既に定義されている。
そして,関数"AppX"は,以下の3つの引数を指定して,144行目のAPI"a_iread"(図14参照)を実行する。この3つの引数とは,ファイルディスクリプタ"fd1",読み出しデータ格納領域のポインタ"buf1",読み出し指定変数"size1"である。
そして,関数"AppX"は,以下の3つの引数を指定して,146行目のAPI"a_iwrite"(図15参照)を実行する。この3つの引数とは,144行目のAPI"a_iread"(図14参照)と同じである。
(APIテーブル)
図17は,APIテーブルの第2の例を説明した図である。システムリソースアクセスAPIハンドラテーブルT3(以下,ハンドラテーブルT3と記す)は,専用APIの名前と,この専用APIの実行によりアクセスするリソースとこのアクセスの種別を解析する検出用のAPIの名前とを記憶したテーブルである。ストレージ12は,図17のハンドラテーブルT3を記憶する。ハンドラテーブルT3の構成は,図9のハンドラテーブルT1の構成と同様である。
図17において説明するリソースに対してアクセスするプログラム部品(例えば,専用API)の名前は,アクセスの種別とアクセス先のリソースの種別とに関連付けられた名前である。
例えば,"!selinux_a_read"は,リソース「a」を読み取るための専用APIの名前を示す。専用APIの名前"!selinux_a_read "の一部文字列"read"は,この名前がアクセスの種別"read"(読み取り)に関連付けられた名前であることを示す。そして,専用APIの名前"!selinux_a_read "において"_"で挟まれた文字"a"は,この名前がアクセス先のリソースの種別に関連付けられた名前であることを示す。
"!selinux_a_write"は,リソース「a」に書き込むための専用APIを示す。専用APIの名前"!selinux_a_write "の一部文字列"write"は,この名前がアクセスの種別"write"(書き込み)に関連付けられた名前であることを示す。そして,専用APIの名前"!selinux_a_write "において"_"で挟まれた文字"a"は,この名前がアクセス先のリソースの種別に関連付けられた名前であることを示す。
検出用API欄は,専用API欄に記憶されている名前で特定される専用APIの実行によりアクセスするリソースの種別とこのアクセスの種別を検出する検出用APIの名前を記憶する。
(検査部100)
図7,図8,図14〜図17を参照して,第2の実施の形態における検査部100の機能を詳細に説明する。図7の検索部102は,第1の実施の形態で説明したように,管理部101からの検査実行指示に応答して,ソフトウェア「x」のソースファイルとヘッダファイルとをストレージ12のソース・ヘッダファイルSHFから検索する(矢印202参照)。そして,検索部102は,検索したソースファイルとヘッダファイルに含まれるソースコード「x」を抽出する。
ソースコード「x」の中には,プログラム部品(例えば,API)が含まれる。このAPIは,例えば,図14の"!selinux_a_read (ownpid, fd, buf, size)",図15の"!selinux_a_write (ownpid, fd, buf + total_written, size - total_written) "である。
このAPIは,この名前に関連付けられたリソースの種別("_a_"参照)に応じたリソースに対して,プログラム部品の名前に関連付けられたアクセスの種別("read","write"参照)に応じたアクセスを行う。
検出部103は,図17のハンドラテーブルT3を読み出す。そして,検出部103は,ソースコード「x」の中から,ハンドラテーブルT3の専用API欄に記憶されている専用APIを検出する。図14〜図17の例では,検出部103は,専用API"!selinux_a_read","!selinux_a_write"を検出する。
そして,検出部103は,ソースコード「x」の専用APIがアクセスするリソースの種別およびアクセスの種別を検出する(矢印203_1参照)。検出部103は,検出した専用APIに対応する検出用API(ハンドラテーブルT3の検出用API欄参照)を実行し,この検出を行う。検出用APIは,例えば専用APIの名前を参照して,この検出を行う。
専用API"!selinux_a_read"を例示すると,検索部102は,図17のハンドラテーブルT3に示した"検出用API"ent_selinux_a_read"を実行して,この検出を行う。
例えば,専用API"!selinux_a_read"の場合,専用APIの名前の一部"_a_"からアクセスするリソースの種別「a」を検出できる。そして,専用API"!selinux_a_read"の場合,この専用APIの名前の一部"read"からアクセスの種別が読み出し("read")であると検出できる。
前記したアクセス種別,リソース種別の検出により,検出部103は,ソフトウェア「x」が,リソース「a」に読み出しのためにアクセス("read")することを検出する。
他にも,専用API"!selinux_a_write"を例示すると,検出部103は,ハンドラテーブルT3に示した"検出用API"ent_selinux_a_write"を実行して,前記した検出を行う。
例えば,専用API"!selinux_a_write"の場合,専用APIの名前の一部"_a_"からアクセスするリソースの種別を検出できる。そして,専用API"!selinux_a_write"の場合,この専用APIの名前の一部"write"からアクセスの種別が書き込み("write")であることを検出できる。
前記したアクセス種別,リソース種別の検出により,検出部103は,ソフトウェア「x」が,リソース「a」に書き込みのためにアクセス("write")することを検出する。検出部103は,検出結果をストレージ12に記憶する(矢印203_2参照)。
以上説明したように,検出部103は,ソースコード「x」に含まれる専用APIの名前に関連付けられた,リソースの種別およびアクセスの種別を検出する。換言すれば,検出部103は,検出した名前(専用APIの名前)に関連付けられた,リソースの種別およびアクセスの種別を検出する。
そして,判定部104は,セキュリティポリシSPと,検出したリソースの種別およびアクセスの種別とに基づいて,ソフトウェア「x」(プログラム)がセキュリティポリシSPに違反するか否かを判定する。判定部104は,この判定において,セキュリティポリシSPに,検出されたリソースの種別およびアクセスの種別が含まれていないと,プログラムがセキュリティポリシSPに違反すると判定する。通知部105は,判定部104が記憶した判定結果を表示装置3に表示したり,通知部105は,この判定結果をログファイルに記憶する。
本実施の形態によれば,アクセスするリソースの種別をプログラム部品の名前から検出できるので,第1の実施の形態で説明したように引数を解析してリソースの種別を検出する場合に比べて,セキュリティ検査の時間を短縮できる。
[その他の実施の形態]
第1,第2の実施の形態では,セキュリティ検査を,セキュリティ検査の対象となるソフトウェアのソースコードをコンパイルする前に行った。この検査をコンパイルする際に実行してもよい。
例えば,検査部100(図7参照)の管理部101は,ソフトウェアの実行ファイルの作成指示を受信すると,第1,第2の実施の形態で説明したように,検査の実行を指示する。検査部100は,この指示に応答して,このソフトウェアのセキュリティ検査を実行する。
なお,第1の実施の形態では,検出部103は,引数を参照してリソースの種別の検出を行う場合,この引数に設定される情報(例えば,int型の値)を検出した。検出部103は,この検出において,コンパイラの既存技術であるデータ解析を利用してもよい。
このセキュリティ検査においてセキュリティポリシ違反がない場合,検査部100は,このソフトウェアの実行ファイルの作成指示をコンパイラ200に行う。コンパイラ200は,検索部102が既に検索したソースファイルとヘッダファイルとからオブジェクトコードを作成し,このオブジェクトコードから実行ファイルを作成する。
セキュリティ検査をコンパイルする際に実行することにより,セキュリティ検査およびコンパイルとで共通する処理(例えば,ソースファイルの検索処理)を重複して行わないので,セキュリティ検査およびコンパイルの処理時間を短縮できる。
以上の実施の形態をまとめると,次の付記のとおりである。
(付記1)
コンピュータに,
記憶部に記憶された,リソースに対してアクセスするプログラム部品の名前を含む部品情報を参照し,
前記部品情報に含まれる前記プログラム部品の名前をソースコードから検出し,
前記記憶部に記憶された,前記ソースコードに基づくプログラムからのアクセスを許可するリソースが規定されたセキュリティポリシ情報と,検出された前記名前のプログラム部品によりアクセスされるリソースとに基づいて,前記ソースコードに基づくプログラムが前記セキュリティポリシ情報に違反するか否かを判定する
処理を実行させるプログラム。
(付記2)
付記1において,
前記プログラム部品の名前は,前記アクセスの種別に関連付けられた名前であって,
前記セキュリティポリシ情報は,前記アクセスが許可される前記リソースの種別と前記アクセスの種別とが対応付けて規定された情報であって,
前記検出において,さらに,検出した前記名前の前記プログラム部品の引数として入力される前記リソースの種別および検出した前記名前に関連付けられた前記アクセスの種別を検出し,
前記判定において,前記セキュリティポリシ情報と,検出した前記リソースの種別および前記アクセスの種別とに基づいて,前記プログラムが前記セキュリティポリシ情報に違反するか否かを判定する
処理を前記コンピュータに実行させるプログラム。
(付記3)
付記2において,
前記プログラム部品は,引数としてアクセス先のリソースの種別が入力され,入力された前記種別に応じたリソースに対して,当該プログラム部品の名前に関連付けられた前記アクセスの種別に応じたアクセス
を前記コンピュータに実行させるプログラム。
(付記4)
付記1において,
前記プログラム部品の名前は,前記アクセスの種別とアクセス先のリソースの種別とに関連付けられた名前であって,
前記検出において,さらに,検出した前記名前に関連付けられた,前記リソースの種別および前記アクセスの種別を検出し,
前記判定において,前記セキュリティポリシ情報と,検出した前記リソースの種別および前記アクセスの種別とに基づいて,前記プログラムが前記セキュリティポリシ情報に違反するか否かを判定する
処理を前記コンピュータに実行させるプログラム。
(付記5)
付記4において,
前記プログラム部品は,当該プログラム部品の名前に関連付けられた前記リソースの種別に応じたリソースに対して,当該プログラム部品の名前に関連付けられた前記アクセスの種別に応じたアクセス
を前記コンピュータに実行させるプログラム。
(付記6)
付記2または4において,
前記判定において,前記セキュリティポリシ情報に,検出された前記リソースの種別および前記アクセスの種別が含まれていないと,前記プログラムが前記セキュリティポリシ情報に違反すると判定する
処理を前記コンピュータに実行させるプログラム。
(付記7)
付記1において,
前記ソースコードのコンパイルの際に,前記検出する処理と前記判定する処理と
を前記コンピュータに実行させるプログラム。
(付記8)
リソースに対してアクセスするプログラム部品の名前を含む部品情報と,ソースコードに基づくプログラムからのアクセスを許可するリソースが規定されたセキュリティポリシ情報とを記憶した記憶部と,
前記部品情報を参照し,前記部品情報に含まれる前記プログラム部品の名前をソースコードから検出し,前記セキュリティポリシ情報と,検出された前記名前のプログラム部品によりアクセスされるリソースとに基づいて,前記ソースコードに基づくプログラムが前記セキュリティポリシ情報に違反するか否かを判定する処理部と
を有する判定装置。
(付記9)
プログラムがセキュリティポリシに違反するか否かを判定する判定装置で実行される判定方法であって,
記憶部に記憶された,リソースに対してアクセスするプログラム部品の名前を含む部品情報を参照し,前記部品情報に含まれる前記プログラム部品の名前をソースコードから検出する処理を前記判定装置に実行させ,
前記記憶部に記憶された,前記ソースコードに基づくプログラムからのアクセスを許可するリソースが規定されたセキュリティポリシ情報と,検出された前記名前のプログラム部品によりアクセスされるリソースとに基づいて,前記ソースコードに基づくプログラムが前記セキュリティポリシ情報に違反するか否かを判定する処理を前記判定装置に実行させる
判定方法。