Version 1 Security Changes for the Microsoft .NET Framework
Microsoft .NET Framework version 1
Summary: This document describes how Microsoft .NET Framework helps you to incorporate the best security practices in your software development, and how to update your existing components and applications. (6 printed pages)
Prerequisites: Familiarity with the common language runtime and the Microsoft® .NET Framework, including basic knowledge of evidence-based security and code-access security.
Customers have expressed their desire that, in today's security-sensitive climate, Microsoft focus intensely on security. In response, Microsoft is aligning to the Trustworthy Computing initiative, an industry-wide effort spearheaded by Craig Mundie, Chief Technical Officer of Advanced Strategies and Policy at Microsoft. The goals of Trustworthy Computing are to improve the design, implementation, and policies that emphasize security. Achieving the goals and meeting the requirements of Trustworthy Computing will require concerted, long-term effort by vendors, government, and industry.
The Microsoft® Visual Studio® .NET and .NET Framework development teams have examined the balance between extensibility and security in the .NET Framework based on the Trustworthy Computing initiative. To strike the balance requested by our customers, we are being extremely conservative about the set of features that will be available to partially trusted code, and we are using the security system to enforce these more conservative policies.
This document describes the changes made to Version 1 of the .NET Framework to address security needs, provide maximum security to the .NET platform out of the box, and provide guidance on how to incorporate key security practices in your software development. For most of you, these changes will not require any specific action. However, it is important for all developers to understand the nature of these changes, which can prove to be useful in your future software development efforts.
Summary of Changes in Version 1
Partially trusted code is code, usually from the Internet or a local intranet, that security policy grants only a subset of permissions to. These permissions enable the code to perform a limited set of actions that are considered safe, but nothing that might be dangerous in the event the code is malicious. The .NET Framework supports partially trusted code to safely enable key scenarios, primarily for mobile code applications. However, because the Internet and local intranet can be sources of either an initial attack or the subsequent propagation of security threats to enterprise and individual customers, there is a difficult trade-off between maximally enabling functionality to partially trusted code and minimizing the risk involved.
The following changes have been implemented in the .NET Framework in response to the requirement for additional security:
- Default process identity for Web applications.
By default, Microsoft ASP.NET now runs Web applications under an unprivileged local account. (Beta versions of the product ran as System.)
- Strong-named assemblies must be explicitly enabled to be used by partially trusted code.
Developers must now declare which strong-named assemblies are designed for use by partially trusted code. Without this explicit declaration, the caller must have full trust to use the code. This change ensures that developers will never unknowingly expose functionality that is not properly secured for use by partially trusted callers. Note that this change applies only to assemblies that have been assigned a strong name.
- Default security policy installed with the common language runtime has been tightened.
The security policy defaults that are installed for initial use with the .NET Framework have been changed to reduce the permissions granted to mobile code from the Internet or the local intranet. The new defaults reflect a slightly more conservative set of mobile code scenarios for the new security/functionality trade-offs of the platform.
- Web applications must be fully trusted.
Application code must be fully trusted to use Web Forms features. Previously, it was possible to use Web Forms with partially trusted code. The new restriction was deemed worth the resulting improved security.
The rest of this document describes these changes in more detail and explains what they mean for developers, including when specific action might be needed to ensure that applications built on the .NET Framework are as secure as possible.
Process Identity in ASP.NET
In its default installation on Microsoft Windows® 2000 and Microsoft Windows XP, ASP.NET runs Web application code in a worker process. The identity of this process defaults to an unprivileged local account called the ASPNET account.
In Beta releases of ASP.NET, the process identity was System, a powerful administrative account with many privileges on the computer. To provide a less-privileged default installation, the weaker account is now used. This account is suitable for use in many Web applications.
Strong-Named Code Must Explicitly Enable Use by Partially Trusted Code
.NET Framework code access security enforces the evidence-based policy constraints on partially trusted code. In most situations, developers do not need to do anything new to gain the advantages of these new technologies. However, to follow the best security practices, the .NET Framework now requires developers to specifically identify strong-named code that may be used in partially trusted code scenarios.
Because it can be easily accessed, code that can be shared between applications is especially at risk of exploitation by other, malicious code. Signing an assembly with a strong name makes the assembly easily available for sharing, either by installation in the global assembly cache or by code download. Therefore, you must now include an explicit declaration in strong-named assemblies that enable them to be safely called by partially trusted code. Without this declaration, only fully trusted callers (which are presumed to not be malicious) will be able to use such assemblies.
Note Only code signed with a strong name is affected by this change. Code that is private to a specific application does not require a strong name. Additionally, because it cannot be referenced by potentially malicious code outside the application, such code does not need to enable its use by partially trusted code.
Code Affected by This Change
The following kinds of code must explicitly enable use by partially trusted code:
- Strong-named code that is written for partially trusted scenarios.
- Any components (whether partially or fully trusted) that will be called by mobile code downloaded from the Internet or the local intranet. These components are affected because under default security policy, the mobile code receives partial trust.
- If default policy is modified, any code that security policy grants less than full trust.
Enabling Use by Partially Trusted Code
By default, any strong-named assembly that does not explicitly opt in to its use by partially trusted code will be callable only by other assemblies that are granted full trust by security policy. This restriction is enforced by placing a LinkDemand for Fulltrust on every public or protected method on every publicly accessible class in the assembly. More information on LinkDemand is available in the Microsoft .NET Framework SDK.
Assemblies that are intended to be called by partially trusted code declare their intent and opt-in through the use of an assembly-level custom attribute. The custom attribute is the System.Security.AllowPartiallyTrustedCallersAttribute class. You opt in by simply declaring this attribute at the assembly level. For example:
[assembly:AllowPartiallyTrustedCallers] // C# syntax
The presence of this assembly-level attribute prevents the default behavior of placing FullTrust LinkDemand security checks, making the assembly callable from any other assembly (partially or fully trusted).
When this attribute is present, all other security checks in your code still work as before, including any class- or method-level declarative security attributes that are present. This attribute blocks only the implicit "fully trusted caller only" enforcement described previously.
When to Use the AllowPartiallyTrustedCallersAttribute
The AllowPartiallyTrustedCallersAttribute should be applied only after the developer has considered the security implications and taken the necessary precautions, including code review against the secure coding guidelines referenced previously. This attribute should be applied to assemblies only if the following criteria are met:
- Partially trusted code use is important to support.
- The assemblies have been designed and built with explicit attention to security considerations to make them robust against all callers, including potentially malicious callers.
- Appropriate security testing with partially trusted code is done before releasing the code.
.NET Framework Assemblies with the AllowPartiallyTrustedCallersAttribute
To enable key scenarios for partially trusted code and minimize unintended use by partially trusted callers, several .NET Framework assemblies are marked for use by partially trusted code. Some code within these assemblies might be subject to security restrictions, including requiring callers to be fully trusted in some cases. All other assemblies that are part of the .NET Framework are intended for use only by fully trusted code.
The following .NET Framework assemblies have the AllowPartiallyTrustedCallersAttribute:
Default Security Policy Changes
Security policies for code downloaded from a local intranet zone were altered to further restrict what such code is allowed to do without compromising key scenarios for mobile code. The following changes were made:
- Removed EnvironmentPermission Read access to "TEMP" and "TMP".
Path names of the respective temporary file locations will not be disclosed because downloaded code typically does not have file access to these locations.
- Removed SecurityPermission.RemotingConfiguration.
Object-remoting scenarios are not supported for partially trusted code applications.
- Restricted the policy giving full trust to Microsoft-signed and ECMA strong-name-signed code to apply only to code installed on the local machine.
Partially Trusted Web Application Support Removed
System.Web.dll is not enabled to support partially trusted callers. Therefore, Web applications must be run in the "Full" trust mode. If a Web application is mapped to a UNC share, that share must be granted full trust using the common language runtime security policy management tools provided in the Microsoft .NET Framework SDK.
Additionally, ASP.NET does not support the <trust> configuration directive that allows Web applications to be run with partial trust. This directive is supported only with the default setting of "Full".
Reflection Security Change
Enforcement of LinkDemand declarative security for types accessed using reflection was strengthened. Because LinkDemand is a security check that occurs during just-in-time compilation, it cannot be directly applied to late-bound use. To ensure that security enforcement is robust, the reflection layer makes a run-time Demand of the same permission for all late-bound uses, preventing possible malicious use of the member through reflection that would not be allowed in the early-bound case.
Impact on Customer Code
The rest of this document describes how the changes described previously might impact you and the appropriate course of action that will ensure your code is as secure as possible. The most common case where you will need to make changes to accommodate the new security implementation will be for components that are intended to be used by partially trusted code.
ASP.NET Application Account
In some cases, ASP.NET applications developed with Beta versions of ASP.NET might require changes to work with the new process identity. For more details regarding this change, please review the [Content link no longer available, original URL:"http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000440"] ASP.NET documentation.
Components Used by Partially Trusted Code
Components intended for use by partially trusted code that are not private to a specific application must be changed if they are signed with a strong name.
If you have such components (typically, in applications with components downloaded from the Internet or the local intranet), perform the following steps:
- If the code was not originally implemented with code access security as an important design goal, completely review the code for security so that partially trusted callers can be safely enabled.
- Include partially trusted code scenarios in component testing; test that all security checks function as intended.
- When you have completed steps 1-3 and you are confident that the code is secure, add the assembly-level attribute described previously to enable partially trusted callers. The resulting component will be secure and will work with partially trusted callers.
If these steps are not taken, the security checks that result from the omission of the partially trusted caller declaration will cause a security exception to be raised at run time, resulting in an application error.
Partially Trusted ASP.NET Application
Because Web Forms do not support partially trusted callers, such Web applications must be changed to be fully trusted. Of course, only trustworthy code should ever be run under full trust. Therefore, you should make this change only if you can trust that the source of the code is not malicious.
Reflection Security Change
This change can cause a new security exception to be raised when your code uses reflection against a type that is protected by a LinkDemand, and the callers above the reflection layer do not have the required permission grants.