メインコンテンツ

汚染された値で制限されたループ

セキュリティで保護されないソース由来の値で制御されているループ

説明

この欠陥は、ループがセキュリティで保護されていないソースから取得された値に制限される場合に発生します。

リスク

汚染された値は、過剰ループや無限ループの原因となることがあります。攻撃者は、この脆弱性を利用して、プログラムを終了させたり、その他の想定外の動作を引き起こしたりする可能性があります。

修正方法

ループを開始する前に、その下限と上限を検証することによって、不明な境界と反復値を確認します。ループは、汚染された値の下限と上限の両方が検証されている場合にのみ実行します。汚染された値の下限と上限の両方が許容範囲内にあることを明示的にチェックします。または、汚染された値を飽和またはクランプします。

チェッカーの拡張

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

すべて展開する

#include<stdio.h>
enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

int taintedloopboundary(void) {
    int count;
    scanf("%d", &count);
    int res = 0;
    for (int i=0 ; i < count; ++i) {//Noncompliant
        res += i;
    }
    return res;
}

この例では、関数でユーザー入力を使用して count 回のループを行っています。count は、for ループの開始前に値がチェックされないため、任意の数値になる可能性があります。

修正: 汚染されたループ制御をクランプ

1 つの修正方法として、汚染されたループ制御をクランプします。汚染されたループ変数 count を検証するために、この例では、インライン関数の minmax を使用することによって count を最小値と最大値に制限します。ユーザー入力に関係なく、count の値は既知の範囲内に留まります。

#include<stdio.h>
#include<algorithm>
#define MIN 50
#define MAX 128
static  inline int max(int a, int b) { return a > b ? a : b;}
static inline int min(int a, int b) { return a < b ? a : b; }

int taintedloopboundary(void) {
	int count;
	scanf("%d", &count);
	int res = 0;
	count = max(MIN, min(count, MAX));
	for (int i=0 ; i<count ; ++i) { 
		res += i;
	} 
	return res;
}
修正 — 汚染されたループ制御をチェック

別の修正方法として、for ループが開始する前に、汚染されたループ境界変数の下限と上限をチェックします。この例では、count の下限と上限をチェックし、count が 0 ~ 127 の範囲内にある場合にのみループを実行します。

#include<stdio.h>

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


int taintedloopboundary(void) {
    int count;
    scanf("%d", &count);
    int res = 0;

    if (count>=0 && count<SIZE128) {
        for (int i=0 ; i<count ; ++i) { 
            res += i;
        }
    }
    return res;
}

結果情報

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

バージョン履歴

R2015b で導入