次の方法で共有


ゲーム開発におけるセキュリティのベスト プラクティス

この記事では、ゲーム開発で使用するベスト プラクティスについて説明します。

はじめに

ユーザーが作成したコンテンツを使用してオンライン ゲームやゲームをプレイする人が増えています。 これは、Microsoft Windows オペレーティング システムのセキュリティの強化と組み合わせることで、ゲームが増加し、攻撃者が悪用するより魅力的なターゲットであることを意味します。 ゲーム開発者は、リリースするゲームが攻撃者が悪用するための新しいセキュリティ ホールを作成していないことを確認することに重点を置く必要があります。 ゲーム開発者は、悪意のあるネットワーク データ、ユーザーの変更、改ざんによって顧客のコンピューターがハッキングされるのを防ぐのに役立つ責任と既得権を持っています。 脆弱性が悪用されると、顧客や金銭が失われる可能性があります。 この記事では、開発時間を過度に増やすことなくコード のセキュリティを強化するための一般的な方法とツールについて説明します。

製品をリリースするときに開発チームが行った 3 つの最も一般的な間違いは次のとおりです。

  • 管理特権を必要とします。 ゲームには管理者特権は必要ありません。 詳細については、「 ゲーム開発者向けのユーザー アカウント制御」を参照してください。
  • 自動保護を使用していません。 開発者は通常、 /GS/SAFESEH、または /NX を使用していません。 これらのコンパイル/リンク フラグを使用すると、ワークロードを大幅に増加させることなく、多くの基本的なセキュリティ ホールを検出または排除できます。 これらのフラグについては、この記事の後半で説明します。
  • 禁止されている API の使用。 プログラマ エラーが発生しやすく、セキュリティ ホールを簡単に生成する多くの API (strcpystrncpy など) があります。 開発者は、これらの API を安全なバージョンに置き換える必要があります。 Visual Studio 2005 には、安全でない API への参照用にオブジェクト ファイルを自動的にチェックできるバイナリ ファイルを分析するためのツールが付属しています。 このツールで生成された情報の対処方法の詳細については、「Martyn Lovell による Visual Studio 2005 Safe C および C++ ライブラリを使用してコード に対する攻撃を撃退する」を参照してください。 また、禁止された関数をコードから削除するのに役立つ banned.h ヘッダー ファイルを取得することもできます。

一覧表示されている各間違いは一般的なだけでなく、開発ワークロード、コーディング標準、または機能に大きな変更を加えずに簡単に修正できます。

安全でないコードの例

攻撃者がバッファー オーバーラン攻撃を実行できるようにするために必要なすべての簡単な例を次に示します。

void GetPlayerName(char *pDatafromNet)
{
    char playername[256]; 
    strncpy(playername, pDatafromNet, strlen(pDatafromNet));

    // ...
}

表面上、このコードは問題ありません。結局のところ、安全な関数を呼び出します。 ネットワークからのデータは、256 バイトのバッファーにコピーされます。 strncpy 関数は、ソース文字列で NULL 終端記号を検索するか、指定されたバッファー数によって制限されます。 問題は、バッファー サイズが正しくないことです。 ネットワークからのデータが検証されていない場合、またはバッファー サイズが間違っている場合 (この例のように)、攻撃者は、バッファーの終了後にネットワーク パケット内のデータを含むスタック データを上書きする大きなバッファーを提供する可能性があります。 これにより、攻撃者は命令ポインターを上書きし、リターン アドレスを変更することで、任意のコードを実行できます。 この例の最も基本的なレッスンは、入力が検証されるまで信頼しない方法です。

データが最初にネットワークから取得されていなくても、潜在的なリスクがあります。 最新のゲーム開発では、多くのユーザーが同じコード ベースを設計、開発、テストする必要があります。 関数が将来どのように呼び出されるかを知る方法はありません。 常に、データのソースと攻撃者が制御できる内容を自問してください。 ネットワークベースの攻撃が最も一般的ですが、セキュリティ ホールを作成する唯一の方法ではありません。 攻撃者は、セキュリティ ホールを開く方法で mod を作成したり、保存されたファイルを編集したりできますか? ユーザーが提供するイメージファイルとサウンドファイルはどうですか? これらのファイルの悪意のあるバージョンがインターネットに投稿され、顧客にとって危険なセキュリティ リスクが生じる可能性があります。

サイド ノートとして、例を修正するには、 strncpy の代わりに strsafe.h または Safe CRT を使用します。 安全な CRT は、C ランタイムの完全なセキュリティの見直しであり、Visual Studio 2005 の一部が付属しています。 安全な CRT の詳細については、Michael Howard による CRT のセキュリティ強化に 関するページを参照してください。

セキュリティを向上させる方法

開発サイクルでセキュリティを向上させる方法はいくつかあります。 最適な方法を次に示します。

セキュリティに関する読み取り

Michael Howard と David LeBlanc による セキュア コードの執筆 に関する本では、攻撃を防ぎ、悪用を軽減するための戦略と方法について、詳細かつ明確に説明しています。 ネットワーク アプリケーションをセキュリティ保護するための手法のリリースにセキュリティを設計する方法から始めて、ゲーム開発者が攻撃者から自分自身、製品、顧客を保護するために必要なすべての側面について説明します。 この本を使用して、開発スタジオにセキュリティの文化を植え付けることができます。 コードセキュリティを開発者の問題やテスターの問題と考えないでください。 セキュリティは、プログラム マネージャーからデザイナー、開発者、テスト担当者まで、チーム全体がプロジェクトでいつ作業するかを考える必要があると考えてください。 レビュー プロセスの一部である目が多いほど、リリース前にセキュリティ ホールをキャッチする可能性が高くなります。

セキュリティで保護されたコードを記述する Second EditionMicrosoft Press Store で確認でき、より一般的なセキュリティ情報については、Michael Howard による攻撃面の減少による将来の攻撃を防 ぐ方法に関するページを参照してください。

Michael Howard、David LeBlanc、John Viega は、ソフトウェア セキュリティの 19 大罪というタイトルのすべての一般的なオペレーティング システムとプログラミング言語について、別の書籍を執筆しています。

ゲームに重点を置いたセキュリティ プレゼンテーションは、 Microsoft XNA Developer Presentations の ダウンロード ページにあります。

脅威モデリング分析

脅威モデリング分析は、特定の言語やツールではなく、いくつかの会議で実現できる広範なエンドツーエンドの方法で、システムのセキュリティを評価するための優れた方法です。 スレッド モデルを適切に実装すると、プロジェクトに大きなワークロードや会議時間を追加することなく、システムのすべての長所と短所を特定できます。 脅威モデリングの方法では、開発プロセスの前と開発中にシステムセキュリティを評価するという考え方も強調され、最も危険な機能に焦点を当てながら包括的な評価が行われるようにします。 これは、セキュリティのプロファイラーと考えることができます。 特定の言語に基づいていないか、特定のツールに依存しないことで、あらゆるジャンルのプロジェクトに取り組むあらゆる開発スタジオで脅威モデリングを使用できます。 脅威モデリングは、セキュリティは誰の責任であり、他の誰かの問題ではないという考えを補強する優れた方法でもあります。

脅威モデリングの場合は、次の場合に特に注意してください。

  • UDP データ ソース
  • 認証を必要としないデータ ソース
  • 大規模な情報収集の一環として頻繁かつ通常プローブされるデータ ソース
  • クライアントが他のクライアントにデータを直接送信する機能

これらは、セキュリティの弱点の可能性が高い領域です。

脅威モデリングの詳細については、MSDN セキュリティ開発センターの 脅威モデリング と、Frank Swiderski と Window Snyder による 脅威モデリング に関する書籍を参照してください。

データ実行防止 (/NX)

複数の悪用を軽減するための最近のツールは、データ実行防止 (DEP) です。 ビルド コマンドに switch /NX を含める場合、Visual Studio は、コードが実行する権限があるかどうかを示すフラグでメモリ ページをマークします。 EXECUTE 権限でフラグが設定されていないメモリ ページでプログラムを実行しようとすると、プログラムが強制的に終了します。 この防止はプロセッサ レベルで適用され、自己変更コードまたはネイティブ JIT 言語コンパイラを使用している開発者に影響します。 現時点では、AMD の Athlon64 および Opteron プロセッサと Intel の Itanium および最新の Pentium 4 プロセッサのみが実行防止をサポートしていますが、今後、すべての 32 ビットプロセッサと 64 ビット プロセッサで実行防止がサポートされることが期待されています。 (開発者が使用するコピー保護スキームは実行防止の影響を受ける可能性がありますが、Microsoft はコピー保護ベンダーと協力して影響を最小限に抑えています)。DEP を使用することをお勧めします。

DEP の詳細については、「 データ実行防止」を参照してください。

バッファー セキュリティ チェック (/GS) とイメージに安全な例外ハンドラー (/SAFESEH) があります

コンパイラ フラグ /GS で指定されたバッファー セキュリティ チェックと、リンカー フラグ /SAFESEH (Visual Studio .NET 2003 で初めて実装) で指定された Image に安全な例外ハンドラーがある場合、開発者のコードセキュリティ保護の作業が少し簡単になります。

/GS フラグを使用すると、コンパイラは、関数のリターン アドレスを上書きするために悪用される可能性のあるスタックベースのバッファー オーバーランのいくつかの形式のチェックを構築します。 /GS を使用すると、潜在的なすべてのバッファー オーバーランが検出されるわけではなく、キャッチオールと見なされるべきではありませんが、多層防御技術が適しています。

/SAFESEH フラグを使用すると、実行可能ファイルまたは DLL の安全な例外ハンドラーのテーブルも生成できる場合にのみ、実行可能ファイルまたは DLL を生成するようにリンカーに指示されます。 安全な構造化例外処理 (SafeSEH) は、例外がディスパッチされる前に、イメージ ファイル内にある関数テーブルに例外ハンドラーが登録されるようにすることで、バッファー オーバーラン攻撃のターゲットとしての例外処理を排除します。 これらの保護の利点は、Windows XP SP2、Windows Server 2003、Windows Vista、および Windows 7 で有効になります。 また、/SAFESEH が正しく機能するためには、all-or-nothing メソッドで使用する必要があります。 実行可能ファイルまたは DLL にバインドされたコードを含むすべてのライブラリは 、/SAFESEH を使用してコンパイルする必要があります。または、テーブルは生成されません。

バッファー セキュリティ チェック (/GS) とイメージに安全な例外ハンドラー (/SAFESEH) の詳細については、MSDN を参照してください。

Microsoft Visual Studio 2012 の /SDL フラグと Visual Studio 2012 の /GS フラグの機能強化に関する情報も参照してください。

Prefast

PREfast は、コンパイルされた C または C++ の実行パスを分析して実行時のバグを見つけるのに役立つ、Microsoft によって提供される無料のツールです。 PREfast は、すべての関数内のすべての実行パスを操作し、各パスで問題を評価することによって動作します。 当初はドライバーやその他のカーネル コードの開発に使用されていたこのツールは、見つけにくいバグやコンパイラによって無視されるバグを排除することで、ゲーム開発者が時間を節約するのに役立ちます。 PREfast を使用することは、ワークロードを削減し、開発チームとテスト チームの両方の作業に集中する優れた方法です。 PREfast は、Visual Studio Team Suite と Visual Studio Team Edition for Software Developersでコード分析として使用でき、コンパイラ スイッチ /analyze によって有効になります。 (このオプションは、Windows ソフトウェア開発キットに付属するコンパイラの無料バージョンでも使用できます)。

注意

Visual Studio 2012 では、すべてのエディションで /analyze がサポートされています。 Visual Studio のすべてのエディションでのコード分析の可用性の詳細については、「 コード分析の新機能」を参照してください。

 

ヘッダー注釈 (特にバッファー ポインター引数) を使用することで、PREfast では、メモリの上書きバグ、クラッシュの一般的な原因、潜在的なセキュリティの脆弱性など、追加の問題が公開される可能性があります。 これは、標準注釈言語 (SAL) を使用して行われます。これは、予想されるポインター引数のセマンティクスと、長さパラメーター、宣言されたバッファー サイズとの相関関係などに関する追加情報を提供する C/C++ 関数プロトタイプのマークアップの形式です。Windows オペレーティング システムのすべてのヘッダーに注釈が付けられているので、独自のライブラリのパブリック API ヘッダーに SAL マークアップを追加すると、PREfast はこのような API のクライアント コードでより詳細で積極的なチェックを実行できます。 SAL の概要と詳細情報へのリンクについては、Michael Howard のブログ エントリ「標準注釈言語 (SAL) の簡単な概要」を参照してください。

Windows アプリケーション検証ツール

Windows アプリケーション検証ツール (AppVerifier) は、1 つのツールで複数の関数を提供することでテスト担当者を支援できます。 AppVerifier は、一般的なプログラミング エラーをテストしやすくするために開発されたツールです。 AppVerifier では、API 呼び出しに渡されるパラメーターをチェックしたり、エラー処理機能チェック誤った入力を挿入したり、レジストリとファイル システムへの変更をログに記録したりできます。 AppVerifier は、ヒープ内のバッファー オーバーランを検出し、Access Control リスト (ACL) が適切に定義されていることをチェックして、ソケット API の安全な使用を強制することもできます。 網羅的ではありませんが、AppVerifier は、開発スタジオが高品質の製品をリリースするのに役立つテスターのツールボックスの 1 つのツールになります。

アプリケーション検証ツールの詳細については、MSDN の 「アプリケーション検証ツール 」および「 ソフトウェア開発ライフサイクル内でのアプリケーション検証ツールの使用 」を参照してください。

ファジー テスト

ファジー テスト は、現在のテスト手法を強化できる半自動化されたテスト方法です。 ファジーテストの背後にある中心的な考え方は、ランダムなデータを入力してどのような中断を確認することで、すべての入力を完全に評価することです。これには、すべてのネットワークデータ、MOD、保存されたゲームなどが含まれます。ファジーテストは非常に簡単です。 ランダム バイトの挿入、隣接するバイトの反転、または数値の否定によって、整形式のファイルまたはネットワーク データを変更するだけです。 0xff、0xffff、0xffffffff、0x00、0x0000、0x00000000、0x80000000は、ファジー テスト中にセキュリティ ホールを公開するのに適した値です。 AppVerifier を使用して、結果として得られる相互作用の組み合わせを確認できます。 ファジーは網羅的ではありませんが、実装と自動化は簡単で、よりわかりにくい、予測不可能なバグをキャッチできます。

ファジー テストの詳細については、 Gamefest 2007 プレゼンテーション「ゲームセキュリティの実用的な手順」を参照してください。

Authenticode 署名

Authenticode は、ユーザーが受け取る実行可能ファイル、DLL ファイル、および Windows インストーラー パッケージ (.msi ファイル) が、開発者がリリースした内容から変更されないようにする方法です。 Authenticode は、暗号化原則、信頼されたエンティティ、業界標準の組み合わせを使用して、実行可能コンテンツの整合性を検証します。 Microsoft は、署名付きコードの改ざんを自動検出するために使用できる暗号化 API CryptoAPI を提供しています。 リリース後にセキュリティ リークが発生した場合は、証明書を取り消すことができます。その証明書で署名されたすべてのコードは認証を停止します。 証明書を取り消すと、その証明書で署名されたすべてのタイトルの検証が取り消されます。 Windows は Authenticode 署名を使用するように設計されており、特定の状況では、ユーザーの PC が攻撃にさらされる可能性がある署名されていないコードをユーザーに警告します。

Authenticode は、セキュリティの問題を排除する方法ではなく、実行可能ファイルがリリースされた後に改ざんを検出する方法と見なす必要があります。 悪用可能なセキュリティの問題を含む実行可能ファイルまたは DLL は、Authenticode を使用して署名および検証できますが、新しいシステムにセキュリティの問題が引き続き発生します。 製品または更新プログラムがセキュリティで保護されていることが確認された後にのみ、ユーザーが改ざんされていないリリースがあることをユーザーに保証するためにコードに署名する必要があります。

開発者がリリースが変更される脅威がないと感じたとしても、他のテクノロジやサービスは Authenticode に依存しています。 コード署名は統合と自動化が簡単です。開発者がリリースに署名していない理由はありません。

Authenticode 署名の詳細については、「 ゲーム開発者向けの Authenticode 署名」を参照してください。

特権を最小限に抑える

一般に、プロセスは、操作に必要な最小限の特権セットで実行する必要があります。 Windows Vista および Windows 7 では、これは ユーザー アカウント制御を使用して実現され、ゲームを管理者ではなく Standard ユーザーとして実行できます。 Windows XP の場合、通常、ゲームは常に管理者として実行されます。 Windows Vista と Windows 7 でも、特定の操作のために完全な管理者権限に昇格することが必要な場合があります。

プロセスが完全な管理者権限で実行されている場合、通常は Standard ユーザー以外の少数の権限のみが実際に必要です。 管理アクセスには、正当なコードでは必要ない多くの権限が含まれますが、プロセスの弱点を通じて攻撃者が使用する可能性があります。 このような権限の例としては、SE_TAKE_OWNERSHIP、SE_DEBUG、SE_CREATE_TOKEN、SE_ASSIGNPRIMARYTOKEN、SE_TCB、SE_SECURITY SE_LOAD_DRIVER、SE_SYSTEMTIME、SE_BACKUP、SE_RESTORE、SE_SHUTDOWN、SE_AUDITなどがあります ( 「Priviledge 定数」を参照)。

一度開始すると、プロセスはより多くの権限を得ることはできませんが、簡単に権限を放棄できます。 起動時に、プロセスは Win32 API をすぐに使用して、不要な権限を削除できます。

Windows セキュリティ機能を利用する

Windows Vista と Windows 7 には、コードセキュリティを向上させる多くの新機能が含まれています。 ユーザー アカウント制御 は、理解して受け入れるための最も重要なコントロールですが、他にも機能があります。 Windows ファイアウォール、データ実行防止、バッファー セキュリティ チェック、および Windows Vista および Windows 7 でも利用できる安全な例外ハンドラーなどの Windows XP SP2 テクノロジに加えて、次の 3 つの新しいセキュリティ機能を考慮する必要があります。

  • オプトイン アドレス空間レイアウトのランダム化機能。 これは、Visual Studio 2005 Service Pack 1 または Visual Studio 2008 の /DYNAMICBASE オプションを使用してリンクすることで有効になります。 これにより、システムはプロセス空間内の多くの主要なシステム DLL の位置をランダム化するため、インターネット全体に広く伝達される悪用可能な攻撃プログラムを記述することがはるかに困難になります。 このリンカー フラグは、Windows XP および以前のバージョンの Windows では無視されます。
  • ヒープの破損により、セキュリティ攻撃のクラス全体が発生する可能性があるため、Windows Vista と Windows 7 のメモリ システムでは、ヒープの破損が検出された場合にプロセスを終了するモードがサポートされるようになりました。 HeapEnableTermianteOnCorruption を使用して HeapSetInformation を呼び出すと、この動作がオプトインされます。 この呼び出しは、Windows XP 以前のバージョンの Windows では失敗します。
  • サービスを記述する場合は、新しい機能を使用して、実際に必要な特権を指定したり、特定の SID へのリソース アクセスを制限したりするように構成できます。 これは、SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFOとSERVICE_CONFIG_SERVICE_SID_INFOを使用して ChangeSeviceConfig2 を使用して行われます。

まとめ

現在および将来のマーケットプレース向けのゲームの開発には、コストと時間がかかります。 セキュリティの問題を含むゲームをリリースすると、最終的に適切に修正するためのコストと時間が増えます。 そのため、リリース前にセキュリティの悪用を軽減するためのツールと手法を統合することは、すべてのゲーム開発者の利益になります。

この記事の情報は、開発スタジオが自分自身とその顧客を支援するためにできることの概要にすぎません。 一般的なセキュリティ プラクティスとセキュリティ情報の詳細については、 Microsoft Security Developer Center を参照してください。