メインコンテンツ

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

危険な標準関数を使用しています

危険な関数が格納先バッファーでバッファー オーバーフローを引き起こす可能性がある

説明

この問題は、コードで、バッファー オーバーフローになる可能性があるやり方でデータをバッファーに書き込む標準関数が使用されている場合に発生します。

次の表に、危険な標準関数、各関数を使用した場合のリスク、および代用する関数を示します。チェッカーは以下にフラグを設定します。

  • 本質的に危険な関数の使用。

  • 危険な可能性のある関数の使用 (データが書き込まれるバッファーのサイズをコンパイル時に決定可能な場合のみ)。チェッカーは、バッファーが動的に割り当てられるこのような関数の使用にフラグを設定しません。

危険な関数リスク レベルより安全な関数
gets本質的に危険 — コンソールからは入力の長さを制御できない。fgets
std::cin::operator>> および std::wcin::operator>>本質的に危険 — コンソールからは入力の長さを制御できない。

入力長を制御するには、cin 呼び出しの前に cin.width を置きます。このメソッドは入力を切り捨てる結果になる場合があります。

バッファー オーバーフローと入力切り捨てが発生しないようにするには、>> 演算子の格納先に std::string オブジェクトを使用します。

strcpy潜在的に危険 — 格納先バッファーのサイズが小さすぎて、ソース バッファーと null 終端が収まらない場合は、バッファー オーバーフローが発生する可能性がある。 関数 strlen() を使用してソース バッファーのサイズを決定し、格納先バッファーがソース バッファーと null 終端を収められるように十分なメモリを割り当てます。strcpy の代わりに、関数 strncpy を使用します。
stpcpy潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。stpncpy
lstrcpy または StrCpy潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。StringCbCopyStringCchCopystrncpystrcpy_s または strlcpy
strcat潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。strncatstrlcat または strcat_s
lstrcat または StrCat潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。StringCbCatStringCchCatstrncaystrcat_s または strlcat
wcpcpy潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。wcpncpy
wcscat潜在的に危険 — 連結された結果が作成先より大きいと、バッファー オーバーフローが発生する可能性がある。wcsncatwcslcat または wcncat_s
wcscpy潜在的に危険 — ソースの長さがコピー先より大きいと、バッファー オーバーフローが発生する可能性がある。wcsncpy
sprintf潜在的に危険 — 出力の長さが不明な長さや値に依存していると、バッファー オーバーフローが発生する可能性がある。snprintf
vsprintf潜在的に危険 — 出力の長さが不明な長さや値に依存していると、バッファー オーバーフローが発生する可能性がある。vsnprintf

リスク

これらの関数はバッファー オーバーフローの原因となることがあり、攻撃者はこれを利用してプログラムに侵入できます。

修正方法

修正方法は欠陥の根本原因によって異なります。上の表に記載されている修正と以下の修正付きのコード例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

すべて展開する

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

#define BUFF_SIZE 128


int dangerous_func(char *str)
{
    char dst[BUFF_SIZE];
    int r = 0;

    if (sprintf(dst, "%s", str) == 1)
    {
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

この関数例では、sprintf を使用して文字列 strdst にコピーしています。しかし、str がバッファーより大きいと、sprintf がバッファー オーバーフローの原因となる場合があります。

修正 — バッファー サイズを指定して snprintf を使用

1 つの修正方法として、snprintf を代わりに使用し、バッファー サイズを指定します。

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

#define BUFF_SIZE 128


int dangerous_func(char *str)
{
    char dst[BUFF_SIZE];
    int r = 0;

    if (snprintf(dst, sizeof(dst), "%s", str) == 1)
    {
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

この例では、source バッファーのサイズは不明ですが、destination バッファーのサイズは 128 で固定されます。この destination バッファーのサイズは、source バッファーからの文字を収め、そのバッファーを null で終了するには不十分な可能性があります。Polyspace® は、ルールの違反を報告します。

#include <string.h>
  
int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char destination[128];
  strcpy((char*)source, destination);
  
  return 0;
}
修正 — 格納先として十分なメモリを割り当てる

この違反は、destination バッファーに十分なメモリを割り当てることによって解決されます。たとえば、関数 strlen() を使用して source バッファーのサイズを計算し、source バッファーからのすべての文字と null 終端 ('\0') を収めるのに十分なメモリを destination バッファーに割り当てます。

#include <string.h>
#include <stdlib.h>
  
int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char* destination = (char *)malloc(strlen(source)+ 1);
  if(destination!=NULL){
      strncpy((char*)source, destination,sizeof(source));//No defect
  }else{
      /*Handle Error*/
  }
  //...
  free(destination);
  return 0;
}

結果情報

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

バージョン履歴

R2015b で導入

すべて展開する