セキュリティに関する考慮事項: Microsoft Windows シェル

このトピックでは、Windows シェルに関連するセキュリティに関する考慮事項について説明します。 このドキュメントでは、セキュリティの問題について知る必要があるすべてを提供することはできません。代わりに、この特定のテクノロジ領域の開始点とリファレンスとして使用してください。

シェルは、適切に処理されない場合に潜在的なセキュリティ リスクを提示するいくつかの要素を含む、システムのさまざまな重要な側面を制御します。 このトピックでは、より一般的な問題の一部と、アプリケーションでそれらを対処する方法について説明します。 セキュリティはインターネットベースの悪用に限定されないことに注意してください。 ターミナル サービスを介してアクセスできるシステムを含む共有システムでは、システムを共有する他のユーザーに損害を与える可能性のある操作をユーザーが実行できないようにする必要もあります。

アプリケーションを正しくインストールする

シェルのセキュリティに関する潜在的な問題の大部分は、アプリケーションを正しくインストールすることで軽減できます。

  • Program Files フォルダーの下にアプリケーションをインストールします。

    オペレーティング システム 場所
    Windows XP、Windows Server 2003 以前 CSIDL_PROGRAM_FILES
    Windows Vista 以降にのみ適用される FOLDERID_ProgramFiles、FOLDERID_ProgramFilesX86、FOLDERID_ProgramFilesX64、FOLDERID_ProgramFilesCommon、FOLDERID_ProgramFilesCommonX86、またはFOLDERID_ProgramFilesCommonX64。 詳細については、「 KNOWNFOLDERID 」を参照してください。

     

  • Program Files フォルダーの下にユーザー データを格納しないでください。

    すべてのユーザーに共通するデータには、適切なデータ フォルダーを使用します。

    オペレーティング システム 場所
    Windows XP、Windows Server 2003 以前 CSIDL_COMMON_APPDATA
    Windows Vista 以降にのみ適用される FOLDERID_ProgramData

     

    特定のユーザーに属するデータには、適切なユーザー データ フォルダーを使用します。

    オペレーティング システム 場所
    Windows XP、Windows Server 2003 以前 CSIDL_APPDATA、CSIDL_PERSONALなど。
    Windows Vista 以降にのみ適用される FOLDERID_RoamingAppData、FOLDERID_Documentsなど。

     

  • Program Files フォルダー以外の場所にインストールする必要がある場合は、ユーザーがファイル システムの不適切な部分にアクセスできないように、アクセス制御リスト (ACL) を適切に設定してください。 特定のユーザーに固有のデータには、他のユーザーがアクセスできないようにする ACL が必要です。

  • ファイルの関連付けを設定するときは、必ずコマンド ラインを正しく指定してください。 完全修飾パスを使用し、空白を含む要素を引用符で囲みます。 コマンド パラメーターを個別の引用符で囲みます。 そうしないと、文字列が正しく解析されず、アプリケーションが正しく起動しない可能性があります。 適切な形式のコマンド ラインの 2 つの例を次に示します。

    "C:\Program Files\MyApp\MyApp.exe" "%1" "%2"
    C:\MyAppDir\MyApp\MyApp.exe "%1"
    

注意

標準インストール フォルダーの場所は、システムによって異なる場合があります。 特定の Windows Vista 以降のシステム上の標準フォルダーの場所を取得するには、適切な KNOWNFOLDERID 値を指定して SHGetKnownFolderPath を呼び出します。 Windows XP、Windows Server 2003 以前のシステムでは、適切な CSIDL 値を使用して SHGetFolderLocation または SHGetFolderPath を呼び出します。

 

Shlwapi

Shell Lightweight API (Shlwapi) には、いくつかの文字列操作関数が含まれています。 これらの関数を誤って使用すると、予期せず文字列が切り捨てられ、切り捨てが返されるという通知を受け取らない可能性があります。 次の場合は、Shlwapi 関数を使用しないでください。 リスクの少ない代替関数を代わりに使用する必要があります。

Shlwapi 関数 代替関数
StrCatStrNCat StringCchCatStringCbCat 、および関連する関数
StrCpyStrCpyN StringCchCopyStringCbCopy 、および関連する関数
wnsprintfwvnsprintf StringCchPrintfStringCbPrintf 、および関連する関数

 

ファイル パスを返す PathRelativePathTo などの関数では、常にバッファーのサイズをMAX_PATH文字に設定します。 これにより、バッファーが最大のファイル パスと終端の null 文字を保持するのに十分な大きさになります。

代替文字列関数の詳細については、「 Strsafe.h について」を参照してください。

オートコンプリート

パスワードにオートコンプリート機能を使用しないでください。

アプリケーションの起動に使用できるシェル関数には、 ShellExecuteShellExecuteExWinExecSHCreateProcessAsUserW があります。 実行するアプリケーションの明確な定義を指定してください。

  • 実行可能ファイルのパスを指定する場合は、完全修飾パスを指定します。 シェルに依存してファイルを見つけないでください。
  • 空白を含むコマンド ライン文字列を指定する場合は、文字列を引用符で囲みます。 それ以外の場合、パーサーはスペースを含む 1 つの要素を複数の要素として解釈する可能性があります。

ファイルの移動とコピー

システム セキュリティの 1 つのキーは、ACL を適切に割り当てることです。 暗号化されたファイルを使用することもできます。 ファイルを移動またはコピーするときに、正しい ACL が割り当てられ、誤って復号化されていないことを確認します。 これには、ファイルシステム内だけでなく、 ごみ箱へのファイルの移動も含まれます。 IFileOperation (Windows Vista 以降) または SHFileOperation (Windows XP 以前) を使用します。 MoveFile を使用しないでください。これは、宛先ファイルに対して想定される ACL が設定されていない可能性があります。

セキュリティで保護された名前空間拡張機能の記述

シェル名前空間拡張機能は、ユーザーにデータを表示するための強力で柔軟な方法です。 ただし、正しく書き込まれていない場合は、システム エラーが発生する可能性があります。 注意すべきいくつかの重要なポイント:

  • 画像などのデータが正しく書式設定されていると想定しないでください。
  • MAX_PATHが文字列内の バイト 数と等しいと想定しないでください。 文字数です

セキュリティ アラート

次の表は、誤って使用した場合にアプリケーションのセキュリティを侵害する可能性のある一部の機能を示しています。

特徴量 対応策
ShellExecuteShellExecuteEx 特定のファイルを見つけるために一連の既定の場所をチェックすることに依存する検索は、スプーフィング攻撃で使用できます。 完全修飾パスを使用して、目的のファイルに確実にアクセスします。
StrCat 最初の引数 psz1 は、 psz2 と終了 '\0' を保持するのに十分な大きさにする必要があります。そうしないと、バッファー オーバーランが発生する可能性があります。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatN、または StringCchCatNEx
StrCatBuff 最後の文字列は、null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatN、または StringCchCatNEx
StrCatChainW 最後の文字列は、null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCatExStringCbCatNExStringCchCatEx、または StringCchCatNEx
Strcpy 最初の引数 psz1 は、 psz2 と終了 '\0' を保持するのに十分な大きさにする必要があります。そうしないと、バッファー オーバーランが発生する可能性があります。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyN、または StringCchCopyNEx
StrCpyN コピーされた文字列は、null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyNStringCchCopyNEx
StrDup StrDup では、 lpsz が null で終わる文字列であると見なされます。 また、返される文字列は null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCatStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyN、または StringCchCopyNEx
StrNCat 最初の引数 pszFront は、 pszBack と終了 '\0' を保持するのに十分な大きさにする必要があります。そうしないと、バッファー オーバーランが発生する可能性があります。 最後の引数 cchMaxpszFront にコピーする文字数であり、 pszFront のサイズ (バイト単位) とは限らないことに注意してください。 代わりに、次のいずれかの代替手段を使用してください。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatN、または StringCchCatNEx
wnsprintf コピーされた文字列は、null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintf、または StringCchVPrintfEx
wvnsprintf コピーされた文字列は、null で終わる保証はありません。 代わりに、次のいずれかの代替手段を使用してください。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintf、または StringCchVPrintfEx

 

Microsoft Security

セキュリティ デベロッパー センター

Microsoft Solution Accelerator に関するページ

セキュリティ TechCenter

Strsafe.h について