メインコンテンツ

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

システム関数の安全でない呼び出し

サニタイズされていないコマンド引数には悪用可能な脆弱性が含まれる

説明

この欠陥は、処理系定義のコマンド プロセッサを呼び出す関数を使用した場合に発生します。これらの関数には以下が含まれます。

  • C 標準関数 system()

  • POSIX 関数 popen()

  • Windows® 関数 _popen() および _wpopen()

リスク

コマンド プロセッサを呼び出す関数の引数がサニタイズされていない場合、悪用可能な脆弱性の原因になる可能性があります。攻撃者は任意のコマンドを実行したり、システム上の任意の場所にあるデータを読み取ったり変更したりできます。

修正方法

コマンド プロセッサを呼び出す system ファミリ関数を使用しないようにします。代わりに、POSIX の execve() や WinAPI の CreateProcess() など、より安全な関数を使用します。

すべて展開する

# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>

enum { 
SIZE512=512,
SIZE3=3};

void func(char *arg)
{
	char buf[SIZE512];
	int retval=sprintf(buf, "/usr/bin/any_cmd %s", arg);
	
	if (retval<=0 || retval>SIZE512){
		/* Handle error */
		abort();
	}
	/* Use of system() to pass any_cmd with 
	unsanitized argument to command processor */
	
	if (system(buf) == -1) {
	/* Handle error */
  }
} 

この例では、実行するコマンド プロセッサのホスト環境に system() が引数を渡しています。このコードはコマンド インジェクションによる攻撃に対して脆弱です。

修正 — 引数をサニタイズして execve() を使用

次のコードでは、any_cmd の引数がサニタイズされた後に execve() に渡されて実行されます。exec ファミリ関数は、コマンド インジェクション攻撃に対して脆弱ではありません。

# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>

enum { 
SIZE512=512,
SIZE3=3};


void func(char *arg)
{
  char *const args[SIZE3] = {"any_cmd", arg, NULL};
  char  *const env[] = {NULL}; 
  
  /* Sanitize argument */
  
  /* Use execve() to execute any_cmd. */

  if (execve("/usr/bin/time", args, env) == -1) { 
    /* Handle error */
  }
} 

結果情報

グループ: セキュリティ
言語: C | C++
既定値: オフ
コマンド ライン構文: UNSAFE_SYSTEM_CALL
影響度: High

バージョン履歴

R2017b で導入