Windows 窗体中的其他安全注意事项

重要

除非另有指定,否则此内容仅适用于 .NET Framework。

.NET Framework 安全设置可能导致应用程序在部分信任环境中与在本地计算机上运行时的表现不同。 .NET Framework 限制对文件系统、网络和非托管 API 等重要本地资源的访问,等等。 安全设置会影响调用Microsoft Windows API 或其他安全系统无法验证的 API 的能力。 安全性还会影响应用程序的其他方面,包括文件和数据访问以及打印。 有关部分信任环境中文件和数据访问的详细信息,请参阅 Windows 窗体中的更安全的文件和数据访问。 有关在部分信任环境中打印的详细信息,请参阅 Windows 窗体中的更安全打印

以下部分介绍如何使用剪贴板、执行窗口操作,以及如何在运行于部分信任环境的应用程序中调用 Windows API。

剪贴板访问

UIPermission 控制对剪贴板的访问,关联的 UIPermissionClipboard 枚举值指示访问级别。 下表显示了可能的权限级别。

UIPermissionClipboard 值 DESCRIPTION
AllClipboard 剪贴板可以不受限制地使用。
OwnClipboard 剪贴板的使用受到一些限制。 将数据置于剪贴板(复制或剪切命令作)的功能不受限制。 接受粘贴的固有控件(如文本框)可以接受剪贴板数据,但用户控件无法以编程方式从剪贴板读取。
NoClipboard 无法使用剪贴板。

默认情况下,本地 Intranet 区域接收 AllClipboard 访问权限,Internet 区域接收 OwnClipboard 访问权限。 这意味着应用程序可以将数据复制到剪贴板,但应用程序无法以编程方式粘贴到剪贴板或从剪贴板读取数据。 这些限制可防止程序不完全信任地读取其他应用程序复制到剪贴板的内容。 如果应用程序需要完全剪贴板访问权限,但你没有权限,则必须提升应用程序的权限。 有关提升权限的详细信息,请参阅 常规安全策略管理

窗口操作

UIPermission 类还控制执行窗口操作和与 UI 相关的操作的权限,关联的 UIPermissionWindow 枚举值表示访问级别。 下表显示了可能的权限级别。

默认情况下,本地 Intranet 区域接收 AllWindows 访问权限,Internet 区域接收 SafeTopLevelWindows 访问权限。 这意味着,在 Internet 区域中,应用程序可以执行大多数窗口操作和 UI 操作,但窗口的外观将被修改。 修改后的窗口在首次运行时显示气球通知,包含修改后的标题栏文本,并且需要标题栏上的关闭按钮。 应用程序的气球通知和标题栏向用户表明该应用程序正在部分信任下运行。

UIPermissionWindow 值 DESCRIPTION
AllWindows 用户无需限制即可使用所有窗口和用户输入事件。
SafeTopLevelWindows 用户只能使用更安全的顶级窗口和更安全的子窗口进行绘图,并且只能为这些顶级窗口和子窗口内的用户界面使用用户输入事件。 这些更安全的窗口已明确标记,并具有最小和最大大小限制。 这些限制可以防止潜在有害的欺骗攻击,例如模仿系统登录界面或系统桌面,并限制编程对父窗口、与焦点相关 API 的访问,以及对 ToolTip 控件的使用。
SafeSubWindows 用户只能使用更安全的子窗口进行绘图,并且只能对该子窗口内的用户界面使用用户输入事件。 浏览器中显示的控件是更安全的子窗口的示例。
NoWindows 用户无法使用任何窗口或用户界面事件。 不能使用用户界面。

UIPermissionWindow枚举标识的每个权限级别允许的操作少于高于该级别的权限级别。 下表指示由 SafeTopLevelWindowsSafeSubWindows 值限制的操作。 有关每个成员所需的确切权限,请参阅 .NET Framework 类库文档中该成员的参考。

SafeTopLevelWindows 权限限制下表中列出的操作。

组件 限制的操作
Application - 设置 SafeTopLevelCaptionFormat 属性。
Control - 获取 Parent 属性。
- 设置 Region 属性。
- 调用 FindFormFocusFromChildHandleFromHandlePreProcessMessageReflectMessageSetTopLevel方法。
- 如果返回的控件不是调用方控件的子级,则调用该GetChildAtPoint方法。
- 修改容器控件内的控件焦点。
Cursor - 设置 Clip 属性。
- 调用 Hide 方法。
DataGrid - 调用 ProcessTabKey 方法。
Form - 获取 ActiveFormMdiParent 属性。
- 设置ControlBoxShowInTaskbarTopMost属性。
- 将 Opacity 属性设置为低于 50%。
以编程方式将 WindowState 属性设置为 Minimized
- 调用 Activate 方法。
- 使用NoneFixedToolWindowSizableToolWindowFormBorderStyle枚举值。
NotifyIcon - 使用 NotifyIcon 组件完全受限。

除了SafeTopLevelWindows值施加的限制外,SafeSubWindows值还会限制下表中列出的动作。

组件 限制的操作
CommonDialog - 显示从 CommonDialog 类派生的对话框。
Control - 调用 CreateGraphics 方法。
- 设置 Cursor 属性。
Cursor - 设置 Current 属性。
MessageBox - 调用 Show 方法。

托管第三方控件

如果窗体托管第三方控件,则可能会出现另一种类型的窗口操作。 第三方控件是你尚未自行开发和编译的任何自定义 UserControl 。 尽管托管方案难以利用,但从理论上讲,第三方控件可以扩展其呈现图面以覆盖窗体的整个区域。 然后,此控件可以模拟关键对话框,并从用户请求用户名/密码组合或银行帐户号等信息。

若要限制此潜在风险,请仅使用你可以信任的供应商的第三方控制。 如果使用从无法验证的源下载的第三方控件,建议查看源代码中是否存在潜在攻击。 验证源不是恶意的后,应自行编译程序集,以确保源与程序集匹配。

Windows API 调用

如果应用程序设计需要从 Windows API 调用函数,则你正在访问非托管代码。 在这种情况下,在处理 Windows API 调用或值时,无法确定代码对窗口或操作系统的行为。 SecurityPermission类和UnmanagedCode值的SecurityPermissionFlag枚举控制对非托管代码的访问。 仅当应用程序被授予 UnmanagedCode 权限时,应用程序才能访问非托管代码。 默认情况下,只有在本地运行的应用程序才能调用非托管代码。

某些 Windows 窗体成员提供需要 UnmanagedCode 权限的非托管访问权限。 下表列出了命名空间中 System.Windows.Forms 需要权限的成员。 有关成员所需的权限的详细信息,请参阅 .NET Framework 类库文档。

组件 成员
Application - AddMessageFilter 方法
- CurrentInputLanguage 财产
- Exit 方法
- ExitThread 方法
- ThreadException 事件
CommonDialog - HookProc 方法
- OwnerWndProc\方法
- Reset 方法
- RunDialog 方法
Control - CreateParams 方法
- DefWndProc 方法
- DestroyHandle 方法
- WndProc 方法
Help - ShowHelp 方法
- ShowHelpIndex 方法
NativeWindow - NativeWindow
Screen - FromHandle 方法
SendKeys - Send 方法
- SendWait 方法

如果应用程序没有调用非托管代码的权限,则应用程序必须请求 UnmanagedCode 权限,或者必须考虑实现功能的替代方法;在许多情况下,Windows 窗体提供了 Windows API 函数的托管替代方法。 如果没有替代方法,并且应用程序必须访问非托管代码,则必须提升应用程序的权限。

调用非托管代码的权限允许应用程序执行几乎任何操作。 因此,仅应为来自受信任源的应用程序授予调用非托管代码的权限。 或者,根据应用程序,对非托管代码进行调用的应用程序功能片段可以是可选的,也可以仅在完全信任环境中启用。 有关危险权限的详细信息,请参阅 “危险权限”和“策略管理”。 有关提升权限的详细信息,请参阅 常规安全策略管理

另请参阅