STR03-C. null 終端バイト文字列を不注意に切り捨てない
バッファオーバーフローの脆弱性を軽減するには、多くの場合、コピーするバイト数を制限する代替関数を使うことが推奨される。たとえば、
strcpy()
の代わりにstrncpy()
を使用するstrcat()
の代わりにstrncat()
を使用するgets()
の代わりにfgets()
を使用するsprintf()
の代わりにsnprintf()
を使用する
これらの関数は、指定した制限を超える文字列を切り捨てる。さらに、strncpy()
のような関数は、結果の文字列が null で終端されることを保証しない(「STR32-C. 文字列は null 終端させる」を参照)。
意図しない null 終端バイトの切り捨てはデータの消失につながり、場合によってはソフトウェアの脆弱性につながる。
違反コード
標準関数 strncpy()
および strncat()
は、指定された n
文字をコピー元の文字列からコピー先の配列へコピーする。strncpy()
の場合、コピー元配列の最初の n
文字までに null 文字がなければ、結果の文字列は null で終端されず、残りの文字は切り捨てられる。
char *string_data; char a[16]; /* ... */ strncpy(a, string_data, sizeof(a));
適合コード (十分な領域がある場合)
十分な領域があれば、strcpy()
関数または strncpy()
関数を使って文字列と null 文字をコピー先バッファにコピーできる。データの切り捨てやバッファオーバーフローなどのエラーを防ぐため、コピー先バッファにコピー対象の文字列と null 文字を保持できる十分な大きさがあるかを確認すること。
char *string_data = NULL; char a[16]; /* ... */ if (string_data == NULL) { /* null ポインタエラーの処理 */ } else if (strlen(string_data) >= sizeof(a)) { /* 文字列過大エラーの処理 */ } else { strcpy(a, string_data); }
この適合コードでは、string_data
が null 文字で終端されていること、つまり、参照先の文字配列の範囲内に null バイトがあることが必要である。null バイトがないと、strlen()
は null バイトを探し続けて他のオブジェクトに迷い込むことになる。
適合コード (TR 24731-1)
「Extensions to the C Library—Part I」 [ISO/IEC TR 24731-1:2007] で定義されている strcpy_s()
関数は、コピー先バッファのサイズを引数として受け取るなどの安全策を提供する(「STR07-C. 境界チェックインタフェースを使用し、文字列操作を行う既存のコードの脅威を緩和する」を参照)。また、strnlen_s()
は、最大長を指定する引数を取り、null で終端されていない可能性のある文字列に対処する。
char *string_data = NULL; char a[16]; /* ... */ if (string_data == NULL) { /* null ポインタエラーの処理 */ } else if (strnlen_s(string_data, sizeof(a)) >= sizeof(a)) { /* 文字列過大エラーの処理 */ } else { strcpy_s(a, sizeof(a), string_data); }
strnlen_s()
または strcpy_s()
のどちらかの呼び出しによって実行時制約エラーが検出されると、現在登録されている実行時制約ハンドラが呼び出される。TR 24731-1 関数による実行時制約処理の詳細については、「ERR03-C. TR24731-1 で定義されている関数を呼び出す際は、実行時制約ハンドラを使用する」を参照。
例外
STR03-EX1: プログラマの意図が、null 終端バイト文字列を意図的に切り捨てることである場合。
リスク評価
文字列の切り捨てはデータの消失につながる可能性がある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
STR03-C |
中 |
中 |
中 |
P8 |
L2 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Compass/ROSE |
|
|
文字列を確実に null 終端するためには、 |
Fortify SCA |
5.0 |
|
CERT C Rule Pack を使ってこのルールの違反を検出できる。 |
V. 9.1 |
NNTS |
|
|
LDRA tool suite |
V. 8.5.4 |
115 S |
実装済み |
関連するガイドライン
CERT C++ Secure Coding Standard | STR03-CPP. Do not inadvertently truncate a null-terminated character array |
ISO/IEC TR 24731-1:2007 | |
ISO/IEC TR 24772:2013 | String Termination [CJM] |
MITRE CWE | CWE-170, Improper null termination CWE-464, Addition of data structure sentinel |
参考資料
[Seacord 2013] | Chapter 2, "Strings" |
翻訳元
これは以下のページを翻訳したものです。
STR03-C. Do not inadvertently truncate a null-terminated byte string (revision 84)