セキュリティに関する考慮事項: Windows ユーザー インターフェイス
このトピックでは、Windows ユーザー インターフェイスのセキュリティに関する考慮事項について説明します。 このトピックでは、セキュリティの問題について知る必要があるすべてを提供するわけではありません。 代わりに、このテクノロジ領域の開始点と参照として使用してください。
コンピューターの相互接続性の向上に伴い、開発者はアプリケーションのセキュリティに関心を持つ必要があります。 ただし、セキュリティにより、一般的なアプリケーションの安全性と堅牢性も向上します。したがって、開発者が優れたユーザー エクスペリエンスを提供できるもう 1 つの方法です。 次のトピックでは、Windows ユーザー インターフェイスを使用するときの潜在的なセキュリティ上の問題について説明します。
文字列に関する考慮事項
多くの関数、メッセージ、マクロでは、パラメーターに文字列が使用されます。 ただし、多くの場合、文字列は null 終端または長さについてはチェックされません。 関連する問題は、文字列またはバッファーの長さを誤って計算することです。 どちらの場合も、バッファー オーバーフローやデータの切り捨てにつながる可能性があり、アプリケーションに悪影響を及ぼす可能性があります。 バッファー オーバーランとその他のセキュリティ上の懸念事項の詳細については、Michael Howard と David Leblanc、Microsoft Press、2002 セキュリティ で保護されたコード の記述に関するページを参照してください。
文字列を安全な方法で処理するには、次の操作を行う必要があります。
- 必要に応じて、文字列の null 終端または適切な長さを確認します。
- 特に TCHAR 値が含まれている場合は特に、文字列またはバッファーの長さを判断 注意してください。
- 文字列を作成する場合、または以前に使用した文字列を使用する場合は、必要に応じてゼロに初期化するか、null 終端記号を挿入します。
さらに、文字列を処理する場合は、StrSafe 関数を使用することを検討してください。 これらの関数は、文字列を安全に処理するように設計されています。
ユーザー入力
Windows ユーザー インターフェイスは、ユーザーからの情報の取得と応答に関係しています。 ただし、正しくないデータを入力したユーザーは、アプリケーションを中断する可能性があります。 したがって、カーディナル ルールは、すべての入力を検証する必要があるということです。
主な懸念事項は文字列データであり、文字列に関する考慮事項 で説明されています。 ただし、アプリケーションで使用する前に、すべての種類の入力を検証する必要があります。 もう 1 つの懸念事項は、ある時点でデータが検証されるが、使用される前に変更される場合 (たとえば、テキストの長さを示すメッセージを受信する場合) です。 そのため、データが変更される可能性がある場合は、使用する直前にデータを確認する必要があります
セキュリティ アラート
次の表に、誤って使用するとアプリケーションのセキュリティを侵害する可能性がある機能を示します。
特徴 | 緩和 |
---|---|
GetAtomNameをする | バッファーのサイズを指定するときは注意してください。 |
GlobalGetAtomName | グローバル文字列アトムは、任意のアプリケーションからアクセスできます。 ただし、別のアプリケーションが不注意な場合は、参照カウントを誤って処理して削除する可能性があります。 代わりにグローバル整数の原子を使用することを検討してください。 |
ImpersonateDdeClientWindowの | 関数が失敗した場合、後続のクライアント要求は呼び出し元プロセスのセキュリティ コンテキストで行われます。 これは、呼び出し元のプロセスが高い特権アカウントとして実行されている場合に問題になる可能性があります。 したがって、呼び出しが失敗した場合やエラーが発生した場合は、クライアント要求の実行を続行しないでください。 |
DdeImpersonateClient | 関数が失敗した場合、後続のクライアント要求は呼び出し元プロセスのセキュリティ コンテキストで行われます。 これは、呼び出し元のプロセスが高い特権アカウントとして実行されている場合に問題になる可能性があります。 したがって、呼び出しが失敗した場合やエラーが発生した場合は、クライアント要求の実行を続行しないでください。 |
GetClipboardFormatNameの | lpszFormatName バッファーの適切なサイズを誤って計算すると、特にアプリケーションが ANSI と Unicode の両方のバージョンで使用されている場合、バッファー オーバーフローが発生する可能性があります。 また、文字列が cchMaxCount パラメーターより長い場合は切り捨てられ、情報が失われる可能性があることに注意してください。 |
GetMenuStringをする | lpString パラメーターは TCHAR バッファーであり、nMaxCount は、TCHARのメニュー文字列の長さです。 これらのパラメーターのサイズを誤って設定すると、メニュー文字列の長さが文字で示される可能性があります。 これらのパラメーターのサイズを誤ると、文字列が切り捨てられ、データが失われる可能性があります。 |
GetStringTypeA、 GetStringTypeEx、 GetStringTypeW | バッファー オーバーフローを回避するには、lpCharType バッファーのサイズを正しく設定します。 |
LoadLibrary | LoadLibrary を誤って使用すると、間違った DLL を読み込むことで、アプリケーションのセキュリティが損なわれる可能性があります。 |
LoadString | 不適切な使用には、nBufferMax パラメーターに間違ったサイズを指定する方法が含まれます。 たとえば、sizeof(lpBuffer) はバッファーのサイズをバイト単位で指定します。これは、Unicode バージョンの関数のバッファー オーバーフローにつながる可能性があります。 バッファー オーバーフローの状況は、アプリケーションのセキュリティに関する多くの問題の原因です。 この場合、sizeof(lpBuffer)/sizeof(TCHAR) を使用すると、バッファーの適切なサイズが得られます。 |
lstrcatをする | この関数は、構造化例外処理 (SEH) を使用して、アクセス違反やその他のエラーをキャッチします。 この関数は、SEH エラーをキャッチすると、文字列 null で終了せずに NULL を返し、NULL を指定せずに文字列を終了し、呼び出し元にエラーを通知しません。 呼び出し元は、十分な領域がエラー状態であると想定しても安全ではありません。 lpString1 最初の引数は、lpString2 と終了 '\0' 保持するのに十分な大きさである必要があります。それ以外の場合は、バッファー オーバーランが発生する可能性があります。 バッファー オーバーランは、アクセス違反が発生した場合に、アプリケーションに対するサービス拒否攻撃につながる可能性があります。 最悪の場合、バッファー オーバーランにより、特に lpString1 がスタック ベースのバッファーである場合に、攻撃者が実行可能コードをプロセスに挿入する可能性があります。 次のいずれかの方法を使用することを検討してください。 StringCbCatまたは stringCchCatをします。 |
lstrcpyをする | この関数は、構造化例外処理 (SEH) を使用して、アクセス違反やその他のエラーをキャッチします。 この関数は、SEH エラーをキャッチすると、文字列 null で終了せずに NULL を返し、NULL を指定せずに文字列を終了し、呼び出し元にエラーを通知しません。 呼び出し元は、十分な領域がエラー状態であると想定しても安全ではありません。 lpString1 最初の引数は、lpString2 と終了 '\0' 保持するのに十分な大きさである必要があります。それ以外の場合は、バッファー オーバーランが発生する可能性があります。 バッファー オーバーランは、アクセス違反が発生した場合に、アプリケーションに対するサービス拒否攻撃につながる可能性があります。 最悪の場合、バッファー オーバーランにより、特に lpString1 がスタック ベースのバッファーである場合に、攻撃者が実行可能コードをプロセスに挿入する可能性があります。 代わりに、StringCchCopy を使用することを検討してください。 |
lstrcpynをする | この関数は、構造化例外処理 (SEH) を使用して、アクセス違反やその他のエラーをキャッチします。 この関数は、SEH エラーをキャッチすると、文字列 null で終了せずに NULL を返し、NULL を指定せずに文字列を終了し、呼び出し元にエラーを通知しません。 呼び出し元は、十分な領域がエラー状態であると想定しても安全ではありません。 lpString1 コピーした文字列を格納するのに十分な大きさでない場合は、バッファー オーバーランが発生する可能性があります。 また、文字列全体をコピーする場合、sizeof は WCHAR ではなくバイト数を返します。sizeof は、この関数の Unicode バージョンでは正しくない文字ではなくバイト数を返します。 バッファー オーバーランは、アクセス違反が発生した場合に、アプリケーションに対するサービス拒否攻撃を引き起こす可能性があります。 最悪の場合、バッファー オーバーランにより、特に lpString1 がスタック ベースのバッファーである場合に、攻撃者が実行可能コードをプロセスに挿入する可能性があります。 代わりに、StringCchCopy を使用することを検討してください。 |
lstrlenをする | lstrlenは、lpString が null で終わる文字列であると想定しています。 そうでない場合は、バッファー オーバーランやアプリケーションに対するサービス拒否攻撃につながる可能性があります。 次のいずれかの方法を使用することを検討してください。 StringCbLength または StringCchLengthします。 |
wsprintfをする | lpOut で返される文字列は、null で終わるとは限りません。 また、%s 形式を使用しないでください。バッファー オーバーランが発生する可能性があります。 アクセス違反が発生すると、アプリケーションに対するサービス拒否が発生します。 さらに悪いケースでは、攻撃者は実行可能コードを挿入できます。 次のいずれかの方法を使用することを検討してください。 StringCbPrintf、 stringCbPrintfEx、 StringCbVPrintf、 StringCbVPrintfEx、 StringCchPrintf、StringCchPrintfEx、StringCchVPrintf、または StringCchVPrintfExをします。 |
wvsprintf | lpOutput で返される文字列は、null で終わるとは限りません。 また、バッファー オーバーランにつながる可能性がある %s 形式の使用は避けてください。 これにより、アクセス違反が発生した場合や、攻撃者が実行可能コードを挿入する可能性がある場合、サービス拒否につながる可能性があります。 次のいずれかの方法を使用することを検討してください。 StringCbPrintf、 stringCbPrintfEx、 StringCbVPrintf、 StringCbVPrintfEx、 StringCchPrintf、StringCchPrintfEx、StringCchVPrintf、または StringCchVPrintfExをします。 |
関連トピック