ABV.UNICODE.BOUND_MAP
バッファオーバーフロー - マッピング関数で配列インデックスが範囲外
ABV.UNICODE.BOUND_MAP は、MultiByteToWideChar マッピング関数と WideCharToMultiByte マッピング関数によって引き起こされるバッファオーバーラン状態をチェックします。通常、このチェックでは、WideCharToMultiByte がバッファ境界を正しくチェックできずに、バッファオーバーフローが生じる状態を検出します。
MultiByteToWideChar マッピング関数と WideCharToMultiByte マッピング関数の演算の詳細については、MSDN の Web サイトを参照してください。
脆弱性とリスク
これらのマッピング関数を不適切に使用すると、バッファオーバーフローを引き起こしてアプリケーションのセキュリティが低下する可能性があります。入力バッファのサイズは文字列のバイト数であり、出力バッファのサイズは文字数であるため、MultiByteToWideChar ではバッファオーバーフローを特に容易に引き起こすことができます。(WideCharToMultiByte 関数の場合は逆も真なり、です。この潜在的な状態を避けるには、バッファが受け取るデータ型に適したバッファサイズを指定することが重要です。
脆弱コード例
#include "stdafx.h"
#include <string.h>
#include <iostream>
using namespace std;
void convert(WCHAR *wcsPath)
{
char cpszPath[5] ="";
WideCharToMultiByte(CP_ACP, 0, wcsPath, -1, cpszPath, 260, 0, 0);
cout << cpszPath << endl;
}
Klocwork は 10 行目について、関数 WideCharToMultiByte がバッファ境界を正しくチェックせず、サイズ (260) のバッファ 'cpszPath' をオーバーフローさせる可能性を指摘する、バッファオーバーフローレポートを生成します。この場合は、入力バッファサイズが未検証であることから、関数 WideCharToMultiByte がバッファオーバーフローを引き起こします。
修正コード例
#include "stdafx.h"
#include <string.h>
#include <iostream>
using namespace std;
void convert(WCHAR sText[100]) {
char szTemp[20];
int nSize = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, sText, -1, szTemp, 0, 0, 0);
if (nSize > sizeof(szTemp))
{
return;
}else
{
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, sText, -1, szTemp, nSize , 0, 0);
}
cout << szTemp << endl;
}
修正例ではターゲットバッファのサイズがゼロの場合は、関数は、変換に必要なバイト数を返します。入力の文字のサイズは、変換前にバッファサイズと比較されます。
関連チェッカー
外部参考資料
- CERT ARR00-C: 配列の仕組みを理解する
- CERT ARR30-C: 範囲外のポインターまたは配列添え字を形成したり使用したりしない
- CERT ENV01-C: 環境変数のサイズについて仮定を行わない
- CWE-119: メモリバッファの範囲内の操作の不適切な制限
- CWE-124: バッファアンダーライト ('バッファアンダーフロー')
- CWE-125: 範囲外の読み取り
- CWE-176: ユニコードエンコーディングの不適切な取り扱い
- CWE-787: 範囲外の作成
- CWE-806: ソースバッファのサイズを使用したバッファアクセス
- STIG-ID:APP3590.1 バッファオーバーフローに脆弱なアプリケーション
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。