メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

Polyspace 解析での汚染のソース

一般に、コードの外部から変更可能なコード要素は、汚染されたデータと見なされます。攻撃者が汚染された変数に値を渡して、プログラムの障害、悪意のあるコードの挿入、リソースのリークを引き起こすおそれがあります。汚染されたデータを使用する操作の結果も、汚染されたものと見なされます。たとえば、汚染された変数を使用してファイルへのパスを計算する場合、そのファイルも汚染されたものになります。汚染されたデータと関連するリスクを軽減するには、データの内容を使用する前に検証します。

Polyspace® 汚染データ欠陥チェッカーを使用して、汚染されたデータのソースを特定してそのソースからのデータを検証することにより、コードのセキュリティを強化します。

汚染されたデータのソース

Polyspace は次のソースからのデータを汚染されたデータと見なします。

  • volatile オブジェクト:キーワード volatile を使用して宣言されたオブジェクトは、プログラム実行中にハードウェアによって変更可能です。volatile オブジェクトの内容をチェックせずに使用すると、セグメンテーション エラー、メモリ リーク、またはセキュリティ上の脅威を引き起こすおそれがあります。検証せずに volatile オブジェクトを使用すると、Polyspace はフラグを設定します。

  • ユーザー入力を取得する関数:getenvgetsreadscanffopen などのライブラリ関数は、環境変数、文字列、データ ストリーム、書式設定済みデータ、ファイルなどのユーザー入力を返します。main() もユーザーから直接入力引数を受け取る場合があります。ユーザーに依存する入力は予測できません。このような入力は、使用する前に書式、長さ、内容をチェックすることにより検証します。

  • ハードウェアを操作する関数:RegQueryValueEx などのライブラリ関数はレジスタや周辺装置などのハードウェアを操作します。このような関数はハードウェアに依存するデータを返し、これらは予測できない可能性があります。ハードウェアから取得したデータは、使用する前に書式、長さ、内容をチェックすることにより検証します。

  • 現在時刻を返す関数:ctime などのライブラリ関数は、システムの現在時刻を書式設定済み文字列として返します。文字列の書式は環境に応じて異なります。このような文字列は、使用する前に書式をチェックすることにより検証します。

  • 乱数を返す関数:乱数は、使用する前に書式と範囲をチェックすることにより検証します。

Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション -consider-analysis-perimeter-as-trust-boundary を使用します。Bug Finder チェッカーの既定の動作の変更を参照してください。

汚染されたデータの欠陥の影響

攻撃者は、想定外の入力をプログラムに故意に送り込むことにより汚染されたデータの欠陥を悪用し、スタックを露出させたり、機密データへのアクセスや機密データの削除を行うコマンドを実行したりします。ユーザー入力を使用してシステムを変更する、次のコードを考えます。

#include <stdio.h>
#include <stdlib.h>
#define MAX 128
void Echo(char* string, int n) {
	printf("Argument %d is; ",n);
	printf(string); //Tainted operation
}
void SystemCaller(char* string){
	printf("Calling System...");
	char cmd[MAX] = "/usr/bin/cat ";
	strcat(cmd, string);
	system(cmd);//Tainted operation
}

int main(int argc, char** argv) {
	int i = 0;
	for(i = 0;i<argc;++i){
		Echo(argv[i],i);
		SystemCaller(argv[i]);
	}
	return (0);
}
ユーザーからの入力は汚染されています。Polyspace は、このコード内の 2 つの汚染されたデータの欠陥にフラグを設定します。

  • 関数 Echo の行 printf(string) は、ユーザー入力文字列を検証せずに出力しています。この欠陥のため、攻撃者は入力文字列を操作してスタックを露出させます。たとえば、ユーザー入力が "%d" である場合、関数は n を出力した後、スタック内の整数を出力します。

  • 関数 SystemCaller では、ユーザー入力文字列がオペレーティング システム コマンドの呼び出しに使用されます。悪意のあるユーザーがこの欠陥を悪用して、機密データにアクセス、機密データを削除、さらにはシステムをクラッシュさせるコマンドを実行するおそれがあります。

このような攻撃を防ぐには、書式、長さ、内容をチェックすることにより、汚染されたデータを検証します。たとえば、次のコードでは汚染されたデータを使用する前に検証しています。

#include <stdio.h>
#include <stdlib.h>
#define MAX 128
extern char** LIST_OF_COMMANDS;
int isAllowd(char*);
void Echo(char* string, int n) {
	printf("Argument %d is; ",n);
	printf("%s",string); //Validated
}
void SystemCaller(char* string){
	printf("Calling System...");
	char cmd[MAX] = "/usr/bin/cat ";
	if(isallowed(string)==1){
	strcat(cmd, string);
	system(cmd);//Validated
	}
}

int main(int argc, char** argv) {
	int i = 0;
	for(i = 0;i<argc|| i<10;++i){
		Echo(argv[i],i);
		SystemCaller(argv[i]);
	}
	return (0);
}
printf%s として書式設定することにより、汚染された入力 string が検証されます。これで、プログラムは文字列の内容を出力し、スタックが露出することはなくなります。SystemCaller で、プログラムは、許可されたコマンドと入力が一致する場合にのみオペレーティング システム コマンドを実行します。

Polyspace での汚染されたデータの欠陥についての詳細は、汚染されたデータの欠陥を参照してください。

Polyspace 汚染データ チェッカー

汚染されたデータを、次の Bug Finder 欠陥とコーディング ルールを使用してチェックします。

参考

|

トピック