セキュリティに関する注意事項 (Entity Framework)
このトピックでは、エンティティ フレームワーク アプリケーションの開発、配置、および実行に特有のセキュリティの注意点について説明します。この他に、安全な .NET Framework アプリケーションを作成するための推奨事項にも従うようにしてください。詳細については、「セキュリティの概要 (ADO.NET)」を参照してください。
全般的なセキュリティの注意点
以下のセキュリティの注意点は、エンティティ フレームワーク を使用するすべてのアプリケーションに当てはまります。
信頼できるデータ ソース プロバイダのみを使用する。
データ ソースと通信するためにはプロバイダで次の処理が行われる必要があります。
エンティティ フレームワーク から接続文字列を取得する。
コマンド ツリーをデータ ソースのネイティブ クエリ言語に変換する。
結果セットを組み立てて返す。
ログオン操作の際には、ユーザーのパスワードに基づく情報が、基になるデータ ソースのネットワーク ライブラリを通じてサーバーに渡されます。悪質なプロバイダを使用すると、ユーザーの資格情報を盗まれたり、悪質なクエリを生成されたり、結果セットを改ざんされたりする可能性があります。
接続を暗号化して機密データを保護する。
データの暗号化は エンティティ フレームワーク では直接処理されません。ユーザーがパブリック ネットワーク経由でデータにアクセスする場合は、セキュリティを強化するためにアプリケーションでデータ ソースへの暗号化接続を確立する必要があります。詳細については、データ ソースのセキュリティ関連のドキュメントを参照してください。SQL Server データ ソースの場合は「SQL Server への接続の暗号化」を参照してください。
接続文字列を保護する。
アプリケーションのセキュリティを実現するうえで、データ ソースへのアクセスを保護することは、最も重要な目標の 1 つです。保護されていない接続文字列や適切に作成されていない接続文字列は脆弱性を招く原因になります。接続情報をテキスト形式で保存したり、メモリ内に保持したりすると、システム全体のセキュリティが損なわれる可能性があります。接続文字列を保護するための推奨事項を以下に示します。
SQL Server データ ソースで Windows 認証を使用する。
Windows 認証を使用して SQL Server データ ソースに接続する場合、接続文字列にログオンやパスワードの情報が含まれません。
保護構成を使用して構成ファイル セクションを暗号化する。
ASP.NET には、保護構成と呼ばれる、構成ファイルの機密情報を暗号化するための機能が用意されています。保護構成は、主に ASP.NET を想定して設計されたものですが、Windows アプリケーションの構成ファイル セクションを暗号化する目的でも使用できます。新しい保護構成機能の詳細については、「保護された構成を使用した構成情報の暗号化」を参照してください。
セキュリティで保護された構成ファイルに接続文字列を格納する。
接続文字列はソース コードに埋め込まないようにしてください。接続文字列は構成ファイルに保存でき、そうすることで、アプリケーションのコードに接続文字列を組み込むことを避けられます。Entity Data Model ウィザードでは、接続文字列が既定でアプリケーション構成ファイルに保存されます。不正なアクセスが行われないようにそのファイルをセキュリティで保護してください。
接続を動的に作成する場合は接続文字列ビルダを使用する。
接続文字列を実行時に作成する必要がある場合は EntityConnectionStringBuilder クラスを使用します。この文字列ビルダ クラスは、入力情報を検証して無効な入力情報をエスケープする処理により、接続文字列インジェクション攻撃の防止に役立ちます。詳細については、「EntityConnection の接続文字列を作成する方法 (Entity Framework)」を参照してください。さらに、適切な文字列ビルダ クラスを使用して、エンティティ データ モデル (EDM) 接続文字列の一部であるデータ ソース接続文字列を作成します。ADO.NET プロバイダの接続文字列ビルダについては、「接続文字列ビルダ (ADO.NET)」を参照してください。
詳細については、「接続情報の保護 (ADO.NET)」を参照してください。
信頼できないユーザーに EntityConnection を公開しない。
EntityConnection オブジェクトは、基になる接続の接続文字列を公開します。EntityConnection オブジェクトにアクセスできるユーザーは、基になる接続の ConnectionState を変更することもできます。EntityConnection クラスはスレッド セーフではありません。
接続をセキュリティ コンテキストの外で渡さない。
接続が確立された後にその接続をセキュリティ コンテキストの外で渡さないでください。たとえば、接続を開くためのアクセス許可を持つスレッドが、接続をグローバルな場所に格納することは避けてください。接続がグローバルな場所にあると、アクセス許可を明示的に与えられていない他の悪質なスレッドであっても、この開いている接続を使用することが可能になってしまいます。
メモリ ダンプからログオン情報やパスワードが漏洩する可能性がある。
データ ソースのログオンとパスワードの情報が接続文字列で渡されると、その情報はガベージ コレクションが行われるまでメモリに保持されます。その結果、パスワードの文字列がいつメモリからなくなるのか判定できなくなります。アプリケーションがクラッシュした場合、重要なセキュリティ情報がメモリ ダンプ ファイルに含まれている可能性があります。メモリ ダンプ ファイルは、アプリケーションを実行しているユーザーと、コンピュータに対する管理アクセス権を持つすべてのユーザーが表示できます。Microsoft SQL Server への接続には Windows 認証を使用してください。
データ ソースでは必要なアクセス許可のみをユーザーに与える。
データ ソースの管理者は、必要なアクセス許可のみをユーザーに与えるようにしてください。Entity SQL では、データを変更する DML ステートメント (INSERT、UPDATE、DELETE など) はサポートされていませんが、データ ソースへの接続にアクセスすることはできます。悪質なユーザーによって、その接続を使用してデータ ソースのネイティブ言語で DML ステートメントを実行される可能性があります。
最小限のアクセス許可でアプリケーションを実行する。
マネージ アプリケーションを完全信頼のアクセス許可で実行できるようにすると、.NET Framework でアプリケーションのコンピュータへのアクセスが制限されなくなります。これは、システム全体を危険にさらすセキュリティの脆弱性の原因になります。.NET Framework のコード アクセス セキュリティやその他のセキュリティ メカニズムを使用するには、部分信頼のアクセス許可を使用して、アプリケーションが機能するために必要な最小限のアクセス許可でアプリケーションを実行する必要があります。エンティティ フレームワーク アプリケーションに必要な最小限のアクセス許可を以下に示します。
FileIOPermission: Write (指定されたメタデータ ファイルを開くため) または PathDiscovery (メタデータ ファイルのディレクトリを検索するため)。
ReflectionPermission: RestrictedMemberAccess (LINQ to Entities クエリをサポートするため)。
DistributedTransactionPermission: Unrestricted (System.Transactions の Transaction に参加するため)。
SecurityPermission: SerializationFormatter (ISerializable インターフェイスを使用して例外をシリアル化するため)。
データベース接続を開いたりデータベースに対してコマンドを実行したりするためのアクセス許可 (SQL Server データベースの SqlClientPermission など)。
詳細については、「コード アクセス セキュリティと ADO.NET」を参照してください。
信頼できないアプリケーションをインストールしない。
エンティティ フレームワーク ではセキュリティのアクセス許可が適用されません。ユーザーが指定したデータ オブジェクト コードは、信頼されているかどうかに関係なくインプロセスで呼び出されます。データ ストアとアプリケーションでクライアントの認証および承認が行われるようにしてください。
すべての構成ファイルへのアクセスを制限する。
管理者は、アプリケーションの構成を指定するすべてのファイル (enterprisesec.config、security.config、machine.conf、アプリケーション構成ファイル (<アプリケーション>.exe.config) など) への書き込みアクセスを制限する必要があります。
app.config ではプロバイダの不変名を変更できます。クライアント アプリケーションは、強力な名前を使用して標準のプロバイダ ファクトリ モデルを通じて基になるプロバイダにアクセスする責任を負う必要があります。
Entity Data Model ファイルとマッピング ファイルへのアクセス許可を制限する。
管理者は、モデル ファイルとマッピング ファイル (.csdl、.ssdl、および .msl) への書き込みアクセスを、モデルやマッピングを変更するユーザーのみに制限する必要があります。エンティティ フレームワーク で実行時に必要なのは、これらのファイルへの読み取りアクセスだけです。そのほか、エンティティ データ モデル ツールによって生成されるオブジェクト レイヤとプリコンパイル ビューのソース コード ファイルへのアクセスを制限する必要もあります。
クエリのセキュリティに関する注意点
EDM のクエリを実行する際には次の点に注意する必要があります。これらの注意点は、EntityClient を使用する Entity SQL クエリと、LINQ、Entity SQL、およびクエリ ビルダ メソッドを使用するオブジェクト クエリに当てはまります。
SQL インジェクション攻撃を防止する。
アプリケーションによっては (ユーザーや他の外部エージェントからの) 外部入力を受け取り、その入力内容に応じた処理を実行する場合があります。直接、間接を問わず、ユーザーまたは外部エージェントから受け取った入力には、対象言語の構文を巧みに利用して不正なアクションを実行する内容が含まれている可能性があります。対象言語が Transact-SQL などの構造化照会言語 (SQL) である場合、この操作は SQL インジェクション攻撃と呼ばれます。悪質なユーザーによって、クエリに直接コマンドを挿入してデータベースのテーブルを削除されたり、サービス拒否の状態を引き起こされたり、本来実行されるべき操作を改変されたりする可能性があります。
Entity SQL インジェクション攻撃 :
Entity SQL では、クエリ述語やパラメータ名で使用される値に悪質な入力を渡すことによって SQL インジェクション攻撃が行われる可能性があります。SQL インジェクションが行われないようにするため、ユーザー入力を Entity SQL コマンド テキストと組み合わせないようにしてください。
Entity SQL クエリでは、リテラルを渡すことのできる場所であればどこででもパラメータを渡すことができます。外部エージェントから受け取ったリテラルを直接クエリに挿入することは避け、パラメータ化クエリを使用するようにしてください。
LINQ to Entities インジェクション攻撃 :
LINQ to Entities 内でクエリを構築することは可能ですが、オブジェクト モデルの API を介して構築します。Entity SQL クエリとは異なり、LINQ to Entities のクエリは、構築に文字列操作や文字列連結は使用されません。このため、通常の SQL インジェクション攻撃に十分な抵抗力を持っていると言えます。
非常に大きな結果セットを使用しないようにする。
非常に大きな結果セットを使用すると、消費されるリソースが結果セットのサイズに比例して増加する操作を実行する場合にクライアント システムがシャットダウンする可能性があります。次のような状況では、予想外に大きな結果セットが生成されることがあります。
適切なフィルタ条件が含まれていない、大きなデータベースに対するクエリ。
サーバーで Cartesian Join を作成するクエリ。
入れ子になった Entity SQL クエリ。
ユーザー入力を受け取るときには、その入力によって結果セットがシステムで処理しきれないほど大きくならないことを確認する必要があります。LINQ to Entities の Take メソッドや Entity SQL の LIMIT 演算子を使用して結果セットのサイズを制限することもできます。
Object Services のセキュリティに関する注意点
エンティティ型を生成したり操作したりする際には次の点に注意する必要があります。
ObjectContext を複数のアプリケーション ドメインで共有しない。
ObjectContext を複数のアプリケーション ドメインで共有すると接続文字列の情報が漏洩する可能性があります。代わりに、シリアル化したオブジェクトやオブジェクト グラフをもう一方のアプリケーション ドメインに転送して、そのアプリケーション ドメインでそれらのオブジェクトを ObjectContext にアタッチするようにしてください。詳細については、「オブジェクトのシリアル化 (Entity Framework)」を参照してください。
型の安全性違反を防止する。
型の安全性違反が発生すると、Object Services でオブジェクトのデータの整合性が保証されなくなります。型の安全性違反は、信頼できないアプリケーションを完全信頼のコード アクセス セキュリティで実行できるようにすると発生する可能性があります。
ホストされるアプリケーションで例外を処理する。
ASP.NET などのホスト環境では try-catch ブロック内で ObjectContext のメソッドやプロパティにアクセスする必要があります。例外をキャッチすると、未処理の例外によって ObjectStateManager のエントリがアプリケーションのユーザーに公開される状況を防ぐことができます。
ASP.NET アプリケーションのセキュリティに関する注意点
ASP.NET アプリケーションでパスを操作する際には次の点に注意する必要があります。
ホストでパスがチェックされるかどうかを確認する。
|DataDirectory| という (パイプ記号で囲まれた) 置換文字列を使用すると、解決されたパスがサポートされているかどうかが ADO.NET によって確認されます。たとえば、DataDirectory の後に ".." を使用することはできません。Web アプリケーション ルート演算子 (~) の解決では、ASP.NET をホストするプロセスによってこれと同じチェックが行われます。IIS ではこのチェックが行われますが、IIS 以外のホストでは、解決されたパスがサポートされているかどうかが確認されない可能性があります。エンティティ フレームワーク アプリケーションを配置するホストの動作を把握しておく必要があります。
解決されるパス名を想定しない。
ルート演算子 (~) と DataDirectory 置換文字列が解決される値は、アプリケーションの実行中に変化しない状態で維持される必要がありますが、ホストでそれらの値の変更が エンティティ フレームワーク によって制限されるわけではありません。
配置の前にパスの長さを確認する。
エンティティ フレームワーク アプリケーションを配置する前に、ルート演算子 (~) と DataDirectory 置換文字列の値がオペレーティング システムのパスの長さの制限を超えないことを確認する必要があります。ADO.NET データ プロバイダではパスの長さの確認は行われません。
ADO.NET メタデータのセキュリティに関する注意点
EDM のモデル ファイルとマッピング ファイルを生成したり操作したりする際には次の点に注意する必要があります。
機密情報がログによって公開されないようにする。
ADO.NET メタデータ サービス コンポーネントでは個人情報はログに記録されません。アクセス制限のために返すことのできない結果があった場合は、データベース管理システムやファイル システムで例外を生成する代わりに 0 個の結果を返す必要があります。例外には機密情報が含まれる可能性があります。
信頼されていないソースから MetadataWorkspace オブジェクトを受け取らない。
信頼されていないソースから MetadataWorkspace クラスのインスタンスをアプリケーションで受け取らないようにしてください。代わりに、それらのソースから明示的にワークスペースを作成および設定する必要があります。
参照
概念
配置に関する注意事項 (Entity Framework)
移行に関する注意事項 (Entity Framework)