メインコンテンツ

外部制御されるパスから実行されたコマンド

セキュリティで保護されないソース由来のパス引数

説明

この欠陥は、プログラムで実行されるコマンドへのパスが外部ソースから構築された場合に発生します。

リスク

攻撃者は次のことができます。

  • プログラムが実行するコマンドを、場合によっては攻撃者のみが制御できるコマンドに変更する。

  • コマンドが実行される環境を変更し、それによって攻撃者がコマンドの意味と実行内容を制御する。

修正方法

コマンドを呼び出す前にパスを検証し、想定どおりの場所であることを確認します。

チェッカーの拡張

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

すべて展開する

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

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

void bug_taintedpathcmd() {
    char cmd[SIZE128] = "";
    char* userpath = getenv("MYAPP_PATH");

    strncpy(cmd, userpath, SIZE100);//Noncompliant
    strcat(cmd, "/ls *");
    /* Launching command */
    system(cmd);//Noncompliant 
}

この例では、パスを環境変数 MYAPP_PATH から取得しています。このパス文字列は汚染されています。Polyspace は関数 strncopy でのこのパス文字列の使用にフラグを設定します。system は、パスの値をチェックせずに、この汚染されたパスからコマンドを実行しています。そのパスが想定されたパスではない場合、プログラムは誤った場所で実行されます。

修正 — 信頼できるパスを使用

1 つの修正方法として、許可されているパスのリストを使用して、環境変数パスと照合します。

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

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

/* Function to sanitize a string */
/* Any defect is localized here */
int sanitize_str(char* s, size_t n) {
    int res = 0;
    /* String is ok if */
    if (s && n>0 && n<SIZE128) {
        /* - string is not null                     */
        /* - string has a positive and limited size */
        s[n-1] = '\0';  /* Add a security \0 char at end of string *///Noncompliant
        /* Tainted pointer detected above, used as "firewall" */
        res = 1;
    }
    return res;
}

/* Authorized path ids */
enum { PATH0=1, PATH1, PATH2 };

void taintedpathcmd() {
    char cmd[SIZE128] = "";

    char* userpathid = getenv("MYAPP_PATH_ID");
    if (sanitize_str(userpathid, SIZE100)) {
        int pathid = atoi(userpathid);


        char path[SIZE128] = "";
        switch(pathid) {
            case PATH0:
                strcpy(path, "/usr/local/my_app0");
                break;
            case PATH1:
                strcpy(path, "/usr/local/my_app1");
                break;
            case PATH2:
                strcpy(path, "/usr/local/my_app2");
                break;
            default:
                /* do nothing */
		break;
        }
        if (strlen(path)>0) {
            strncpy(cmd, path, SIZE100);
            strcat(cmd, "/ls *");
            system(cmd);    
        }
    }
}

結果情報

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

バージョン履歴

R2015b で導入