多くの古い 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 関連の非推奨の警告を無効にします。 詳細については、「互換性」をご覧ください。
その他のセキュリティ機能
一部のセキュリティ機能を次に示します。
パラメーター検証
セキュリティ保護された関数と、その非セキュリティ保護バージョンの多くでは、パラメーターが検証されます。 検証には次のものが含まれます。
-
NULL
値を確認します。 - 列挙値が有効であるかどうかのチェック。
- 整数値が有効な範囲にあるかどうかのチェック。
詳細については、「 パラメーターの検証」を参照してください。
開発者も無効なパラメーターのハンドラーを利用できるようになりました。 アプリケーションをアサートして終了するのではなく、関数が無効なパラメーターを検出した場合、CRT を使用すると、
_set_invalid_parameter_handler
または_set_thread_local_invalid_parameter_handler
を使用してこれらの問題を確認できます。-
バッファ サイズ指定
バッファーに書き込むセキュリティ保護された関数には、バッファー サイズを渡す必要があります。 セキュリティ保護されたバージョンでは、書き込みの前に、バッファーが十分な大きさであることが検証されます。 この検証は、悪意のあるコードの実行を許可する可能性がある、危険なバッファー オーバーラン エラーを回避するのに役立ちます。 通常、これらの関数は、
errno
エラー コードを返し、バッファーのサイズが小さすぎる場合、無効なパラメーター ハンドラーを呼び出します。gets
など、入力バッファーからの読み込みを行う関数のセキュリティで保護されたバージョンでは、最大サイズを指定する必要があります。一部のセキュリティ強化 CRT 関数のデバッグ バージョンでは、渡されたバッファーに特殊文字 (0xFE) が格納されます。 この充填文字により、関数に不適切なサイズが渡された場合に、それを見つけることができます。 残念ながら、性能も低下します。 パフォーマンスを向上させるには、
_CrtSetDebugFillThreshold
を使用してバッファーフィルを無効にします。 詳細と、この動作を持つ関数の一覧については、_CrtSetDebugFillThreshold
を参照してください。Null 終端
終端されていない可能性のある文字列を残した一部の関数にはセキュリティで保護されたバージョンがあり、これにより文字列が正しく null で終了します。
強化されたエラー報告
セキュリティで保護された関数は、既存の関数で使用できるよりも多くのエラー情報を含むエラー コードを返します。 セキュリティで保護された関数と既存の関数の多くは
errno
設定され、多くの場合、errno
コード型も返され、エラー報告が向上します。ファイルシステムのセキュリティ
セキュリティで保護されたファイル I/O API では、既定のケースで安全なファイル アクセスをサポートします。
Windows のセキュリティ
セキュリティで保護されたプロセス API では、セキュリティ ポリシーが適用され、ACL を指定できます。
書式設定文字列の構文チェック
たとえば、正しくない型フィールド文字を使用している場合、書式指定文字列
printf
で無効な文字列が検出されます。
関連項目
パラメーターの検証
テンプレートのオーバーロードをセキュリティで保護する
C ランタイム (CRT) と C++ 標準ライブラリ (STL) .lib
ファイル