WPF 部分信頼セキュリティ

一般的に、インターネット アプリケーションでは、悪意による損害を防ぐため、重要なシステム リソースへの直接アクセスを制限する必要があります。 既定では、HTML およびクライアント側のスクリプト言語では、重要なシステム リソースにアクセスできません。 ブラウザーでホストされる Windows Presentation Foundation (WPF) アプリケーションは、ブラウザーから起動できるため、同様の一連の制限に準拠している必要があります。 これらの制限を適用するため、WPF ではコード アクセス セキュリティ (CAS) と ClickOnce の両方が使用されます (詳細については、「WPF のセキュリティ方針 - プラットフォーム セキュリティ」を参照してください)。 既定では、ブラウザーでホストされるアプリケーションは、インターネット、ローカル イントラネット、またはローカル コンピューターのどこから起動するかに関係なく、インターネット ゾーンの一連の CAS 権限が要求されます。 アクセス許可がフルセットで付与されていないアプリケーションは、部分信頼で実行されている、と言います。

WPF には、可能な限り多くの機能を部分信頼で安全にできるようにするさまざまなサポートが用意されています。また、CAS と共に、部分信頼プログラミングのサポートが追加されています。

このトピックは、次のセクションで構成されています。

WPF 機能の部分信頼のサポート

次の表は、インターネット ゾーンのアクセス許可セットの制限内で安全に使用できる Windows Presentation Foundation (WPF) の高度な機能を示しています。

表 1:部分信頼で安全な WPF 機能

機能分野 機能
全般 ブラウザー ウィンドウ

起点サイト アクセス

IsolatedStorage (512KB 制限)

UIAutomation プロバイダー

コマンド実行

入力方式エディター (IME)

タブレットのスタイラスとインク

マウス キャプチャおよび移動イベントを使用した、シミュレートされたドラッグ アンド ドロップ

OpenFileDialog

XAML 逆シリアル化 (XamlReader.Load 経由)
Web 統合 ブラウザーのダウンロード ダイアログ

ユーザーが開始したトップ レベルのナビゲーション

mailto: リンク

Uniform Resource Identifier パラメーター

HTTPWebRequest

IFRAME でホストされている WPF コンテンツ

Frame を使用した同一サイトの HTML ページのホスト

WebBrowser を使用した同一サイトの HTML ページのホスト

Web サービス (ASMX)

Web サービス (Windows Communication Foundation を使用)

[スクリプティング]

ドキュメント オブジェクト モデル
ビジュアル 2D と 3D

アニメーション

メディア (起点サイトとクロス ドメイン)

イメージング/オーディオ/動画
読み取り FlowDocument

XPS ドキュメント

埋め込みフォントとシステム フォント

CFF フォントと TrueType フォント
編集 スペル チェック

RichTextBox

プレーン テキストとインク クリップボードのサポート

ユーザーが開始した貼り付け

選択したコンテンツのコピー
コントロール 一般的なコントロール

この表では、大まかな WPF 機能について説明します。 より詳細な情報については、Windows SDK ドキュメントに記載されている、WPF の各メンバーで必要なアクセス許可を参照してください。 また、次の機能には、特別な考慮事項など、部分的な信頼の実行に関する詳細情報が含まれています。

次の表は、インターネット ゾーンのアクセス許可セットの制限内で実行するのが安全ではない WPF 機能の概要を示しています。

表 2:部分信頼では安全でない WPF 機能

機能分野 機能
全般 ウィンドウ (アプリケーション定義のウィンドウおよびダイアログ ボックス)

SaveFileDialog

ファイル システム

レジストリへのアクセス

ドラッグ アンド ドロップ

XAML シリアル化 (XamlWriter.Save 経由)

UIAutomation クライアント

ソース ウィンドウへのアクセス (HwndHost)

完全な音声サポート

Windows フォームの相互運用性
ビジュアル ビットマップ効果

画像のエンコード
編集 リッチ テキスト形式のクリップボード

完全な XAML サポート

部分信頼プログラミング

XBAP アプリケーションの場合、既定のアクセス許可セットを超えるコードの動作は、セキュリティ ゾーンによって異なります。 ユーザーがアプリケーションをインストールしようとすると警告が表示されることもあります。 ユーザーは、インストールを続行するか取り消すかを選択できます。 次の表は、各セキュリティ ゾーンのアプリケーション動作と、完全な信頼を受け取るアプリケーションで行う必要のある操作を示しています。

警告

XBAP が動作するには、インターネット エクスプローラーや Firefox などの従来のブラウザーが必要です。 これらの古いブラウザー バージョンは、通常、Windows 10 や Windows 11 ではサポートされていません。 最新のブラウザーでは、セキュリティ リスクがあるため XBAP アプリに必要なテクノロジがサポートされなくなりました。 XBAP を有効にするプラグインはサポートされなくなりました。

セキュリティ ゾーン 動作 完全信頼を受け取るための操作
ローカル コンピューター 完全な信頼を自動的に受け取る アクションは必要ありません。
イントラネットおよび信頼済みサイト 完全な信頼のプロンプトを表示する プロンプトにソースが表示されるように、証明書を使用して XBAP に署名します。
インターネット "信頼されていません" というメッセージが表示され、失敗する 証明書を使用して XBAP に署名します。

注意

前の表で説明した動作は、ClickOnce 信頼済み配置モデルに従わない完全な信頼の XBAP の動作です。

一般に、許可されているアクセス許可を超える可能性のあるコードは、おそらく、スタンドアロン アプリケーション間、およびブラウザーでホストされるアプリケーション間の両方で共有される共通コードです。 CAS と WPF は、このシナリオを管理するためのいくつかの手法を提供します。

CAS を使用してアクセス許可を検出する

場合によっては、ライブラリ アセンブリの共有コードをスタンドアロン アプリケーションと XBAP の両方で使用できます。 このような場合、コードによって、アプリケーションに付与されているアクセス許可セットよりも多くのアクセス許可を必要とする機能が実行される可能性があります。 アプリケーションでは、Microsoft .NET Framework セキュリティを使用して特定のアクセス許可があるかどうかを検出できます。 具体的には、必要なアクセス許可のインスタンスで Demand メソッドを呼び出すことによって、特定のアクセス許可があるかどうかをテストできます。 これを次の例に示します。この例には、ファイルをローカル ディスクに保存できるアクセス許可があるかどうかをクエリするコードが含まれています。

using System.IO;
using System.IO.IsolatedStorage;
using System.Security;
using System.Security.Permissions;
using System.Windows;

namespace SDKSample
{
    public class FileHandling
    {
        public void Save()
        {
            if (IsPermissionGranted(new FileIOPermission(FileIOPermissionAccess.Write, @"c:\newfile.txt")))
            {
                // Write to local disk
                using (FileStream stream = File.Create(@"c:\newfile.txt"))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine("I can write to local disk.");
                }
            }
            else
            {
                MessageBox.Show("I can't write to local disk.");
            }
        }

        // Detect whether or not this application has the requested permission
        bool IsPermissionGranted(CodeAccessPermission requestedPermission)
        {
            try
            {
                // Try and get this permission
                requestedPermission.Demand();
                return true;
            }
            catch
            {
                return false;
            }
        }


Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows

Namespace SDKSample
    Public Class FileHandling
        Public Sub Save()
            If IsPermissionGranted(New FileIOPermission(FileIOPermissionAccess.Write, "c:\newfile.txt")) Then
                ' Write to local disk
                Using stream As FileStream = File.Create("c:\newfile.txt")
                Using writer As New StreamWriter(stream)
                    writer.WriteLine("I can write to local disk.")
                End Using
                End Using
            Else
                MessageBox.Show("I can't write to local disk.")
            End If
        End Sub

        ' Detect whether or not this application has the requested permission
        Private Function IsPermissionGranted(ByVal requestedPermission As CodeAccessPermission) As Boolean
            Try
                ' Try and get this permission
                requestedPermission.Demand()
                Return True
            Catch
                Return False
            End Try
        End Function

    }
}
    End Class
End Namespace

アプリケーションに必要なアクセス許可がない場合、Demand を呼び出すと、セキュリティ例外がスローされます。 それ以外の場合は、アクセス許可が付与されています。 IsPermissionGranted はこの動作をカプセル化し、必要に応じて true または false を返します。

機能の適切な低下

コードに必要な操作を実行するためのアクセス許可があるかどうかを検出することは、異なるゾーンから実行できるコードにおいては重要です。 ゾーンを検出することもできますが、可能であれば、ユーザーに代替手段を提供することをお勧めします。 たとえば、完全信頼アプリケーションでは、通常、ユーザーは任意の場所にファイルを作成できますが、一方で部分信頼アプリケーションでは、分離ストレージにのみファイルを作成できます。 ファイルを作成するコードが、完全信頼 (スタンドアロン) アプリケーションと部分信頼 (ブラウザーでホストされる) アプリケーションの両方で共有されるアセンブリに存在し、両方のアプリケーションでユーザーがファイルを作成できるようにする場合は、適切な場所にファイルを作成する前に、共有コードが部分信頼または完全な信頼のどちらで実行されているかどうかを検出する必要があります。 次のコードは、これら両方を示しています。

using System.IO;
using System.IO.IsolatedStorage;
using System.Security;
using System.Security.Permissions;
using System.Windows;

namespace SDKSample
{
    public class FileHandlingGraceful
    {
        public void Save()
        {
            if (IsPermissionGranted(new FileIOPermission(FileIOPermissionAccess.Write, @"c:\newfile.txt")))
            {
                // Write to local disk
                using (FileStream stream = File.Create(@"c:\newfile.txt"))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine("I can write to local disk.");
                }
            }
            else
            {
                // Persist application-scope property to
                // isolated storage
                IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
                using (IsolatedStorageFileStream stream =
                    new IsolatedStorageFileStream("newfile.txt", FileMode.Create, storage))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine("I can write to Isolated Storage");
                }
            }
        }

        // Detect whether or not this application has the requested permission
        bool IsPermissionGranted(CodeAccessPermission requestedPermission)
        {
            try
            {
                // Try and get this permission
                requestedPermission.Demand();
                return true;
            }
            catch
            {
                return false;
            }
        }


Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows

Namespace SDKSample
    Public Class FileHandlingGraceful
        Public Sub Save()
            If IsPermissionGranted(New FileIOPermission(FileIOPermissionAccess.Write, "c:\newfile.txt")) Then
                ' Write to local disk
                Using stream As FileStream = File.Create("c:\newfile.txt")
                Using writer As New StreamWriter(stream)
                    writer.WriteLine("I can write to local disk.")
                End Using
                End Using
            Else
                ' Persist application-scope property to 
                ' isolated storage
                Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
                Using stream As New IsolatedStorageFileStream("newfile.txt", FileMode.Create, storage)
                Using writer As New StreamWriter(stream)
                    writer.WriteLine("I can write to Isolated Storage")
                End Using
                End Using
            End If
        End Sub

        ' Detect whether or not this application has the requested permission
        Private Function IsPermissionGranted(ByVal requestedPermission As CodeAccessPermission) As Boolean
            Try
                ' Try and get this permission
                requestedPermission.Demand()
                Return True
            Catch
                Return False
            End Try
        End Function

    }
}
    End Class
End Namespace

多くの場合、部分信頼の代替を見つけることができるはずです。

イントラネットなどの制御された環境では、カスタム マネージド フレームワークをクライアント ベース全体でグローバル アセンブリ キャッシュ (GAC) にインストールできます。 これらのライブラリでは、完全な信頼を必要とするコードを実行できます。また、AllowPartiallyTrustedCallersAttribute を使用して、部分信頼のみ許可されているアプリケーションから参照できます (詳細については、セキュリティに関する記事と、「WPF のセキュリティ方針 - プラットフォーム セキュリティ」を参照してください)。

ブラウザー ホストの検出

アクセス許可ごとに確認する必要がある場合は、CAS を使用してアクセス許可を確認することが適切な方法です。 ただし、この手法では通常の処理の一部として例外をキャッチすることに依存していますが、これは一般的には推奨されず、パフォーマンスの問題が発生する可能性があります。 代わりに、XAML ブラウザー アプリケーション (XBAP) がインターネット ゾーンのサンドボックス内でのみ実行されている場合は、BrowserInteropHelper.IsBrowserHosted プロパティを使用できます。このプロパティは、XAML ブラウザー アプリケーション (XBAP) に対して true を返します。

警告

XBAP が動作するには、インターネット エクスプローラーや Firefox などの従来のブラウザーが必要です。 これらの古いブラウザー バージョンは、通常、Windows 10 や Windows 11 ではサポートされていません。 最新のブラウザーでは、セキュリティ リスクがあるため XBAP アプリに必要なテクノロジがサポートされなくなりました。 XBAP を有効にするプラグインはサポートされなくなりました。

Note

IsBrowserHosted は、アプリケーションがブラウザーで実行されているかどうかを識別するだけで、アプリケーションで実行されている一連のアクセス許可は識別されません。

アクセス許可の管理

既定では、XBAP は部分信頼 (既定のインターネット ゾーン アクセス許可セット) を使用して実行されます。 ただし、アプリケーションの要件によっては、一連のアクセス許可を既定値から変更することができます。 たとえば、XBAP をローカル イントラネットから起動した場合、次の表に示すように、引き上げられたアクセス許可セットを利用できます。

警告

XBAP が動作するには、インターネット エクスプローラーや Firefox などの従来のブラウザーが必要です。 これらの古いブラウザー バージョンは、通常、Windows 10 や Windows 11 ではサポートされていません。 最新のブラウザーでは、セキュリティ リスクがあるため XBAP アプリに必要なテクノロジがサポートされなくなりました。 XBAP を有効にするプラグインはサポートされなくなりました。

表 3:LocalIntranet とインターネットのアクセス許可

アクセス許可 属性 LocalIntranet インターネット
DNS DNS サーバーへのアクセス はい いいえ
環境変数 読み取り はい いいえ
ファイル ダイアログ 開く はい はい
ファイル ダイアログ 無制限 はい いいえ
分離ストレージ ユーザーによるアセンブリの分離 はい いいえ
分離ストレージ 不明な分離 はい はい
分離ストレージ 無制限のユーザー クォータ はい いいえ
Media 安全なオーディオ、動画、および画像 はい はい
印刷 既定の印刷 はい いいえ
印刷 安全な印刷 はい はい
リフレクション 出力 はい
セキュリティ マネージド コードの実行 はい はい
セキュリティ 付与されたアクセス許可のアサート はい いいえ
ユーザー インターフェイス 無制限 はい いいえ
ユーザー インターフェイス 安全なトップ レベルのウィンドウ はい はい
ユーザー インターフェイス 独自のクリップボード はい はい
Web ブラウザー HTML への安全なフレーム ナビゲーション はい はい

注意

切り取りと貼り付けは、ユーザーが開始したときに部分信頼でのみ許可されます。

アクセス許可を引き上げる必要がある場合は、プロジェクトの設定と ClickOnce アプリケーション マニフェストを変更する必要があります。 詳細については、「WPF XAML ブラウザー アプリケーションの概要」をご覧ください。 次のドキュメントも参照してください。

XBAP で完全な信頼が求められる場合は、同じツールを使用して、要求されたアクセス許可を引き上げることができます。 ただし、XBAP で完全な信頼が許可されるのは、ローカル コンピューター、イントラネット、またはブラウザーの信頼済みサイトまたは許可されたサイトに記載されている URL からこれがインストールされて起動している場合にのみです。 アプリケーションがイントラネットまたは信頼済みサイトからインストールされている場合、ユーザー向けに、アクセス許可が昇格された旨を通知する標準の ClickOnce プロンプトが表示されます。 ユーザーは、インストールを続行するか取り消すかを選択できます。

または、ClickOnce 信頼済みのデプロイ モデルを使用して、任意のセキュリティ ゾーンから完全に信頼された配置を行うことができます。 詳細については、「信頼されたアプリケーションの配置の概要」およびセキュリティに関する記事を参照してください。

関連項目