WPF 부분 신뢰 보안

일반적으로 악의적인 손상을 방지하기 위해 인터넷 응용 프로그램은 중요한 시스템 리소스에 직접 액세스하는 것이 제한되어야 합니다. 기본적으로 HTML 및 클라이언트 쪽 스크립팅 언어에서는 중요한 시스템 리소스에 직접 액세스할 수 없습니다. 브라우저에서 호스팅되는 Windows Presentation Foundation (WPF) 응용 프로그램은 브라우저에서 시작할 수 있으므로 일련의 유사한 제한을 따라야 합니다. 이러한 제한을 적용하기 위해 WPF는 Code Access Security (CAS) 및 ClickOnce를 모두 사용합니다(WPF 보안 전략 - 플랫폼 보안 참조). 기본적으로 브라우저에서 호스팅되는 응용 프로그램은 인터넷에서 시작했는지, 로컬 인트라넷에서 시작했는지, 아니면 로컬 컴퓨터에서 시작했는지에 관계없이 인터넷 영역 CAS 권한 집합을 요청합니다. 전체 권한 집합보다 적은 권한으로 실행되는 응용 프로그램을 부분 신뢰 수준으로 실행된다고 말합니다.

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

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

  • WPF 기능 부분 신뢰 지원

  • 부분 신뢰 프로그래밍

  • 권한 관리

WPF 기능 부분 신뢰 지원

다음 표에서는 인터넷 영역 권한 집합의 제한 내에서 안전하게 사용할 수 있는 Windows Presentation Foundation (WPF)의 상위 수준 기능을 보여 줍니다.

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

기능 영역

기능

일반

브라우저 창

원본 사이트 액세스

IsolatedStorage(512KB 한도)

UIAutomation 공급자

명령

IME(입력기)

태블릿 스타일러스 및 잉크

마우스 캡처 및 이동 이벤트를 사용한 시뮬레이션된 끌기/놓기

OpenFileDialog

XamlReader.Load를 통한 XAML Deserialization

웹 통합

브라우저 다운로드 대화 상자

사용자가 시작하는 최상위 탐색

mailto:links

Uniform Resource Identifier 매개 변수

HTTPWebRequest

IFRAME에서 호스팅되는 WPF 콘텐츠

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

웹 브라우저를 사용하여 동일한 사이트 HTML 페이지 호스팅

웹 서비스(ASMX)

웹 서비스(Windows Communication Foundation 사용)

스크립팅

문서 개체 모델

시각적 표시

2D 및 3D

애니메이션

미디어(원본 사이트 및 크로스 도메인)

이미징/오디오/비디오

읽기

FlowDocuments

XPS 문서

포함 및 시스템 글꼴

CFF 및 트루타입 글꼴

편집

맞춤법 검사

RichTextBox

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

사용자가 시작한 붙여넣기

선택한 콘텐츠 복사

컨트롤

일반 컨트롤

이 표에서는 상위 수준의 WPF 기능을 보여 줍니다. WPF의 각 멤버에 필요한 권한이 문서화되어 있는 Windows Software Development Kit (SDK)에서 자세한 내용을 확인할 수 있습니다. 또한 다음 기능에서는 부분 신뢰 실행과 관련된 더 자세한 정보를 제공하고 특별히 고려해야 할 사항도 설명합니다.

다음 표에서는 인터넷 영역 권한 집합의 제한 내에서 실행하는 것이 안전하지 않은 WPF 기능을 보여 줍니다.

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

기능 영역

기능

일반

창(응용 프로그램에서 정의한 창 및 대화 상자)

SaveFileDialog

파일 시스템

레지스트리 액세스

끌어서 놓기

XamlWriter.Save를 통한 XAML Serialization

UIAutomation 클라이언트

소스 창 액세스(HwndHost)

완전한 음성 지원

Windows Forms 상호 운용성

시각적 표시

비트맵 효과

이미지 인코딩

편집

서식있는 텍스트 형식 클립보드

완전한 XAML 지원

부분 신뢰 프로그래밍

XBAP 응용 프로그램의 경우 기본 권한 집합을 초과하는 코드는 보안 영역에 따라 다르게 동작하게 됩니다. 설치하려고 시도할 때 경고가 발생하는 경우도 있습니다. 사용자는 설치를 계속하거나 취소하도록 선택할 수 있습니다. 다음 표에서는 각 보안 영역에 대한 응용 프로그램 동작과 응용 프로그램에서 완전 신뢰를 받기 위해 수행해야 하는 작업에 대해 설명합니다.

보안 영역

동작

완전 신뢰 얻기

로컬 컴퓨터

자동 완전 신뢰

아무런 작업도 수행할 필요가 없습니다.

인트라넷 및 신뢰할 수 있는 사이트

완전 신뢰 확인

사용자가 프롬프트에서 소스를 볼 수 있도록 인증서로 XBAP에 서명합니다.

Internet

"신뢰할 수 없음"이라는 메시지가 표시되고 실패함

인증서로 XBAP에 서명합니다.

참고참고

위의 표에서 설명한 동작은 신뢰할 수 있는 ClickOnce 배포 모델을 따르지 않는 완전 신뢰 XBAP에 대한 동작입니다.

일반적으로 허용되는 권한을 초과할 수 있는 코드는 독립 실행형 응용 프로그램과 브라우저에서 호스팅되는 응용 프로그램 사이에서 공유되는 공용 코드입니다. CAS 및 WPF에서는 이 시나리오를 관리하기 위한 여러 기술이 제공됩니다.

CAS를 사용하여 권한 탐지

라이브러리 어셈블리의 공유 코드를 독립 실행형 응용 프로그램 및 XBAPs 모두에서 사용할 수 있는 경우가 있습니다. 이러한 경우 코드는 응용 프로그램의 부여된 권한 집합에서 허용되는 것보다 많은 권한이 필요한 기능을 실행할 수 있습니다. 응용 프로그램은 Microsoft .NET Framework 보안을 실행하여 특정 권한을 갖고 있는지 여부를 탐지할 수 있습니다. 특히 원하는 권한의 인스턴스에서 Demand 메서드를 호출하여 특정 권한을 갖고 있는지 테스트할 수 있습니다. 로컬 디스크에 파일을 저장할 수 있는 기능이 있는지 쿼리하는 다음 예제 코드에서는 이 사항을 보여 줍니다.


Imports System.IO ' File, FileStream, StreamWriter
Imports System.IO.IsolatedStorage ' IsolatedStorageFile
Imports System.Security ' CodeAccesPermission, IsolatedStorageFileStream
Imports System.Security.Permissions ' FileIOPermission, FileIOPermissionAccess
Imports System.Windows ' MessageBox

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
using System.IO; // File, FileStream, StreamWriter
using System.IO.IsolatedStorage; // IsolatedStorageFile
using System.Security; // CodeAccesPermission, IsolatedStorageFileStream
using System.Security.Permissions; // FileIOPermission, FileIOPermissionAccess
using System.Windows; // MessageBox

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;
            }
        }



...


    }
}

응용 프로그램에 원하는 권한이 없는 경우 Demand를 호출하면 보안 예외가 throw됩니다. 그렇지 않으면 권한이 부여된 것입니다. IsPermissionGranted는 이 동작을 캡슐화하고 true 또는 false를 적절히 반환합니다.

기능의 점진적 저하

필요한 작업을 수행할 수 있는 권한이 코드에 있는지 여부를 탐지하는 것은 다른 영역에서 실행할 수 있는 코드와 관련됩니다. 영역을 탐지하는 것이 별개의 문제이지만 가능하다면 사용자에게 대체 방법을 제공하는 것이 훨씬 좋습니다. 예를 들어 일반적으로 완전 신뢰 응용 프로그램에서 사용자는 원하는 모든 곳에 파일을 만들 수 있지만 부분 신뢰 응용 프로그램에서는 격리된 저장소에만 파일을 만들 수 있습니다. 파일을 만들기 위한 코드가 완전 신뢰(독립 실행형) 응용 프로그램 및 부분 신뢰(브라우저에서 호스팅된) 응용 프로그램 모두에서 공유하는 어셈블리에 존재하고 두 응용 프로그램 모두에서 사용자가 파일을 만들 수 있게 하려면 공유된 코드는 해당 위치에서 파일을 만들기 전에 부분 신뢰 또는 완전 신뢰에서 실행 중인지 여부를 탐지해야 합니다. 다음 코드에서는 두 사항을 모두 보여 줍니다.


Imports System.IO ' File, FileStream, StreamWriter
Imports System.IO.IsolatedStorage ' IsolatedStorageFile
Imports System.Security ' CodeAccesPermission
Imports System.Security.Permissions ' FileIOPermission, FileIOPermissionAccess
Imports System.Windows ' MessageBox

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
using System.IO; // File, FileStream, StreamWriter
using System.IO.IsolatedStorage; // IsolatedStorageFile
using System.Security; // CodeAccesPermission
using System.Security.Permissions; // FileIOPermission, FileIOPermissionAccess
using System.Windows; // MessageBox

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;
            }
        }



...


    }
}

대부분의 경우 부분 신뢰 대체 방법을 찾을 수 있어야 합니다.

인트라넷과 같은 제어된 환경에서는 관리되는 사용자 지정 프레임워크를 클라이언트 기반을 경유하여 global assembly cache (GAC)에 설치할 수 있습니다. 이러한 라이브러리는 완전 신뢰가 필요한 코드를 실행할 수 있으며 AllowPartiallyTrustedCallersAttribute를 사용하여 부분 신뢰에서만 허용되는 응용 프로그램에서 참조할 수 있습니다. 자세한 내용은 보안(WPF)WPF 보안 전략 - 플랫폼 보안을 참조하십시오.

브라우저 호스트 탐지

CAS를 사용하여 권한을 검사하는 것은 권한 단위로 검사해야 할 경우 적합한 기술입니다. 그러나 이 기술은 표준 처리의 일부를 예외로 catch하는 것에 의존하므로 일반적으로 권장되지 않으며 성능 문제를 일으킬 수 있습니다. 대신에 인터넷 영역 샌드박스 내에서만 XAML browser application (XBAP)가 실행되는 경우 XAML browser applications (XBAPs)에 대해 true를 반환하는 BrowserInteropHelper.IsBrowserHosted 속성을 사용할 수 있습니다.

참고참고

IsBrowserHosted는 응용 프로그램이 실행될 때 사용하는 권한 집합이 아니라 응용 프로그램이 브라우저에서 실행 중인지 여부만 구별합니다.

권한 관리

기본적으로 XBAPs는 부분 신뢰 수준에서 실행됩니다(기본 인터넷 영역 권한 집합). 그러나 응용 프로그램의 요구 사항에 따라 권한 집합을 기본값에서 변경할 수 있습니다. 예를 들어 XBAPs가 로컬 인트라넷에서 시작될 경우 다음 표와 같이 늘어난 권한 집합을 활용할 수 있습니다.

표 3: LocalIntranet 및 Internet 권한

권한

특성

LocalIntranet

Internet

DNS

DNS 서버 액세스

아니요

환경 변수

Read

아니요

파일 대화 상자

를 엽니다.

파일 대화 상자

무제한

아니요

격리된 저장소

사용자별 어셈블리 격리

아니요

격리된 저장소

알 수 없는 격리

격리된 저장소

제한되지 않은 사용자 할당량

아니요

미디어

안전한 오디오, 비디오 및 이미지

인쇄

기본 인쇄

아니요

인쇄

안전한 인쇄

리플렉션

내보내기

아니요

보안

관리 코드 실행

보안

부여된 권한 어설션

아니요

사용자 인터페이스

무제한

아니요

사용자 인터페이스

안전한 최상위 창

사용자 인터페이스

고유한 클립보드

웹 브라우저

HTML로의 안전한 프레임 탐색

참고참고

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

권한을 늘려야 하는 경우 프로젝트 설정과 ClickOnce 응용 프로그램 매니페스트를 변경해야 합니다. 자세한 내용은 WPF XAML 브라우저 응용 프로그램 개요를 참조하십시오. 다음 문서도 도움이 될 수 있습니다.

XBAP에서 완전 신뢰가 필요한 경우 동일한 도구를 사용하여 요청된 권한을 늘릴 수 있습니다. 단, XBAP는 로컬 컴퓨터, 인트라넷 또는 브라우저의 신뢰할 수 있거나 허용된 사이트에 있는 URL에서 설치되고 시작된 경우에만 완전 신뢰를 받습니다. 응용 프로그램이 인트라넷 또는 신뢰할 수 있는 사이트에서 설치된 경우 사용자는 고급 권한에 대해 알리는 표준 ClickOne 프롬프트를 받습니다. 사용자는 설치를 계속하거나 취소하도록 선택할 수 있습니다.

또는 완전 신뢰 배포를 위해 신뢰할 수 있는 ClickOnce 배포 모델을 모든 보안 영역에서 사용할 수 있습니다. 자세한 내용은 신뢰할 수 있는 응용 프로그램 배포 개요보안(WPF)을 참조하십시오.

참고 항목

개념

보안(WPF)

WPF 보안 전략 - 플랫폼 보안

WPF 보안 전략 - 보안 엔지니어링