WPF 부분 신뢰 보안

일반적으로 악의적인 손상을 방지하기 위해 중요한 시스템 리소스에 직접 액세스하지 않도록 인터넷 애플리케이션을 제한해야 합니다. 기본적으로 HTML 및 클라이언트 쪽 스크립트 언어는 중요한 시스템 리소스에 액세스할 수 없습니다. WPF(Windows Presentation Foundation) 브라우저에서 호스트된 애플리케이션을 브라우저에서 시작할 수 있기 때문에 비슷한 제한 사항 집합을 따라야 합니다. 이러한 제한 사항을 적용하기 위해 WPF는 CAS(코드 액세스 보안) 및 ClickOnce 모두를 사용합니다(WPF 보안 전략 - 플랫폼 보안 참조). 기본적으로 브라우저에서 호스트된 애플리케이션은 인터넷, 로컬 인트라넷 또는 로컬 컴퓨터에서 시작되는지와 관계없이 인터넷 영역 CAS 권한 집합을 요청합니다. 전체 권한 집합보다 적은 권한으로 실행하는 애플리케이션은 부분 신뢰로 실행된다고 할 수 있습니다.

WPF는 가능한 많은 기능을 부분 신뢰로 안전하게 사용할 수 있도록 다양한 지원을 제공하며, CAS와 함께 부분 신뢰 프로그래밍에 대한 추가 지원을 제공합니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

WPF 기능 부분 신뢰 지원

다음 표에는 인터넷 영역 권한 집합의 한도 내에서 사용하기에 안전한 높은 수준의 WPF(Windows Presentation Foundation) 기능이 나열되어 있습니다.

표 1: 부분 신뢰에서 안전한 WPF 기능

기능 영역 기능
일반 브라우저 창

원 사이트 액세스

IsolatedStorage(512KB 제한)

UIAutomation 공급자

명령

IME(입력기)

태블릿 스타일러스 및 잉크

마우스 캡처 및 이동 이벤트를 사용하여 시뮬레이션된 끌어서 놓기

OpenFileDialog

XamlReader.Load를 통한 XAML Deserialization
웹 통합 브라우저 다운로드 대화 상자

사용자가 시작한 최상위 탐색

mailto:links

URI(Uniform Resource Identifier) 매개 변수

HTTPWebRequest

IFRAME에 호스팅되는 WPF 콘텐츠

프레임을 사용하여 동일한 사이트 HTML 페이지 호스팅

WebBrowser를 사용하여 동일한 사이트 HTML 페이지 호스팅

웹 서비스(ASMX)

웹 서비스(Windows Communication Foundation 사용)

스크립팅

문서 개체 모델
시각적 개체 2D 및 3D

애니메이션

미디어(원본 사이트 및 도메인 간)

이미지/오디오/비디오
읽는 중 FlowDocuments

XPS 문서

포함된 시스템 글꼴

CFF & 트루타입 글꼴
편집 맞춤법 검사

RichTextBox

일반 텍스트 및 잉크 클립보드 지원

사용자가 시작한 붙여넣기

선택한 콘텐츠 복사
컨트롤 일반 컨트롤

이 표는 높은 수준의 WPF 기능을 나타냅니다. 자세한 내용은 Windows SDK에서 WPF의 각 멤버에게 필요한 권한을 문서화합니다. 또한 다음 기능에는 특별한 고려 사항을 포함하는 부분 신뢰 실행에 대한 자세한 정보가 있습니다.

다음 표는 인터넷 영역 권한 집합의 한도 내에서 실행하기에 안전하지 않은 WPF 기능의 개요를 나타냅니다.

표 2: 부분 신뢰에서 안전하지 않은 WPF 기능

기능 영역 기능
일반 창(애플리케이션 정의 창 및 대화 상자)

SaveFileDialog

파일 시스템

레지스트리 액세스

끌어서 놓기

XamlWriter.Save를 통한 XAML 직렬화

UIAutomation 클라이언트

소스 창 액세스(HwndHost)

완전한 음성 지원

Windows Forms 상호 운용성
시각적 개체 비트맵 효과

이미지 인코딩
편집 RTF(서식 있는 텍스트) 클립보드

전체 XAML 지원

부분 신뢰 프로그래밍

XBAP 애플리케이션의 경우 기본 권한 집합을 초과하는 코드가 보안 영역에 따라 다르게 동작합니다. 일부 경우에는 사용자가 설치를 시도할 때 경고를 받게 됩니다. 사용자는 설치를 계속하거나 취소하도록 선택할 수 있습니다. 다음 표에서 각 보안 영역의 동작 및 애플리케이션이 완전 신뢰를 받기 위해 수행해야 하는 작업을 설명합니다.

Warning

XBAP를 사용하려면 Internet Explorer 및 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 호출은 보안 예외를 throw합니다. 그렇지 않은 경우 사용 권한이 부여됩니다. 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를 사용한 권한 검사는 권한 단위로 확인해야 할 때 적합한 기술입니다. 이 기술은 일반적인 프로세스의 일부인 예외 감지에 영향을 받으며, 일반적으로 권장되지 않고 성능 문제를 일으킬 수 있습니다. 대신 XBAP(XAML 브라우저 애플리케이션)가 인터넷 영역 샌드박스 내에서만 실행되는 경우 XBAP(XAML 브라우저 애플리케이션)에 대해 true를 반환하는 BrowserInteropHelper.IsBrowserHosted 속성을 사용할 수 있습니다.

Warning

XBAP를 사용하려면 Internet Explorer 및 Firefox와 같은 레거시 브라우저가 작동해야 합니다. 이러한 이전 브라우저 버전은 일반적으로 Windows 10 및 Windows 11에서 지원되지 않습니다. 최신 브라우저는 보안 위험으로 인해 XBAP 앱에 필요한 기술을 더 이상 지원하지 않습니다. XBAP를 사용하도록 설정하는 플러그 인은 더 이상 지원되지 않습니다.

참고 항목

IsBrowserHosted는 애플리케이션이 함께 실행할 권한 집합이 아닌, 애플리케이션이 브라우저에서 실행되는지 여부만 구분합니다.

사용 권한 관리

기본적으로 XBAP는 부분 신뢰(기본 인터넷 영역 권한 집합)를 사용하여 실행합니다. 그러나 애플리케이션의 요구에 따라 기본값에서 권한 집합을 변경할 수 있습니다. 예를 들어, XBAP가 로컬 인트라넷에서 시작되는 경우 다음 표에 나와 있는 향상된 권한 집합을 사용할 수 있습니다.

Warning

XBAP를 사용하려면 Internet Explorer 및 Firefox와 같은 레거시 브라우저가 작동해야 합니다. 이러한 이전 브라우저 버전은 일반적으로 Windows 10 및 Windows 11에서 지원되지 않습니다. 최신 브라우저는 보안 위험으로 인해 XBAP 앱에 필요한 기술을 더 이상 지원하지 않습니다. XBAP를 사용하도록 설정하는 플러그 인은 더 이상 지원되지 않습니다.

표 3: LocalIntranet 및 인터넷 권한

사용 권한 attribute LocalIntranet 인터넷
DNS DNS 서버 액세스
환경 변수 읽기 아니요
파일 대화 상자 열기
파일 대화 상자 제한 없음 아니요
격리된 스토리지 사용자가 어셈블리 격리 아니요
격리된 스토리지 알 수 없는 격리
격리된 스토리지 무제한 사용자 할당량
미디어 안전한 오디오, 비디오 및 이미지
인쇄 기본 인쇄
인쇄 안전 인쇄
반사 내보내기 아니요
보안 관리되는 코드 실행
보안 부여된 권한 어셜션 아니요
사용자 인터페이스 제한 없음 아니요
사용자 인터페이스 안전한 최상위 창
사용자 인터페이스 소유 클립보드
웹 브라우저 HTML 안전 프레임 탐색

참고

잘라내기 및 붙여넣기는 사용자가 시작한 경우 부분 신뢰에서만 허용됩니다.

권한을 높이는 경우 프로젝트 설정 및 ClickOnce 애플리케이션 매니페스트를 변경해야 합니다. 자세한 내용은 WPF XAML 브라우저 애플리케이션 개요를 참조하세요. 다음 문서도 유용할 수 있습니다.

XBAP에서 완전 신뢰가 필요한 경우 동일한 도구를 사용하여 요청된 권한을 높일 수 있습니다. XBAP는 로컬 컴퓨터, 인트라넷 또는 브라우저의 신뢰할 수 있거나 허용된 사이트에 나열된 URL에 설치되고 시작되는 경우에만 완전 신뢰를 받습니다. 인트라넷 또는 신뢰할 수 있는 사이트에서 애플리케이션이 설치되면, 사용자는 상승된 권한을 알리는 표준 ClickOnce 프롬프트를 받습니다. 사용자는 설치를 계속하거나 취소하도록 선택할 수 있습니다.

또는 모든 보안 영역에서 완전 신뢰 배포를 위한 ClickOnce 신뢰 배포 모델을 사용할 수 있습니다. 자세한 내용은 신뢰할 수 있는 애플리케이션 배포 개요보안을 참조하십시오.

참조