.NET Framework Security
New and Improved Security in the .NET Framework 2.0
 

Rudolph Araujo and Shanit Gupta
Foundstone Professional Services

December 2005

Applies to:
   .NET Framework 2.0
   Visual Studio 2005
   Security

Summary: Survey some of the major security changes in Microsoft .NET Framework 2.0 and Visual Studio 2005. (41 printed pages)

Contents

Introduction
Partial Trust Development
Code Access Security
ASP.NET
C/C++
Visual Basic .NET
Cryptography
Managed Code
Tools Support
Conclusion
Appendix of References
About The Authors
About Foundstone Professional Services

Introduction

Developers build applications to accomplish a specific set of objectives. Security is usually treated as an overhead. Incorporating security in applications often consumes time, costs money, and is not straightforward to do. However, with the emphasis on building secure applications, developers have to commit to being diligent in building safe applications, as this is presently demanded by businesses. Additionally, as compliance requirements have become more stringent, development teams have come to realize that building secure applications is no longer optional because protecting sensitive customer information is a requisite function of conducting business in today's digital environments. In the past, security was left to a few practitioners regarded as the local "cryptography gurus" who were tasked with overlaying security over existing code either just before the application went into production, or worse, after high profile vulnerabilities were discovered. [This in fact is part of the problem with developers and IT organizations often assuming cryptography (and more specifically SSL) is the "shiny red button" that represents the solution to all security woes.] Security features were not intuitive in the languages and frameworks and certainly not easy to use. Thankfully, with some of the newer frameworks, such as Java and Microsoft .NET, this has changed to a marginal extent. These frameworks do attempt to make it easy for developers to do the "right thing," while making it more difficult for them to do the wrong thing. The .NET Framework 2.0 and Visual Studio 2005 attempt to make a significant jump in the direction of allowing developers the ease to incorporate the principles of secure application development. The new versions of the Framework and development environment equip software development teams with several new features, tools, and aids to assist programmers in incorporating the security features with minimal stress.

In this paper we will discuss the new security features in the .NET Framework 2.0 and in Visual Studio 2005. The remainder of this submission is organized into the following broad categories of discussion which are indexed above to allow practitioners to pick and choose content of most relevance to them:

  • Partial Trust Development
  • Code Access Security
  • ASP.NET
  • C/C++
  • Visual Basic .NET
  • Cryptography
  • Managed Code
  • Tools Support

Each section below provides a short description of the key new/enhanced features offered in the updated Framework as well as where appropriate links to locate more information. The reader is strongly advised to follow these links for the specific topics of interest as many of these them also provide more detailed code samples and use scenarios.

Partial Trust Development

In the .NET Framework version 1.x, it was difficult, if not impossible, to create trusted applications. This was true for a number of reasons including the lack of rich database support—the SQL client classes were not accessible in partial trust in prior versions of the .NET Framework, the difficulty of debugging partial trust scenarios, and the lack of clear, concise and accurate information about what would work and what would not in these scenarios. Most developers, therefore, took the route of bumping up their applications to run in full trust to avoid having to deal with the complexities of partial trust. Partial trust is an extremely effective mechanism for enforcing the principle of least privilege. It allows the privileges of an assembly to be restricted based upon the code access security policies in addition to the permissions of the user in whose context the application runs.

With .NET 2.0 it has become much easier to create rich applications that can still operate within a partially trusted sandbox. In this section, we will describe some of these new features and enhancements that are built to specifically target the problem mentioned.

  • Enhanced Security Exception—With the enhanced SecurityException in the .NET Framework 2.0, the developer is equipped with properties that allow her to find the precise cause of the security problem. The enhanced SecurityException is integrated in the IDE and is accompanied with the detailed cause of the exception. It also provides list of steps that can resolve the problem. New properties in the .NET Framework SecurityException object are as listed below:

    Table 1

    NameTypeDescription
    Action SecurityActionThe SecurityAction that failed the security check
    Demanded ObjectThe permission, permission set, or permission sets that were demanded and triggered the exception
    DenySetInstance ObjectIfa Deny stack frame caused the security exception to fail, then this property will contain that set, otherwise it will be null.
    FailedAssemblyInfo AssemblyNameAssemblyName of the assembly that caused the security check to fail.
    FirstPermissionThatFailed IPermissionThe first permission in failing PermissionSet (or PermissionSetCollection) that did not pass the security check.
    MethodMethodInfoThe method that the failed assembly was in when it encountered the security check that triggered the exception. If a PermitOnly or Deny stack frame failed, this will contain the method that put the PermitOnly or Deny frame on the stack.
    PermitOnlySetInstanceObjectIf the stack frame that caused the security exception had a PermitOnly permission set, this property will contain it; otherwise, it will be null.
    Url StringURL of the assembly that failed the security check
    Zone SecurityZoneZone of the assembly that failed the security check.

    Reference:
    SecurityException Class in the .NET Framework Class Library

  • Debug in Zone—Developers usually develop and debug their programs from a local computer and thus from the most trusted environment—usually with full trust. To test and debug how the application would function when executing from an intranet or the Internet, the developer still must move the application to another system and test the application in those conditions.

    To help developers simplify their testing, the Debug in Zone feature helps them run managed code in a sandbox using custom permissions. This allows a developer to emulate the behavior of the code as seen by the users. Thus developers have the option to debug the application as if it were running from the Internet, intranet or local computer zones. In most of the cases the developer will be able to select one of these standard execution environments for the application. However, in cases where the developer wants to custom build the environment, it can be done using fine grain access permissions as well. This helps the developers debug code as if it were executing within a specific zone or within a defined code access security policy. Thus, developers can detect violations early and learn about the execution sandbox that each of the zones provides.

    Reference:
    New Security Features in Visual Studio 2005

  • PermCalc—In many cases the functionality of the application remains fairly static. This is especially true for line of business type applications. There is usually a well-defined set of features that the code needs to provide for it to be useful and serve its purpose. One helpful feature would be to find the minimum set of security permissions the application needs to meet all of its business requirements. The PermCalc tool is capable of achieving just that. The output of the tool estimates the minimum set of permissions required to run application. The tool traces through the different code paths in the application as well as through the shared and system libraries used by the application. For every code path trace, the tool collects all the permissions demanded through declarative demands, link demands, and declarative stack walk modifiers.

    All the permission states used in declarative security actions must be known at compile time to successfully effect all declarative security actions on application assemblies if they are to be calculated exactly. If a declarative demand is used, the minimum grant permission set for every assembly on the call stack at that point is updated with the demanded permission set. If a declarative assert is found on the simulated call stack, then only the intersection between the asserted permission set and the demanded permission set is updated for all assemblies above the assert on the call stack. Similarly, if a link demand is found, only the caller on the simulated call stack above the point of the link demand is updated with the requested permission set.

    The code path trace is a trace through the Microsoft intermediate language (MSIL) of every method, starting with the primary entry-point method of the application. If imperative permission set actions is found in the method MSIL trace, then the following update algorithm is run for each assembly:

    • If the permission state used in the imperative demand, link demand, assert, permit only, or deny can be determined statically, and it is certain not to be dependent on any state available only at run time, then the effect of such security action on application assemblies can be determined and calculated for the effects of declarative security actions on the minimum grant permission set of all profiled assemblies.
    • If the state of the permission set used in an imperative security action cannot be determined statically, then the unrestricted state of the permission is assumed, for example, unrestricted security permission or unrestricted file IO read permissions. In some instances this can lead to an overestimation of the permissions required for an application to run. The user can use the -Under option to override this default behavior.
    • If there are multiple code paths through a method and some have different security action annotations, then the union of the demands and the intersection of the asserts are used because the tool might not be able to determine which of the possible code paths through a method the application will take at run time.

      Reference:
      Permission Calculator Tool (Permcalc.exe)

  • IntelliSense in Zone—The IntelliSense-in-Zone feature (only available in Visual Basic .NET) can be used in conjunction with code access security policies to help developers make the right choices about the APIs they use in their application. When running in Visual Basic .NET, the IntelliSense feature provides visual feedback to let developers know about any APIs that are not available within the current execution zone and hence will cause the application to violate the security policy. For instance, if executing from the Local Intranet zone, an application can only read the "username" environment variable by default. The IntelliSense-in-zone feature will therefore visually flag any attempts to violate this policy, such as attempting to access other environment variables.

    Reference:
    Visual Basic-Specific IntelliSense

  • Simple Sandboxing API using AppDomains—This feature allows applications to execute un-trusted code such as third party scripts, executables, and plug-ins within a sandbox that has a restricted permission set. Thus, the host may chose which permissions it would like to grant the untrusted code. Specifically, the method that enables this mechanism is a new overload of the AppDomain.CreateDomain method. Similarly, the introduction of the AppDomainManager class provides the hosting application with more fine-grained control over the set of operations the hosted code is allowed to perform and also the general execution of this code.

    Listing 1

    public static AppDomain CreateDomain ( 
    string friendlyName, 
    Evidence securityInfo, 
    AppDomainSetup info, 
    PermissionSet grantSet, 
    params StrongName[] fulltrustAssemblies )

    Reference:
    AppDomain.CreateDomain Method (String, Evidence, AppDomainSetup, PermissionSet, StrongName[])

  • Partial Trust Permissions—In the .NET Framework 2.0, SQL Server access is available at the medium trust level since the .NET Framework Data Provider for SQL Server no longer demands full trust. This makes the SQL Client classes available to medium-trust applications that, in turn, allows partial trust developers access to Microsoft SQL Server installations. Similarly, medium trust applications can now subscribe to receive notifications from SQL server since the SQLNotification permission is also available in partial trust. The OLE DB managed provider also no longer requires full trust of its callers; they will only need the OleDbPermission. To access an OLE Db data source from partial trust, a custom trust policy is required that grants OleDbPermission to the application.

    In version 2.0, SmtpPermission is available at Full, High, and Medium trust levels. This allows applications to send e-mail. Applications will also no longer need full trust to access the event log. A custom trust policy can be created which will grant the code the EventLogPermission.

Code Access Security

Applications built under the .NET Framework provide access to resources based upon the evidence presented by the code. This model is called Code Access Security. This security model is significantly different from the traditional model where the permissions assigned to an application were based upon the privileges of the logged on user. The evidence can be provided in the form of origin of the application and digital signatures. Each system can be configured based upon application domain, user, machine, and enterprise policy. Based on these policy settings the application may be granted or denied permission to certain set of resources.

The Code Access Security model is further enhanced in the .NET 2.0 Framework. It provides a host of new features, enhances many of the existing ones while trying to make the experience for a developer leveraging this model as easy and intuitive as possible. This therefore also includes a few tools necessary for enforcement of policies.

  • Full Trust GAC—Unlike 1.* and Whidbey Beta 1 it is important to note that the GAC is explicitly full trust in 2.0 and not as a side effect of being on the local machine. Whidbey Beta 2 grants assemblies in the GAC full trust regardless of how the security policy is configured for them. However the assembly level declarative security will still work as expected. If assembly decides to RequestRefuse or RequestOptional even when it is present in the GAC the grant set will not be full trust. But to state the obvious any assembly placed in the GAC will start with full trust irrespective of the policy set. This update obviously requires the users to be much more careful about importing an untrusted assembly in GAC.

    Reference:
    .NET Security Blog

  • Full trust means Full Trust—In .NET 2.0, any code granted full trust will no longer have CAS protection. This means that the developers will no longer be able to use Identity Permissions to restrict code that is granted full trust.
    • Identity Permissions in any state become subset of the Unrestricted permission set. This means that the demand for any identity permission will now pass for any code in full trust.
    • Set logic for IdentityPermissions changes. This will allow developers to perform logic operations like union and intersection for identity permissions.
    • LinkDemands are optimized out in Full trust. Any LinkDemand for any Identity or CAS permission will now pass in Full trust. A potential application-breaking change is one in which the interest of performance benefits the non-CAS LinkDemands are ignored in Full trust.

      Reference:
      Eugene Bobukh's Weblog

  • Security Transparency—Transparent code is code that voluntarily gives up its ability to elevate the permissions of the call stack. Due to these restrictions, transparent code has the effect of running with either the set of permissions it was granted or the set of permissions its callers were granted, whichever is smaller. Because of that, fully trusted transparent code essentially runs in the same security context of its callers, since the caller's permissions are necessarily less than or equal to full trust. This is particularly useful if you want to let your assembly be used by partially trusted callers. It will ensure that the partially trusted code is unable to perform any operation that it would not have been able to perform otherwise. The following rules apply to transparent code:
    • Transparent code cannot Assert for permissions to stop the stack walk from continuing.
    • It cannot satisfy a LinkDemand. Instead, any LinkDemands on APIs called by the transparent assembly will be automatically converted into full demands.
    • Transparent code cannot automatically use unverifiable code, even if it has SkipVerification permission. Instead, any method that contains unverifiable code will have a demand for UnmanagedCode permission injected into it.
    • Similarly, calls to P/Invoke methods that have been decorated with the SuppressUnmanagedCodeAttribute will cause a full demand for UnmanagedCode.

      It is possible to mark different segments of code as security critical or transparent using the attributes:

    a) [assembly: SecurityTransparent] : This makes the whole assembly a security transparent module.
    b) [assembly: SecurityCritical] : It allows certain segments of code to be made critical. The security critical code will have to be explicitly marked. The rest of the code will be treated as security transparent

    References:
    .NET Security Blog: When the Opposite of Transparent Isn't Opaque
    .NET Security Blog: Marking Your Code Transparent

  • ClickOnce—ClickOnce provides a trustworthy deployment model for users to be able to download and execute applications from centrally managed servers without requiring administrator privileges on the client machine. Applications deployed using ClickOnce are ensured not to interfere with any other application or corrupt any data on the system. Furthermore, ClickOnce applications are run in secure execution context whose permissions are limited based on where the application is coming from or the trust assigned to the originator of that application. It is possible to override the location-based policy with custom security policy on the system that depends on the content-based evidence.
  • TrustManager—This is the default UI within System.Windows.Forms.dll that allows end-users to make ClickOnce trust decisions about allowing code that requires higher privileges than what the current policy and zone allow to be installed on the local machine. Trust Managers can be locked down and configured to allow only applications in certain zones to elevate privileges. Additionally, it is possible to configure only trusted applications to be allowed to elevate privileges. Another option is to deploy a trust license from a trusted license authority that will allow elevated privilege action without prompting the user.
  • ApplicationSecurityManager—Helps determine and cache trust decisions during the ClickOnce process and can also be used to point to a custom trust manager if used. The applications trust decisions are cached in an XML file that can be accessed using the ApplicationSecurityManager class. This makes it possible to enumerate the application trust of other applications and add and remove security application trust.

    References:
    ClickOnce: Deploy and Update Your Smart Client Projects Using a Central Server
    ClickOnce and Security

  • GacMembershipCondition—A new evidence based membership condition has been added to the Framework. The GacMembershipCondition is satisfied by all assemblies that are installed into the GAC. These assemblies have explicit full trust permissions and are no longer tied to the local machine policy

    Reference:
    GacMembershipCondition Class

  • CodeConnectAccess/NetCodeGroup—These classes are used to control how executing code can connect back to the site it was downloaded from. The developer can control both the protocol and port that the code is permitted to use when connecting back to its site of origin. Furthermore, it is possible to create a connection access rule that applies when the origin scheme is not present in the evidence or is not recognized. It also allows the developer to create a connection access rule that applies when there is no connection access rule with a matching scheme.

    Listing 2

    public static void SetNetCodeGroupAccess() 
    { 
    const string userPolicyLevel = "User"; 
    // Find the User policy level. 
    PolicyLevel userLevel = null; 
    System.Collections.IEnumerator policyHirarchy = System.Security.SecurityManager.PolicyHierarchy(); 
    while(policyHirarchy.MoveNext()) 
    {
       userLevel = (PolicyLevel) policyHirarchy.Current;
       if(userLevel.Label == userPolicyLevel ) 
       { 
          break; 
       } 
    } 
    if (userLevel.Label != userPolicyLevel) throw new ApplicationException("Could not find User policy level."); 
    IMembershipCondition membership = new UrlMembershipCondition(@"http://www.foundstone.com/*");
    NetCodeGroup codeGroup = new NetCodeGroup(membership);
    
    // Delete default settings. 
    codeGroup.ResetConnectAccess(); 
    
    // Create an object that represents access to the HTTPS scheme and 
    // default port.    
    CodeConnectAccess httpsAccess = new CodeConnectAccess(Uri.UriSchemeHttps,    CodeConnectAccess.DefaultPort); 
    
    // Create an object that represents access to the origin scheme and 
    // port. 
    CodeConnectAccess originAccess = CodeConnectAccess.CreateOriginSchemeAccess(CodeConnectAccess.OriginPort); 
    
    // Add connection access objects to the NetCodeGroup object. 
    codeGroup.AddConnectAccess(Uri.UriSchemeHttp, httpsAccess); 
    codeGroup.AddConnectAccess(Uri.UriSchemeHttp, originAccess); 
    
    // Enter the name and description information
    codeGroup.Name = "ContosoHttpCodeGroup"; codeGroup.Description = "Code originating from Foundstone.com can connect back using HTTPS."; 
    
    // Add the code group to the User policy's root node. userLevel.RootCodeGroup.AddChild(codeGroup); 
    
    // Save the changes to the policy level. System.Seclurity.SecurityManager.SavePolicy(); 
    }

    References:
    CodeConnectAccess Class
    NetCodeGroup Class

  • Code Access Security Permissions—A number of code access security permissions have been added to the Framework. Some of these key new permissions are enumerated in the table below:

    Table 2

    PermissionDescriptionReference
    SmtpPermissionIs available up to medium trust and allows access to the SmtpClient class to access an SMTP serverSmtpPermission Class
    NetworkInformationPermissionControls access to networking information and statistics from the local computerNetworkInformationPermission Class
    StorePermissionControls the access that code is granted to the certificate store containing X.509 certificatesStorePermission Class
    DataProtectionPermissionControl access to the managed DPAPI classes for encrypting memory and storageDataProtectionPermission Class
    KeyContainerPermissionControls access to the key container and gives developers the ability to provide applications with limited access to key containers.KeyContainerPermission Class
  • HostProtectionResource—Allows a class or method to let the runtime know about categories of functionality that is potentially damaging to the host, the application or threads. For instance, the statement below shows the use of HostProtectionResource enumeration with the HostProtectionAttribute attribute. We use the enumeration flags to indicate that the method exposes the shared state that may be shared across multiple threads and the application also exposes a user interface (UI).

    Listing 3

    [HostProtectionAttribute(Resources = HostProtectionResource.SharedState
        |HostProtectionResource.UI)]

    Reference:
    Host Protection Resource Enumeration

  • Custom Permissions—Custom permission classes no longer have to be in the GAC in the new version of the Framework. In v2.0, declarative security is processed at runtime as opposed to at compile time as was done in v1.x. Since the v1.x compilers needed to access the security attributes, and their AppBase was set to the compiler path (generally the Framework directory), they could not find the classes unless they were in the Global Assembly Cache (GAC). Because the .NET 2.0 compilers do not instantiate the declarative security classes, they do not have a problem with them not being in the GAC. If the assembly with the permission classes is located next to the running app, when the runtime can find the attributes when it needs to instantiate them.
  • CASPol—Although the v1.0 and v1.1 versions of CASPol provided a switch to disable the CLR security system, in v2.0, security can only be disabled as long as the CASPol process remains active. When CASPol is terminated, it returns security to the "on" state. Even abruptly terminating the CASPol process will still return security to this secure state.

ASP.NET

The new security features in ASP.NET 2.0 will help application developers create and manage user accounts and custom role-based access control within a Web application. The Framework has features to design and implement authentication and authorization controls, which eliminates the need for developers to write custom code for such functionality in each and every application. Along with the standard security controls, the new Framework also provides a powerful mechanism to ease the task of administrators managing the Web application. This is done using the Web Site Administration Tool that is a set of pre-written ASP.NET pages. This requires no programming skills for Web application administrators. We provide more details on each of the important features below:

  • Membership—ASP.NET 2.0 contains a membership feature that greatly reduces the amount of code you have to write when authenticating visitors to your application. It alleviates the need to manage physical storage of user name and password information. It also provides a UI to manage membership to the application as well as a group of security controls that support authentication, password recovery and login status. The configuration details are stored in web.config that can be configured using a wizard that allows the developer to configure the membership of the application.

    Reference:
    How to Specify ASP.NET Membership

  • User Management Controls—Most applications have the standard set of routines to provide authentication and authorization mechanisms in the application and still developers make mistakes in implementing them. Therefore, it makes sense to provide a standard set of controls that are well built, secure and easily reusable. The User Management Controls provided by ASP.NET 2.0 attempt to perform just this function. The controls included are:

    Table 3

    Control NameDescription
    LoginProvides the functionality for a user to login and logout of the application
    CreateUserWizardProvides the standard registration page for a new user to register. The functionality can be easily extended. For instance a registration email with necessary information can be sent after the registration is completed
    PasswordRecoveryProvides a highly configurable control to perform a set of actions when the user forgets his password. The actions performed range from emailing a password reminder to sending the existing password itself in clear text.
    ChangePasswordProvides a way for the users to change their passwords. The MailDefinition property will notify the user once the password has been updated
    LoginNameProvides the authenticated user's registered name, which can be displayed back to the user in the application
    LoginStatusDetermines the authentication status of the user and can accordingly display the login or the logout link
    LoginViewManages the view of the user depending on the role and privilege of the current user
  • Configuration File Encryption—In the .NET Framework 2.0, developers will be able to encrypt sensitive parts of the web.config file (if containing password or keys, for instance) using the aspnet_regiis utility. The decryption is done transparently. The DPAPI protected configuration provider supports machine-level and user-level stores for key storage. The choice of store depends largely on whether or not the application shares state with other applications and whether or not sensitive data must be kept private for each application. If the application is deployed in the Web farm scenario, developers should use RSAProtectedConfigurationProvider to leverage the ease with which RSA keys can be exported on multiple systems. It uses RSA public key cryptography to provide data confidentiality.

    The following example encrypts the connection string section using the tool aspnet_regiis:

    Listing 4

    aspnet_regiis.exe -pef "connectionStrings" C:\VirtualDirectory\Path

    Reference:
    How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI

  • Role Manager—The role manager in v2.0 of the Framework provides out of the box support for role-based access control (RBAC). The RoleManagerModule class is used to assign a RolePrincipal to the User property of the current HTTPContext. If the request is successful, the RoleManagerModule reassigns the cookies that now contain cached role information.

    Reference:
    RoleManagerModule Class

  • Web Site Administration Tool—The ASP.NET Web Site Administration Tool allows you to view and manage your Web site configuration through a simple Web interface. The Web Site Administration tool can be used to create new users and roles and control access to folders and individual pages of the Web application. The aspnet_regiis tool can be used to control access to the Web site administration tool. One instance would be to only allow access to the administration tool on the local machine.

    Reference:
    Cube Analyzer (Decision Support Objects)

  • URL Authorization—URL Authorization can be used to restrict access to specific paths by defining those in the web.config and mapping them to specific users or roles. In 1.* versions of the .NET Framework this could only be done for resources controlled by the ASP.NET runtime such as .aspx pages. In the .NET Framework 2.0, this has been extended to non-ASP.NET file types as well for instance .jpg or .html.

C/C++

The most common security problem specific to unmanaged code is buffer overflows. Buffer overflows occur when the data entered in the buffer is larger than the size allocated to it. This results in the overwriting of other sections of memory. This way an attacker can inject and execute malicious code causing damaging effects. The new features of the Visual Studio IDE provide mechanisms to help detect and eliminate many instances of this vulnerability. They also provide tools to spot other kinds of errors and bugs that may otherwise be ignored by the compiler.

  • Stack-Based Buffer Overflow Detection—The /GS flag can be used during compilation to mitigate some classes of buffer overruns. It is capable of detecting buffer overflow attempts that overwrite the return address—a common technique for exploiting code that does not enforce buffer size restrictions. This is achieved by injecting security checks into the compiled code. This flag is on by default even if the /GS option is not explicitly mentioned in the command line for the compiler.

    If the attacker can overflow the local buffers she would be able to overwrite the exception handler frame, the frame pointer, and the function return address. This is essentially a buffer overflow condition that is commonly known as stack smashing.

    When the code is compiled with the /GS flag, for every function call, the prolog of the function retrieves a random 4 byte value from a pre-defined location. This random value is then XORed with the return address of the function to be called and is inserted on the stack below the return address. When the function is about to return the epilog of the function once again XORs the return address from the stack with the cookie stored below the return address. If the result matches the original value stored at the predefined location, it is an indication that the return address has not been tampered with and the execution continues. If the values do not match, the program jumps to a security error handler function and exits.

    In addition, since Visual C++ .NET 2003, vulnerable and sensitive data structures, such as the address of exception handlers were moved to a position in the call stack below the area where buffers are located. This helps prevent bypassing the protection offered by the security cookie by corrupting exception handler pointers for instance. By moving this data to a region below the buffers in the new compiler version, modifying this data with buffer overruns is no longer possible. Further, the linker in Visual C++ .NET 2003 and above also inserts the address of all structured exception handlers into the executable header. Thus, when an exception occurs, the operating system compares the address of the exception handler referenced on the stack to that in the executable's header. If the two do not match the handler will not be allowed to execute thus preventing the execution of potentially arbitrary injected code. Windows Server 2003 and Windows XP Service Pack 2 both have this ability built in.

    Reference:
    /GS (Buffer Security Check)

  • SafeCRT Libraries and Integer Overflow Protection—These libraries include changes to the standard C/C++ runtimes where specific functions were found to have unsafe design. These functions have been deprecated and replaced by newer, safer ones. Compiler warnings are issued to indicate use of unsafe functions. Extra debugging information is also added wherever it can help. The library has been submitted to ANSI for ISO standardization.

    The new allocation operator has also been enhanced to check for integer overflows when allocating large blocks or memory—typically arrays of objects. The C++ compiler that will ship with Visual Studio 2005 will emit code into the executable to check for such conditions and either return NULL or throw an exception depending on the operator's error semantics.

    Reference:
    Repel Attacks on Your Code with the Visual Studio 2005 Safe C and C++ Libraries

Visual Basic .NET

The My object introduced in the new Framework exposes easy-to-use methods for many tasks.

  • My Classes—These classes attempt to provide access to a number of key properties enumerated below for the currently logged on user through an easily accessible and intuitive interface.

    Table 4

    PropertyDescription
    My.User.IsAuthenticatedReturns true to indicate if the use is authenticated, otherwise false.
    My.User.CurrentPrincipal.IdentityGets or sets the current principal for role-based security.
    My.User.IsInRoleDetermines if the current user belongs to a specified role. Returns true if the current user is of the role specified otherwise false.
    My.User.NameGets the name of the current user.

Cryptography

Cryptography can very easily become the most difficult aspect of application and software security to understand and even more difficult to implement. Most developers do not understand and do not want to understand the significance and specifics of random number generators, key generation, encryption, signatures, and secure data storage. Developers would ideally like well-defined APIs that they can use to incorporate cryptography to provide features such as confidentiality, integrity and non-repudiation within their application. The .NET Framework provides many such classes and methods to ease the job of developers. They take most of the burden away from the implementation phase of the development lifecycle. There are some significant additions made to the cryptography related APIs in the upcoming version of the .NET Framework. We discuss some of them here.

  • Public-Key Cryptography Standards (PKCS#7)—These new classes provide the capability to sign and encrypt messages. The standards support the use of X.509 certificates for encrypting and decrypting data. The message generated conforms to the well-defined S/MIME standard that enables the message to be transmitted via e-mail. Further, support for X.509 certificates has also been enhanced with the X509Certificate2 object.

    Listing 5

    . . . 
    . . . 
    . . . 
    static void Main(string[] args)
    {
       byte[] originalMsg;
       const String msg = "Sensitive message in the String";
       Encoding unicode = Encoding.Unicode;
       byte[] msgBytes = unicode.GetBytes(msg);
       X509CertificateEx signerCert = GetSignerCert();
       X509CertificateEx recipientCert = GetRecipientCert();
       /* For Sender */
       byte[] encodedSignedCms = SignMsg(msgBytes, signerCert);
       byte[] encodedEnvelopedCms = EncryptMsg(encodedSignedCms, recipientCert);
       
       /* For Receiver */
       encodedSignedCms = DecryptMsg(encodedEnvelopedCms);
       VerifyMsg(encodedSignedCms, out origMsg));
       unicode.GetString(origMsg));
    }
    static public X509CertificateEx GetSignerCert()
    {
    . . . 
    . . .
    X509Store storeMy = new X509Store(StoreName.My,
    StoreLocation.CurrentUser);
    ...
    //  Find the signer's certificate.
    X509CertificateExCollection certColl =
    storeMy.Certificates.Find(X509FindType.FindBySubjectName,
    signerName, false);
    ...
    return certColl[0];
    }
    
    static public X509CertificateEx GetRecipientCert()
    {
    //  Open the AddressBook local user X509 certificate store.
    X509Store storeAddressBook = new X509Store(StoreName.
    AddressBook, StoreLocation.CurrentUser);
    storeAddressBook.Open(OpenFlags.ReadOnly);
    ...
    //  Get recipient certificate.
    X509CertificateExCollection certColl = storeAddressBook.
    Certificates.Find(X509FindType.FindBySubjectName,
    recipientName, false);
    ... 
    return certColl[0];
    }
    static public byte[] SignMsg(Byte[] msg, X509CertificateEx signerCert)
    {
    // Place message in a ContentInfo object.
    // This is required to build a SignedCms object.
    ContentInfo contentInfo = new ContentInfo(msg);
    
    // Instantiate SignedCms object with the ContentInfo 
    // above.
    // Has default SubjectIdentifierType IssuerAndSerialNumber.
    // Has default Detached property value false, so message is 
    // included in the encoded SignedCms.
    SignedCms signedCms = new SignedCms(contentInfo);
    
    // Formulate a CmsSigner object, which has all the needed
    // characteristics of the signer.
    CmsSigner cmsSigner = new CmsSigner(signerCert);
    
    // Sign the PKCS #7 message.
    signedCms.ComputeSignature(cmsSigner);
    
    // Encode the PKCS #7 message.
    return signedCms.Encode();
    }
    
    static public bool VerifyMsg(byte[] encodedSignedCms,
    out byte[] origMsg)
    {
    
    // Prepare a SignedCms object in which to decode
    // and verify.
    SignedCms signedCms = new SignedCms();
    …
    signedCms.Decode(encodedSignedCms);
    …
    // Verify signature. 
    signedCms.CheckSignature(true);
    
    origMsg = signedCms.ContentInfo.Content;
    return true;
    }
    
    static public byte[] EncryptMsg(Byte[] msg, X509CertificateEx recipientCert)
    {
    // Place message in a ContentInfo object.
    // This is required to build an EnvelopedCms object.
    ContentInfo contentInfo = new ContentInfo(msg);
    
    // Instantiate EnvelopedCms object with the ContentInfo
    // above.
    // Has default SubjectIdentifierType IssuerAndSerialNumber.
    // Has default ContentEncryptionAlgorithm property value
    // RSA_DES_EDE3_CBC.
    EnvelopedCms envelopedCms =
    new EnvelopedCms(contentInfo);
    
    // Formulate a CmsRecipient object that
    // represents information about the recipient
    // to encrypt the message for.
    CmsRecipient recip1 = new CmsRecipient(
    SubjectIdentifierType.IssuerAndSerialNumber,
    recipientCert);
    
    // Encrypt the message for the recipient.
    envelopedCms.Encrypt(recip1);
    
    // The encoded EnvelopedCms message contains the encrypted
    // message and the information about each recipient that
    // the message was enveloped for.
    return envelopedCms.Encode();
    }
    
    // Decrypt the encoded EnvelopedCms message.
    static public Byte[] DecryptMsg(byte[] encodedEnvelopedCms)
    {
    // Prepare object in which to decode and decrypt.
    EnvelopedCms envelopedCms = new EnvelopedCms();
    
    // Decode the message.
    envelopedCms.Decode(encodedEnvelopedCms);
    
    // Decrypt the message for the single recipient.
    envelopedCms.Decrypt(envelopedCms.RecipientInfos[0]);
    return envelopedCms.Encode();
    }
    

    References:
    Exploring What's New in the CLR 2.0
    Enveloped and Signed CMS/PKCS #7 Message
    X509Certificate2 Class

  • SecureString—This class stores data using the Data Protection API (DPAPI). Data is always in its encrypted form while it is stored inside of a SecureString. It is decrypted only when the data is accessed. This limits the exposure of sensitive information. Further, the .NET 2.0 Framework ensures that the garbage collector does not move such secure strings around in memory. SecureString also inherits from CriticalFinalizerObject, which ensures that the memory where the encrypted string was stored is zeroed out several times and then garbage collected as soon as possible. [This CriticalFinalizerObject class is available for custom classes to inherit from as well for deterministic garbage collection. See CriticalFinalizerObject Class.] It is also possible to make a secure string instance read-only so that it may not be modified. Secure strings do not allow inspection, comparison, or conversion of its instances. Developers have to convert the secure string to a binary string to be able to manipulate or compare the value of a SecureString object. Converting a SecureString to a String defies the purpose of using a SecureString. Once a SecureString object is copied to String object the value will be present in memory and all the risks associated with using the String class will now be applicable. For example, if the password is read from a text box, the .Text property will return the value as a String and copying it to a SecureString class will not provide any more security at that point. This is due to the fact that strings are immutable and by default the garbage collector is non-deterministic. Methods such as Process.Start, for instance, have been overloaded to accept SecureString objects. However, significant code still remains such as the .Text property of a textbox that still return a regular string.

    Listing 6

    bool Login() 
    {
    string loginName;
    SecureString password;
    bool successful = false;
    ...
    
    ReadLoginName(loginName);
    while(true) {
       ConsoleKeyInfo keypressed = Console.ReadKey(true);
       if (keypressed == ConsoleKey.Enter)
          successful = VerifyLogin(loginName, password);
       else 
          password.AppendChar(keypressed.KeyChar);
    }
    password.Clear();
    return successful;    
    }

    Reference:
    SecureString Class

  • ProtectedMemory—The class provides methods for encrypting sensitive data in memory. This will prevent exposure of sensitive information in the event of memory dump or if another application is trying to access the sensitive information in an applications process space. The class provides two wrappers for unmanaged data protection API called Protect and Unprotect. The Protect method encrypts the data and places the result in the same memory. The Unprotect method decrypts the memory and provides the result in the same variable. The data needs to be a multiple of 16 bytes. A similar class ProtectedData can be used to protect persistent data saved to disk.

    Reference:
    ProtectedMemory.Protect Method

  • XML Encryption—EncryptedXml is the main class used for XML encryption in the .NET Framework. This class implements the World Wide Web Consortium (W3C) specification for XML encryption. While the input to this class implementation does not have to be XML, the output is. It also allows to encrypt portions of an XML document or to encrypt different portions of the same document with different keys. It can work in conjunction with XML digital signatures.

    Listing 7

    void () 
    {
    ... 
    xmlDoc.Load("PersonalInfo.xml");
    ...
       
    // Create a new TripleDES key. 
    TripleDESCryptoServiceProvider tDESkey = new TripleDESCryptoServiceProvider();
    
    // Encrypt the "SSN" element.
    Encrypt(xmlDoc,tDESkey,"SSN");
    
    // Decrypt the encrypted element.
    Decrypt(xmlDoc,tDESkey);
    }
    
    public void Encrypt(XMLDocument docValue,TripleDES algValue, string Element) 
    { 
    // Find the element by name and create a new 
    // XmlElement object. 
    XmlElement inputElement = docValue.GetElementsByTagName(Element)[0] as    XmlElement; 
    
    // Create a new EncryptedXml object. 
    EncryptedXml exml = new EncryptedXml(docValue); 
    
    // Encrypt the element using the symmetric key. 
    byte[] rgbOutput = exml.EncryptData(inputElement, algValue, false); 
    
    // Create an EncryptedData object and populate it. 
    EncryptedData ed = new EncryptedData(); 
    
    // Specify the namespace URI for XML encryption 
    // elements. 
    ed.Type = EncryptedXml.XmlEncElementUrl; 
    
    // Specify the namespace URI for the TrippleDES 
    // algorithm. 
    ed.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncTripleDESUrl); 
    
    // Create a CipherData element. 
    ed.CipherData = new CipherData(); 
    
    // Set the CipherData element to the value of the 
    // encrypted XML element. 
    ed.CipherData.CipherValue = rgbOutput; 
    
    // Replace the plaintext XML elemnt with an 
    // EncryptedData element. 
    EncryptedXml.ReplaceElement(inputElement, ed, false); 
    }
    
    public void Decrypt(XMLDocument docValue,TripleDES algValue) 
    { 
    
    // XmlElement object. 
    XmlElement encryptedElement = docValue.GetElementsByTagName("EncryptedData")[0] as XmlElement; 
    
    // Create an EncryptedData object and populate it. 
    EncryptedData ed = new EncryptedData(); 
    ed.LoadXml(encryptedElement); 
    
    // Create a new EncryptedXml object. 
    EncryptedXml exml = new EncryptedXml(); 
    
    // Decrypt the element using the symmetric key. 
    byte[] rgbOutput = exml.DecryptData(ed, algValue); 
    
    // Replace the encryptedData element with the plaintext 
    // XML elemnt. 
    exml.ReplaceData(encryptedElement, rgbOutput); 
    }
    

    Reference:
    EncryptedXml Class

  • XML Signatures—The SignedXML class that implements the World Wide Web Consortium (W3C) specification for XML signature and verification is the main class used for XML digital signatures in the .NET Framework. It provides an interoperable way to sign and verify all or part of an XML document or other data that is addressable from a Uniform Resource Identifier (URI).

    Listing 8

void example () 
{
SignXmlFile("Example.xml", "signedExample.xml", Key);
bool result = VerifyXmlFile("SignedExample.xml", Key);
}

// Sign an XML file and save the signature in a new file. This method 
// does not save the public key within the XML file. This file cannot be 
// verified unless the verifying code has the key with which it was 
// signed. 

public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) 
{ 
// Create a new XML document. 
XmlDocument doc = new XmlDocument(); 

// Load the passed XML file using its name. 
doc.Load(new XmlTextReader(FileName)); 

// Create a SignedXml object. 
SignedXml signedXml = new SignedXml(doc); 

// Add the key to the SignedXml document. 
signedXml.SigningKey = Key; 

// Create a reference to be signed. 
Reference reference = new Reference(); 
reference.Uri = "http://www.foundstone.com"; 

// Add an enveloped transformation to the reference. 
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 
reference.AddTransform(env); 

// Add the reference to the SignedXml object. 
signedXml.AddReference(reference); 

// Compute the signature. 
signedXml.ComputeSignature(); 

// Get the XML representation of the signature and save 
// it to an XmlElement object. 
XmlElement xmlDigitalSignature = signedXml.GetXml(); 

// Append the element to the XML document. 
doc.DocumentElement.AppendChild(doc.ImportNode (xmlDigitalSignature, true)); 

if (doc.FirstChild is XmlDeclaration) 
{ 
doc.RemoveChild(doc.FirstChild); 
} 

// Save the signed XML document to a file specified 
// using the passed string. 
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); 

doc.WriteTo(xmltw); 
xmltw.Close(); 
}

// Verify the signature of an XML file against an asymetric 
// algorithm and return the result. public static Boolean 

VerifyXmlFile(String Name, RSA Key) 
{ 
// Create a new XML document. 
XmlDocument xmlDocument = new XmlDocument(); 

// Load the passed XML file into the document. xmlDocument.Load(Name); 

// Create a new SignedXml object and pass it 
// the XML document class. 
SignedXml signedXml = new SignedXml(xmlDocument); 

// Find the "Signature" node and create a new 
// XmlNodeList object. 
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature"); 

// Load the signature node. 
signedXml.LoadXml((XmlElement)nodeList[0]); 

// Check the signature and return the result. 
return signedXml.CheckSignature(Key); 
}

Reference:
SignedXml Class

  • FIPS Enforcement—This ensures that only algorithms compliant with FIPS 140-1 are used. If not, an exception gets raised. This needs to be used in combination with a Windows XP SP2 policy setting and is likely to be useful in high security environments, for instance, within the defense and government sectors for instance.

    Reference:
    .NET Security Blog: Enforcing FIPS Certified Cryptography

  • Password Based Key Derivation Function—This provides an implementation of RFC 2898 and allows the developers to use a password to encrypt a block of data by using the password to generate a symmetric key.

    Listing 9

    byte[] salt = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
    Rfc2898DeriveBytes  pdb = new Rfc2898DeriveBytes ("*S3cr3Tk3Y*", salt);
    // Encrypt the data.
    TripleDES encAlg = TripleDES.Create();
    encAlg.Key = pdb.GetBytes(16);
    
    //Use key and encrypt
    
    pdb.Reset();

    Reference:
    PasswordDeriveBytes Class

  • Larger Strong Name Keys—The SN tool (sn -k) can support key of size up to 16,384 bits. This allows for keys that are longer and hence less likely to be disclosed via a brute forcing attack. It also permits application developers to comply with widely accepted best practices some of which are discussed in the references below.

    References:
    Selecting Cryptographic Key Sizes (1999)
    Strong Name Tool (Sn.exe)

Managed Code

Managed code is code written in one of the several languages supported by the .NET Framework. These languages share a unified set of class libraries and when compiled generate Intermediate Language (IL) code rather than native machine code directly. At runtime, this IL code is JIT (just-in-time) compiled into native code. Memory management, among other key functions, is handled by the common language runtime rather than individual programs—hence the "managed" classification. Use of managed code allows developers to avoid common security vulnerabilities that can lead to a compromised system. However, at the same time managed code is not a panacea. Even when written in a managed language, an application can still be susceptible to gaping vulnerabilities. The .NET Framework 2.0 provides some new features to better equip developers for them to develop more secure applications. It provides mechanisms for in-depth defense that will limit the damage even if an application is compromised. Next we discuss some of these new security features.

  • Process Handling—Process.Start now has an overload that allows developers to execute an application in the context of some other user without having to deal with the LogonUser API or performing any kind of native platform calls. By specifying its file name, user name, password, and domain, the new process and its primary thread are created.

    Listing 10

    public static Process Start ( string fileName, string arguments, 
    string userName, SecureString password, string domain )
    
       filename : Name of the application file that is to be executed
       arguments: Command line arguments for the process to be executed
       userName: The user name to use for starting the process
       password: Password corresponding to the username specified as a securestring object
       domain: The domain to use for starting the process

    Reference:
    Process.Start Method (String, String, SecureString, String)

Windows Server 2003 Kerberos Extensions

  • Protocol Transition—The protocol transition extension allows a service that uses Kerberos to obtain a Kerberos service ticket on behalf of a Kerberos principal to the service without requiring the principal to initially authenticate to the Kerberos Key Distribution Center (KDC) with credentials. This means that the developer will be able to use non-Kerberos authentication mechanism to authenticate the application users and later be able to generate Windows tokens using the WindowsIdentity constructor with just the user name and without the password. The caller process that uses protocol transition must have both the "Impersonation Privilege" and "Act as Part of Operating System" privileges to be able to impersonate another user.
  • Constrained Delegation—The constrained delegation extension allows a service to obtain service tickets (under the delegated users identity) to a subset of other services after it has been presented with a service ticket that is obtained either through the TGS_REQ protocol, as defined in IETF RFC 1510, or using the protocol transition extension discussed above. For a service account to use protocol transition with constrained delegation, a new control flag called Trusted-to-Authenticate-for-Delegation (T2A4D) needs to be set. This flag is set on the service account in the Active Directory.

    Reference:
    Kerberos Protocol Transition and Constrained Delegation

  • Authentication—Applications can use the new NegotiateStream and SslStream classes for authentication and to help secure information transmitted between a client and a server. These authenticated stream classes support mutual authentication, data encryption, and data signing. The NegotiateStream class uses the Negotiate security protocol for authentication and provides a managed wrapper for SSPI functionality that will attempt the use of Kerberos first and if that fails fall back to NTLM. After authentication is completed, a secure channel is established ensuring that any data communicated will be integrity protected using message authentication code and encrypted. The SslStream class uses the X.509 certificates for authentication. It allows the client to check for server certificate revocation and provide a client certificate for mutual authentication. After the authentication is completed, a shared session key is established and all the future communication will be integrity protected and encrypted.

    References:
    SslStream Class
    NegotiateStream Class
    Security Enhancements in the .NET Framework 2.0

  • Secure Remoting Channels—The IPC channel is new in remoting. The advantages of this channel are that it uses named pipes for communication and therefore these can be ACLed fairly easily. Also this channel is only accessible from the local machine. Hence it can only be used if the remoting server and the client are on the same physical machine. The TCP channel also now supports authentication and encryption using SSPI. Further it is possible to identify the caller and run with the permissions associated with the caller's identity.

    Listing 11

    <configuration> 
       <system.runtime.remoting> 
          <application> 
             <channels> 
                <channel ref="tcp" 
                      impersonationLevel="Identify" 
                      authenticationPolicy="Policy, policy" /> 

    Reference:
    Authentication with the TCP Channel

  • Managed Access Control Lists—The System.Security.AccessControl namespace provides access to all native Windows access control objects such as SACLs, DACLs, ACEs, and SIDs. The managed ACL API makes working with ACLs far easier by providing several methods that can be used to get and set ACLs for every resource. One potential use of a managed ACL would be to build application specific authorization over logs files that can be configured by the administrator of the application dynamically without having to deal with the native Windows file permission dialog but in the context of application specific users and roles.

    Listing 12

    void Main() 
    {
    ...
    ...
    string filename = "logfile.txt";
    /* Add Permission */
    ProvideAccessToFile(filename, @"DomainName\AccountName", 
    FileSystemRights.AppendData, AccessControlType.Allow);
    
    
       /* Remove Permission */
       RemoveAccessToFile(filename, @"DomainName\AccountName", 
       FileSystemRights.AppenData, AccessControlType.Allow);
    ...
    ...
    }
    
    void ProvideAccessToFile(string fileName, string accountInfo, 
    FileSystemRights permissions, AccessControlType accessControl) 
    {
       // Get a FileSecurity object that represents the current security settings. 
       FileSecurity fSecurity = File.GetAccessControl(fileName); 
       // Add the FileSystemAccessRule to the security settings. 
       fSecurity.AddAccessRule(new FileSystemAccessRule(accountInfo, 
       permissions, accessControl)); 
       // Set the new access settings. 
       File.SetAccessControl(fileName, fSecurity);
    }
    
    void RemoveAccessToFile(string fileName, string accountInfo, FileSystemRights permissions, AccessControlType accessControl) 
    {
    // Get a FileSecurity object that represents the // current security 
    settings. FileSecurity fSecurity = File.GetAccessControl(fileName); 
    
    // Add the FileSystemAccessRule to the security settings. 
    fSecurity.RemoveAccessRule(new FileSystemAccessRule(accountInfo, 
    permissions, accessControl)); 
    
    // Set the new access settings. 
    File.SetAccessControl(fileName, fSecurity);
    }

    Reference:
    MiningModel.Properties Property

  • Execution Context—This new class allows the programmer to control the execution of threads. It provides all the relevant information pertaining to the execution of a thread. It also includes the security context, call context, synchronization context, localization context, and transaction context. The developer has the flexibility to capture this context information and potentially transfer it from the current thread to another thread.

    Listing 13

    static void Callme(object obj) 
    {
     // The security context does not from the previous threat
    // The threads executes under the privileges of the process owner
    Console.WriteLine("The process is executing under the permissions of 
    {0}", WindowsIdentity.GetCurrent().Name);
    }
    
    Static void Main () 
    {
    IntPtr accessToken = IntPtr.Zero;
    If (LogonUser("UserName","Foundstone", "Password", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, accessToken)) 
    {
       WindowsImpersonationContext wic = WindowsIdentity.Impersonate(accessToken);
       executionContext.SupperFlow();
       ThreatPool.QueueUserWorkItem(Callme);
       wic.Undo();
    }
    ...
    ...
    }

    Reference:
    System.Security.AccessControl Namespace

  • Active Directory APIs—The System.DirectoryServices.ActiveDirectory namespace provides easy access to Active Directory Service Interfaces (ADSI) style APIs in the managed world allowing developers to perform AD management tasks. Active Directory service concepts such as forest, domain, site, subnet partition, and schema are part of this object model.

    Reference:
    System.DirectoryServices.ActiveDirectory Namespace

Tools Support

Finally, the .NET Framework and the Visual Studio 2005 equip the developers and testers with a number of other tools and utilities that can help debug and test the applications in a more efficient and comprehensive manner. Some of them enforce policies while the others perform static and run time checks. Visual Studio 2005 also provides powerful team edition for developers and tester to collaborate and increase the productivity. We briefly discuss some of the key new tools here:

  • FxCop—FxCop is a code analysis tool that checks .NET managed code assemblies for conformance to Microsoft .NET Framework Design Guidelines. It is built to detect over 200 defects including SQL injection, permissions problems and strong name issues. For a complete list of security rules please visit the references below.

    References:
    FxCop on GotDotNet
    Visual Studio Team System Walkthrough: Analyzing Managed Code for Code Defects

  • PREfast—This tool is performs static source code analysis to detect some categories of errors and bugs. In most cases, a compiler does not catch these errors. The tool works on applications built in C/C++ and is capable of performing checks for security vulnerabilities such as buffer overruns, un-initialized memory and memory leaks.

    Reference:
    PREfast

  • Standard Annotation Language—SAL as it is popularly known allows definition of what assumptions a function makes about its parameters as well as the side-effects it will have after it is done. The compiler can then use this information to auto-generate key validation routines to enforce these declarations.

    Reference:
    SAL Annotations

  • Application Verifier—This is a set of standard checks that can be used during the application testing process. It focuses on detecting the common issues that deal with application security and quality such as heap corruption, invalid handles usage, locks usage, file paths, and registry checks. It is only meant for use with unmanaged code.

    Reference:
    Windows Application Verifier

  • Code Coverage & Stress Testing—Visual Studio Team Edition provides several capabilities to enable both the developers and the testers produce better quality of products. Some of the features include the ability to manage test, evaluate code coverage, perform Web testing, and run load and stress test. These features will help identify hot spots that are frequently executed as well as dead code and pieces of code that are rarely reached and therefore may not be adequately tested. For instance, the Web testing tool, allows the development team to record entire Web sessions within the browser and then potentially replay them or perhaps extract valuable information that is likely to lead to system compromise.

    Reference:
    Visual Studio Team System Developer Center: Software Testers

Conclusion

In this paper we have attempted to survey some of the major changes in Microsoft .NET Framework 2.0 and Visual Studio 2005. Our intention was to gather this information and present it in one clear and concise source. While we have not listed every security-significant feature, we have attempted to provide sufficient details and links to further information on these and other facets of this release. Readers are advised to follow these links for detailed coverage of each feature described above, as well as to obtain information about those not discussed here.

In conclusion, it is important to note that the wealth of features available in the .NET Framework and the tools that accompany it are not a silver bullet and do not absolve developers from focusing on security within their own applications. Rather, these features are intended to make it easy for development teams to do the "right" thing, from a security perspective.

Appendix of References

CategoryTopicReference(s)
Partial Trust DevelopmentEnhanced SecurityExceptionhttp://msdn2.microsoft.com/en-us/library/yx0zh807.aspx
 Debug in Zonehttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/vs05security.asp
 PermCalchttp://msdn2.microsoft.com/en-us/library/ms165077
 IntelliSense in Zonehttp://msdn2.microsoft.com/en-us/library/cxy240ac.aspx
 Simple Sandboxing API using AppDomainshttp://msdn2.microsoft.com/en-us/library/ms130766
Code Access SecurityFull Trust GAChttp://blogs.msdn.com/shawnfa/archive/2005/02/10/370743.aspx
 FullTrust means Full Trusthttp://blogs.msdn.com/eugene_bobukh/archive/2005/05/06/415217.aspx
 Security Transparencyhttp://blogs.msdn.com/shawnfa/archive/2005/08/31/458641.aspx
  http://blogs.msdn.com/shawnfa/archive/2005/09/09/462975.aspx
 ApplicationSecurityManagerhttp://msdn.microsoft.com/msdnmag/issues/04/05/clickonce/default.aspx

http://develop.com/us/downloads/DM_Clickonce.pdf

 LinkDemandChoice 
 GacMembershipCondition

CodeConnectAccess/NetCodeGroup

http://msdn2.microsoft.com/library/bs03hw31(en-us,vs.80).aspx
  http://msdn2.microsoft.com/en-us/library/6wh076wh(en-US,VS.80).aspx
  http://msdn2.microsoft.com/en-us/library/97fzw93d.aspx
 Code Access Security Permissionshttp://msdn2.microsoft.com/en-us/library/87s2x3z7(en-us,vs.80).aspx
  http://msdn2.microsoft.com/en-us/library/7sk936tt(en-us,vs.80).aspx
 HostProtectionResourcehttp://msdn2.microsoft.com/en-us/library/wxd64h1c(en-us,vs.80).aspx
  http://msdn2.microsoft.com/en-us/library/s4tw8178(en-US,VS.80).aspx
  http://msdn2.microsoft.com/en-us/library/bk0z5tde(en-US,VS.80).aspx
  http://msdn2.microsoft.com/en-us/library/zt5bfyda.aspx
 Membershiphttp://msdn2.microsoft.com/en-us/library/ms181971.aspx
Configuration File Encryptionhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000005.asp
ASP.NETRole Managerhttp://msdn2.microsoft.com/en-us/library/c3es4xha.aspx
 Web Site Administration Toolhttp://msdn2.microsoft.com/en-us/library/ms133902.aspx
C/C++Stack Protectionhttp://msdn2.microsoft.com/en-us/library/8dbf701c.aspx
 SafeCRT Librarieshttp://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
CryptographyPublic-Key Cryptography Standards (PKCS#7)http://download.microsoft.com/download/e/2/1/e216b4ce-1417-41af-863d-ec15f2d31b59/DEV290.ppt
  http://msdn2.microsoft.com/en-us/library/ms180952(en-US,VS.80).aspx
  http://msdn2.microsoft.com/en-us/library/ms148409.aspx
 SecureStringhttp://msdn2.microsoft.com/library/7kt014s1(en-us,vs.80).aspx
 XML Encryptionhttp://msdn2.microsoft.com/en-us/library/bh5h3ft3(en-US,VS.80).aspx
 XML Signatureshttp://msdn2.microsoft.com/en-us/library/3y0fth1d(en-US,VS.80).aspx
 FIPS Enforcementhttp://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx
 Password Based Key Derivation Functionhttp://msdn2.microsoft.com/en-us/library/zb9zth5a.aspx
 Larger Strong Name Keyshttp://citeseer.ist.psu.edu/lenstra99selecting.html
  http://msdn2.microsoft.com/en-us/library/k5b5tt23.aspx
Managed CodeProcess Handlinghttp://msdn2.microsoft.com/en-us/library/sxf2saat
 Windows Server 2003 Kerberos Extensionshttp://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/security/constdel.mspx
 Authentication http://msdn2.microsoft.com/en-us/library/d50tfa1c.aspx
  http://msdn2.microsoft.com/en-us/library/33t4bbc1.aspx
  http://msdn.microsoft.com/msdnmag/issues/05/01/SecurityBriefs/
 Secure Remoting Channelshttp://msdn2.microsoft.com/library/59hafwyt(en-us,vs.80).aspx
 Managed Access Control Listshttp://msdn2.microsoft.com/en-us/library/ms135841.aspx
 Execution Contexthttp://msdn2.microsoft.com/en-us/library/tbsb79h3.aspx
 Active Directory APIshttp://msdn2.microsoft.com/en-us/library/wwzcae1f.aspx
Tools SupportFxCophttp://www.gotdotnet.com/team/fxcop/
  http://msdn2.microsoft.com/en-us/library/ms182066(en-us,vs.80).aspx
 PREfasthttp://www.microsoft.com/whdc/devtools/tools/PREfast.mspx
 Source Code Annotation Languagehttp://msdn2.microsoft.com/en-us/library/ms235402.aspx
 Application Verifierhttp://www.microsoft.com/technet/prodtechnol/windows/appcompatibility/appverifier.mspx
 Code Coverage and Stress Testinghttp://msdn.microsoft.com/vstudio/teamsystem/tester/default.aspx

About The Authors

Rudolph Araujo

Rudolph Araujo is a Principal Software Security Consultant and trainer at Foundstone. At Foundstone, Rudolph is responsible for creating and delivering the threat modeling and security code review service lines. Rudolph is also responsible for content creation and training delivery for Foundstone's Building Secure Software and Writing Secure Code—ASP.NET class.

Rudolph has strong computer science fundamentals and many years of software development experience on both UNIX and Windows environments. Prior to joining Foundstone, Rudolph led the checks development team for BindView bv-Control for Internet Security—a vulnerability assessment product. He has also worked as a software developer at Morgan Stanley. Most recently, Rudolph has worked as a researcher at Carnegie Mellon University's CYLAB investigating virus and worm threats especially over peer-to-peer networks. His research interests also span the domain of Web service security and reliability.

Rudolph holds a Masters Degree from Carnegie Mellon University with a focus on information security and a Bachelors Degree in Computer Engineering from Goa University in India. He is an experienced C / C++ and C#/.NET developer and the author of Foundstone's .NET Security Toolkit, SSLDigger and Hacme Bank tools. Rudolph is also a presenter in MSDN Webcast series. Rudolph has been honored with the Microsoft Visual Developer—Security MVP Award in recognition of his thought leadership and contributions to the application security and developer communities. Rudolph is also a contributor to multiple online and print journals such as Software Magazine where he writes a column on writing secure code.

Shanit Gupta

Shanit Gupta is a Security Consultant and trainer at Foundstone. Shanit specializes in vulnerability assessment, penetration testing, Web application assessments, and secure software development initiatives.

Shanit has very strong computer-engineering fundamentals and many years of software development experience. Prior to joining Foundstone, Shanit was involved in developing real-time operating systems and the survivable prototype of Kerberos authentication service at Carnegie Mellon. Shanit also worked at Alcoa Inc., as a software developer building critical internal applications.

Shanit holds a Masters from Carnegie Mellon University with a focus on information security, and a Bachelors in Computer Science and Engineering from the Osmania University. He is an experienced C / C++ and C#/.NET developer, and is a project manager for the release of Foundstone free tools including Validator.NET, .NETMon, and CookieDigger.

Acknowledgements

We are grateful to Shawn Farkas and Mike Downen who through their respective blogs have taken it upon themselves to educate .NET developers about new security features in the .NET Common Language Runtime. A lot of the material in this paper has also been compiled based on discussions amongst the Microsoft Developer Security MVPs. We are also indebted to Ron Nguyen, Robert Deane and Nicholas Murison at Foundstone for helping with technical editing. Finally, thanks to Rick Samona, Mike Downen and Mike Howard at Microsoft for technically reviewing the paper.

About Foundstone Professional Services

Foundstone Professional Services, a division of McAfee, offers a unique combination of services and education to help organizations continuously and measurably protect the most important assets from the most critical threats. Through a strategic approach to security, Foundstone identifies, recommends, and implements the right balance of technology, people, and process to manage digital risk and leverage security investments more effectively.

Foundstone's Secure Software Security Initiative (S3i) services help organizations design and engineer secure software. By building in security throughout the Software Development Lifecycle, organizations can significantly reduce their risk of malicious attacks and minimize costly remediation efforts. Services include:

  • Source Code Audits
  • Software Design and Architecture Reviews
  • Threat Modeling
  • Web Application Penetration Testing
  • Software Security Metrics and Measurement

See the Foundstone Web site for more information about Foundstone S3i services.

Foundstone S3i training is designed to teach programmers and application developers how to build secure software and to write secure code. Classes include:

See the Foundstone Web site for the latest course schedule.

Page view tracker