CRT のセキュリティ機能

多くの古い CRT 関数には、セキュリティが強化された新しいバージョンがあります。 セキュリティで保護された関数が存在する場合、低いセキュリティ レベルの古いバージョンは非推奨としてマークされ、新しいバージョンには _s ("secure") のサフィックスが付いています。

このコンテキストでの "非推奨" とは、関数の使用が推奨されないという意味です。 関数が CRT から削除される予定であるという意味ではありません。

セキュリティ保護された関数は、セキュリティ エラーが防止されたり修正されたりするわけではありません。 そうではなく、発生したエラーがキャッチされます。 エラー状態の追加チェックが行われます。 エラーがある場合は、エラー ハンドラーを呼び出します (「パラメーターの検証」を参照)。

たとえば、strcpy 関数は、コピーする文字列が大きすぎてコピー先のバッファーに入らない場合、これを通知できません。 セキュリティ保護されたバージョンの strcpy_s は、バッファーのサイズをパラメーターとして受け取ります。 そのため、バッファー オーバーランが発生するかどうかを判断できます。 strcpy_s を使用して、11 文字を 10 文字のバッファーにコピーするとエラーになります。strcpy_s ではこの間違いを訂正できません。 ただし、エラーを検出し、無効なパラメーター ハンドラーを呼び出して通知することができます。

非推奨に関する警告を除去する

低いセキュリティ レベルの古い関数に対する非推奨警告を除去するには、いくつかの方法があります。 _CRT_SECURE_NO_WARNINGS を定義するか、warning プラグマを使用するのが、最も簡単な方法です。 どちらの方法でも警告は無効になりますが、その警告の原因になったセキュリティの問題はそのまま存在します。 非推奨に関する警告を有効にしたまま、新しい CRT セキュリティ機能を利用するのがよい方法です。

C++ でそれを行う最も簡単な方法は、セキュリティ保護されたテンプレート オーバーロードを使用することです。 この方法では、多くの場合、使用されていない関数の呼び出しが、それらの関数のセキュリティ保護されたバージョンの呼び出しに置き換えられるので、非推奨に関する警告は除去されます。 たとえば、この非推奨とされている strcpy の呼び出しについて考えます:

char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated

_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES を 1 として定義すると、strcpy の呼び出しが、バッファー オーバーランを防ぐ strcpy_s の呼び出しに変更され、警告は除去されます。 詳細については、「セキュリティ保護されたテンプレート オーバーロード」を参照してください。

セキュリティで保護されたテンプレート オーバーロードのない、非推奨の関数の場合、セキュリティで保護されたバージョンを使用するように手動でコードを更新することを強くお勧めします。

セキュリティには関連しませんが、非推奨に関する警告が発生する別の要因として、POSIX 関数があります。 POSIX の関数名を標準に沿った名前に置き換えるか (access_access にするなど)、_CRT_NONSTDC_NO_WARNINGS を定義して、POSIX 関連の非推奨に関する警告を無効にします。 詳細については、「 互換性」を参照してください。

その他のセキュリティ機能

一部のセキュリティ機能を次に示します。

  • Parameter Validation. セキュリティ保護された関数と、その非セキュリティ保護バージョンの多くでは、パラメーターが検証されます。 検証には次のものが含まれます。

    • NULL 値のチェック。
    • 列挙値が有効であるかどうかのチェック。
    • 整数値が有効な範囲にあるかどうかのチェック。
  • 詳細については、「パラメーターの検証」を参照してください。

  • 開発者も無効なパラメーターのハンドラーを利用できるようになりました。 関数で無効なパラメーターが検出された場合に、アプリケーションをアサートしたり終了したりすることなく、_set_invalid_parameter_handler、_set_thread_local_invalid_parameter_handler でこれらの問題をチェックできます。

  • Sized Buffers. バッファーに書き込むセキュリティ保護された関数には、バッファー サイズを渡す必要があります。 セキュリティ保護されたバージョンでは、書き込みの前に、バッファーが十分な大きさであることが検証されます。 これにより、悪意のあるコードを実行できる可能性がある危険なバッファー オーバーラン エラーを回避できます。 通常、これらの関数は、errno エラー コードを返し、バッファーのサイズが小さすぎる場合、無効なパラメーター ハンドラーを呼び出します。 gets など、入力バッファーからの読み込みを行う関数のセキュリティで保護されたバージョンでは、最大サイズを指定する必要があります。

  • Null termination. 文字列に終端文字を設定しない可能性がある一部の関数には、確実に文字列を null で終わらせる、セキュリティ保護バージョンがあります。

  • Enhanced error reporting. セキュリティ保護された関数では、以前から存在する関数より詳細なエラー情報を含むエラー コードが返されます。 現在、セキュリティ保護された関数と多くの以前から存在する関数は、errno を設定するため、より詳細なエラー情報を提供する errno コード型も返すことが多いです。

  • Filesystem security. セキュリティで保護されたファイル I/O API では、既定のケースで安全なファイル アクセスをサポートします。

  • Windows security. セキュリティで保護されたプロセス API では、セキュリティ ポリシーが適用され、ACL を指定できます。

  • Format string syntax checking. 無効な文字列が検出されます。たとえば、printf 書式指定文字列の不正な型フィールド文字を使用した場合です。

関連項目

パラメーターの検証
セキュリティ保護されたテンプレート オーバーロード
C ランタイム (CRT) と C++ 標準ライブラリ (STL) .lib ファイル