メインコンテンツ

外部制御されるコマンドの実行

オペレーティング システムでのコマンドの投入に対し脆弱な、セキュリティで保護されないソース由来のコマンド引数

説明

この欠陥は、コマンドの全体または一部が外部制御された入力から構築された場合に発生します。

リスク

攻撃者は外部制御される入力を、オペレーティング システムのコマンドとして、あるいはアプリケーションの引数として利用できます。攻撃者は、読み取りや変更が可能な機密データの読み取りや変更を行い、意図しないコードを実行し、あるいはプログラムの他の側面にアクセスする可能性があります。

修正方法

入力を検証し、想定どおりの入力値のみが許可されるようにします。たとえば、許容される入力のリストを作成し、入力をそのリストと比較します。

チェッカーの拡張

既定では、Polyspace® は外部ソースからのデータは汚染されていると仮定します。Polyspace 解析での汚染のソースを参照してください。Polyspace 解析の現在のスコープ以外から発生したすべてのデータを汚染されたものと見なすには、コマンド ライン オプション [-consider-analysis-perimeter-as-trust-boundary] を使用します。

すべて展開する

#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "unistd.h"
#include "dlfcn.h"
#include "limits.h"
#define MAX 128


void taintedexternalcmd(void)
{
	char* usercmd;
	fgets(usercmd,MAX,stdin);
	char cmd[MAX] = "/usr/bin/cat ";
	strcat(cmd, usercmd);
	system(cmd);//Noncompliant 
}

この関数例では、コマンド変数をチェックせずにユーザー入力からコマンドを呼び出しています。

修正 — 事前定義されたコマンドを使用

1 つの修正方法として、switch ステートメントを使用して、ユーザー入力を switch 変数として使う事前定義されたコマンドを実行します。

#define _XOPEN_SOURCE
#define _GNU_SOURCE

#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "unistd.h"
#include "dlfcn.h"
#include "limits.h"

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};
enum { CMD0 = 1, CMD1, CMD2 };

void taintedexternalcmd(void)
{
    int usercmd = strtol(getenv("cmd"),NULL,10);
    char cmd[SIZE128] = "/usr/bin/cat ";

    switch(usercmd) {
        case CMD0:
            strcat(cmd, "*.c");
            break;
        case CMD1:
            strcat(cmd, "*.h");
            break;
        case CMD2:
            strcat(cmd, "*.cpp");
            break;
        default:
            strcat(cmd, "*.c");
    }
    system(cmd); 
}

結果情報

グループ: 汚染されたデータ
言語: C | C++
既定値: オフ
コマンド ライン構文: TAINTED_EXTERNAL_CMD
影響度: Medium

バージョン履歴

R2015b で導入