メインコンテンツ

CERT C++: MSC50-CPP

Do not use std::rand() for generating pseudorandom numbers

説明

ルール定義

疑似乱数を生成する std::rand() を使用しないようにします。1

Polyspace 実装

ルール チェッカーは、"疑似乱数発生器が脆弱です" をチェックします。

すべて展開する

問題

疑似乱数発生器が脆弱ですでは、暗号法的に脆弱な疑似乱数発生器 (PRNG) ルーチンの使用を特定します。

このチェッカーによってフラグが付けられる暗号法的に脆弱なルーチンのリストには次のものが含まれます。

  • rand, random

  • drand48lrand48mrand48erand48nrand48jrand48 および drand48_r などの同等の _r 付きルーチン

  • RAND_pseudo_bytes

リスク

こうした暗号法的に脆弱なルーチンは予測可能であり、セキュリティ目的で使用してはなりません。予測可能な乱数値で実行フローを制御する場合、プログラムは悪意のある攻撃に対し脆弱となります。

修正方法

CryptGenRandom (Windows) や OpenSSL/RAND_bytes (Linux/UNIX) など、より暗号法的に健全な乱数発生器を使用します。

例 - ランダムなループ回数

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

volatile int rd = 1;
int main(int argc, char *argv[])
{   
    int j, r, nloops;
    struct random_data buf;
    int i = 0;
    
    nloops = rand(); //Noncompliant
    
    for (j = 0; j < nloops; j++) {
        if (random_r(&buf, &i)) //Noncompliant
            exit(1);
        printf("random_r: %ld\n", (long)i);
    }
    return 0;
}

この例では、randrandom_r を使用して乱数を生成しています。これらの関数をセキュリティ目的で使用すると、こうした PRNG は悪意のある攻撃の発生源となる可能性があります。

修正 — より強固な PRNG を使用

1 つの修正方法として、脆弱な PRNG を、より強固な乱数発生器に置き換えます。


#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>

volatile int rd = 1;
int main(int argc, char* argv[])
{   
    int j, r, nloops;
    unsigned char buf;
    unsigned int seed;
    int i = 0;
    
    if (argc != 3) 
    {
        fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    seed = atoi(argv[1]);
    nloops = atoi(argv[2]);
    
    for (j = 0; j < nloops; j++) {
        if (RAND_bytes(&buf, i) != 1)
            exit(1);
        printf("RAND_bytes: %u\n", (unsigned)buf);
    }
    return 0;
}

チェック情報

グループ: 49.その他 (MSC)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.