Benefits of Upgrading to a .NET Framework 2.

0 solution

Security solutions offered by Visual Studio.NET 2005 (Whidbey)
Version 1.0 Chris Seary 17 May 2005

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 1 of 46

CONTENTS 1. 2. 2.1 2.2 2.3 2.4 2.5 3. 3.1 3.2 3.3 3.4 3.5 3.6 3.7 4. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 5. 5.1 5.2 EXECUTIVE SUMMARY SOME SECURITY ISSUES WITHIN LARGE ORGANISATIONS Identity management More complex security functionality Integration issues Skills required Malicious software THE WINDOWS DNA SECURITY MODEL Windows DNA architecture The different technologies used for securing a Windows DNA architecture Internet Information Services (IIS) Discretionary Access Control Lists (DACLs) COM+ security Security for Application Services Limitations of the Windows DNA security model SECURITY BENEFITS OF THE .NET SECURITY MODEL .NET Security Model Security features of the Windows DNA model Role based security checking HTTP Modules and separation of security functionality from the application Separation of IIS security context from web application security context Code Access Security Common Language Runtime (CLR) FURTHER BENEFITS FRO M UPGRADING TO .NET FRAMEWORK 2.0 Issues with .NET Framework 1.x New .NET Framework 2.0 features and improvements 2 3 4 4 5 6 6 7 8 8 8 8 9 9 9 9 11 11 11 11 11 12 13 13 15 15 15 17 17 18 20 20 21 25 26 28 29

APPENDIX A APPLYING .NET SECURITY FEATURES TO A WEB APPLICATION A.1 Role based security checking A.2 Security within an example application A.3 Flowing the identity of the user A.4 Introducing the trusted subsystem A.5 A trusted subsystem, certificate authentication and a custom security database A.6 Forms authentication A.7 Securing the principal object using Code Access Security A.8 Extending security functionality A.9 Summary APPENDIX C SECURITY GUIDANCE FOR UPGRADING TO A .NET ARCHITECTURE APPENDIX D CREATING CERTIFICATE S FOR TESTING XML DIGITAL SIGNATURES APPENDIX E CREATING A POLICY FILE TO SECURE A WEB APPLICATION THAT USES A CUSTOM HTTPMODULE


17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 2 of 46


♦ This white paper is directed at decision makers within any organisation that currently has a large investment in ASP/VB6 based web applications. ♦ There are many drawbacks from a security perspective when using the old COM based Windows DNA. They are mainly apparent in maintainability and implementation of more complex security functionality. ♦ There are many reasons for upgrading to a .NET solution, such as utilising WS-Security and ensuring compatibility with 64 bit operating systems. This document demonstrates that richer security functionality is offered by the .NET platform, which makes the development of secure applications easier and quicker than with VB 6.0. ♦ Visual Studio.NET 2005 (Whidbey) beta 2 is available now, and so this is an extremely good opportunity to move to the latest Microsoft development platform as VB 6.0 loses mainstream support. In 2001, many large scale applications around the world were being developed using .NET Framework 1.0 betas, several months before it was released to manufacture. In the same way, the benefits of upgrading to Framework 2.0 can be realised using the current beta versions. ♦ The body of the document covers o o o Security issues in large organisations The drawbacks of legacy applications regarding security The advantages of moving to .NET.

♦ The .NET security model is discussed in relation to how it overcomes the disadvantages of the DNA approach. Particular focus is given to the advantages of the next version of Visual Studio.NET (codenamed Whidbey) and .NET Framework version 2.0. This introduces a more complete security functionality which is extensible enough to stay current for the near future. ♦ Mainstream support by Microsoft for Visual Basic 6.0 will end in early 2005. This means that many organisations will be making decisions on the form and structure of their applications after this date. ♦ The appendices attached to this document give a technical perspective on the new .NET security model, with many detailed code examples. It is not necessary for IT decision makers to understand them. These are provided for demonstration to any technical staff contributing to the decision making process. ♦ Although primarily aimed at IT decision makers, this paper will be useful to those responsible for technical implementation of security. The appendices have a great deal of sample code, derived from both industry experience and recommendations by Microsoft. ♦ Appendix C gives advice for preparing to migrate to .NET version 2.0 as regards security.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 3 of 46


Identity management

Many large organisations, often in the public sector, have issues relating to identities of their clients. In the past, separate divisions within some organisations have created separate or overlapping relationships to the same individual. This has resulted in the user requiring more than one credential to access his/her details. In extreme cases, multiple identities have been created, as in the diagram below. These situations were generally the result of poor security practice.

Organisation Division A Division B

Identity 1

Identity 2

Individual In the diagram above, the individual has two identities within the organisation. If the organisation were the country’s revenue service, then this could mean that Joe Bloggs may appear as two completely separate identities when dealing with separate divisions. This could mean a lack of correlation between the Joe Bloggs in division A and the Joe Bloggs in division B. The implications of this are: ♦ It is harder to form a useful relationship with the individual. Each division has only one view of the person they are interacting with. Lacking the broader context of the user’s activities means that a holistic assessment of their activities cannot be realised. ♦ A potential avenue for fraud is available ♦ The individual has multiple security credentials to manage ♦ There is less consistency of authentication – for instance, one application may require username and password, whereas another may require certificates ♦ Cross-division processes are more complex within the organisation, and can lead to error ♦ Maintenance of security processes is more expensive

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 4 of 46

Organisation Centralised identity management Role A

Division A

Identity 1

Role B

Division B

Individual Many governments around the world are encouraging their public sector institutions to make all services available through just one identity for each user. In the second diagram the individual has only one identity, and this comes from a relationship between the individual and the organisation. The identity could be realised in a variety of ways, for instance: ♦ User details stored in a database ♦ An entity within a PKI ♦ An entity within a security directory (eg. Active Directory) ♦ An entity created from correlating all multiple related identities (a metadirectory) Centralised identity management may take the form of a metadirectory for correlating all of the historical identities for Joe Bloggs, but may use one data store for all new applications. The identities are managed centrally, and are mapped to each division or application through roles. The individual is mapped to one account within the organisation, and is given different roles for each service that they access. Implementation may require knowledge of: ♦ Infrastructure ♦ Databases ♦ Directory services


More complex security functionality

To update personal data, many organisations are now requiring more stringent proof of identity together with a requirement to assure non-repudiation when information is submitted. A common way to achieve this through a web application is to provide a downloadable applet (perhaps Java or ActiveX, depending on browser compatibility issues), allowing the user to use digital certificates to sign a message. This signature can be used to authenticate or provide non-repudiation for submitted data. Implementation requires knowledge of: ♦ Scripting languages (usually javascript)
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 5 of 46

♦ Applet creation (possibly Java if there are cross-platform requirements) ♦ Cryptographic principles (eg. How to assess the rules necessary for validating certificates) ♦ Cryptographic implementation (eg. Which function calls are necessary for validating certificates) ♦ Certificate management (eg. How Certificate Revocation Lists are to be retrieved)


Integration issues

Recent reports have shown that many large or medium sized organisations are keen to make more use of the IT functionality available within their organisation. This involves allowing disparate applications to communicate with each other, allowing the whole to become more than just the sum of its parts. One of the technologies used to facilitate this is web services. Web services pass XML over the HTTP protocol, and they are understood by most operating platforms. HTTP is not the only web service transport, but it is certainly the most popular. However, as Web Service security standards have become richer (and generally more complex), making different applications and platforms communicate has become more complex and expensive. Indeed, many of the implementations so far (such as earlier versions of WSE tools produced by Microsoft) will become redundant as the new standards are adopted . Organisations require methods for implementing web services which: ♦ are standardised ♦ use a less complex API ♦ have good development tools available ♦ are secure


Skills required

If each application within an organisation were to produce its own security functionality, at a minimum the following skills would be required within the development team: ♦ Infrastructure ♦ Databases ♦ Directory services ♦ Scripting languages ♦ Applet creation ♦ Cryptographic principles ♦ Cryptographic implementation ♦ Certificate management ♦ Security testing and validation This does not include any of the skills necessary for developing the application itself. If each application incorporates its own security functionality, then similar development work is likely to be repeated across different teams and is much less likely to be secure. Repeating critical security functionality across different teams may lead to inconsistency in its implementation. Poor security implementation is more likely to incur legal action than poor development in other areas (such as database access).

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 6 of 46


Malicious software

Many facts and figures are available for the disruption caused by malicious users across the internet. On report suggests that between 170 and 200 billion dollars is lost worldwide, and this figure is growing. Trojans introduced into a system may compromise a server by calling system functions or using system resources to interrupt services or extract information. Communications channels are often opened by the malicious software to facilitate more disruption. Developers themselves introduce some problems to code. One of the most common ways is to introduce a buffer overflow (described in section 3.7). Any tools that reduce these threats will have direct savings for any business that exposes its applications to the internet.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 7 of 46


Windows DNA architecture

There are many variations on a given theme, and Microsoft provided many tools and technologies for producing web applications. However, the most popular Windows DNA architecture included: ♦ ASP pages for the user interface hosted on Internet Information Server ♦ Visual Basic components for business and data access components, often using COM+ ♦ Database (SQL Server, Oracle etc.) This allowed web applications to be developed rapidly and required relatively less experience and programming knowledge on the part of the developers.


The different technologies used for securing a Windows DNA architecture

Implementation of Windows DNA (Distributed Network Architecture) security was often quite narrow in scope. Some articles on MSDN are no longer than two or three pages, covering security across all tiers of the application. The security features of any Windows application rely on the tools presented by the operating system. Although similar security features to that of .NET could be produced, this required a very high degree of skill and often required recourse to more ad vanced languages such as C++. There are four main security gatekeepers within the DNA model: ♦ Internet Information Services (IIS) ♦ NTFS permissions ♦ COM+ security ♦ Security features of application services such as SQL Server Although there are some very good implementations of these features, it was common to see homegrown security solutions created to satisfy more complex security requirements.


Internet Information Services (IIS)
♦ Anonymous ♦ Digest ♦ Basic ♦ Integrated Windows ♦ Certificates

IIS presents a number of authentication methods:

These integrate with the local SAM database or Active Directory (AD). Active Directory is often used for smaller, intranet based applications. It has very rich authentication capabilities, and integrates with the other security components mentioned here. However, it is not especially scalable. Even though Active Directory can potentially store very large numbers of users, manageability and maintenance becomes extremely impractical as it grows. It is often necessary to replace AD with another security principal repository, such as one designed using SQL Server. When working with a different security database most applications switched to Anonymous authentication. Thus, if a different security provider was used in order to achieve scalability, then the rich authentication capabilities of IIS were lost. It was certainly possible to link other security
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 8 of 46

repositories to Basic and Digest authentication, but this was a very complex task requiring specialist skills, and consequently this was rarely seen in the type of application discussed in section 3.1. Certificates could also be handled using tools provided by the Windows API, but mistakes in this type of implementation were (and still are) common. Using Anonymous authentication and creating a custom repository was the only way to make this type of application run as a trusted subsystem, consequently losing the ability to use Windows authentication. A trusted subsystem runs under one specific account, rather than flowing the user’s identity throughout the application. This is discussed further in section 4.5.


Discretionary Access Control Lists (DACLs)

DACLs are security access lists applied to objects within the Windows operating system. NTFS permissions are Discretionary Access Lists (DACLs) applied to files, but they can equally be applied to message queues or any other Windows resource. Access to objects is restricted to the list of users or groups in the DACL.


COM+ security

While DACLs control access to objects, COM+ services can restrict access to processes via roles. Members of a certain role would have access to components, or at a more granular level, the functions exposed by those components. This can be applied declaratively, via the Component Services applet, or programmatically using the methods available to COM+ objects.


Security for Application Services

Applications such as SQL Server provide their own security system. Thus, a user can be granted access to different objects within a database. SQL Server has rich and quite granular security functionality, but for distributed applications Microsoft recommends restricting access via stored procedures. This is especially true for web applications, where queries are often not conducted in the context of the logged on user.


Limitations of the Windows DNA security model

As noted earlier, if a different store is used for security principals (such as SQL Server) then complexity usually forces developers to forgo the rich authentication features provided by IIS. This generally means that the application will use Forms authentication only. The COM based model is susceptible to malicious code. Any Trojan introduced to the system is only restricted according to the user account it is running under, irrespective of where the code originated from. The trusted subsystem model (section 4.5) is not possible using ASP pages and Visual Basic components without sacrificing authentication functionality. This means that users have to be granted permissions for all of the application’s functionality if Windows authentication is required. Developers using languages such as C++ for development had the capability to introduce other anomalies – possibly the most common security hole introduced during coding is the buffer overrun. An application expecting an array of length x is actually passed an array of length x + y. The code in section y can introduce malicious function calls that compromise the application. The DNA security model lacks granularity. A user may be required to access details relating to user x but not to user y. This type of cross-entity access is not handled well by Active Directory, as it is a many to many relationship, which is not managed well in a hierarchical d atastore. Many security requirements go beyond application-specific security (see section 2.1), and relate to the organisation as a whole. There is no intrinsic model for separating security architecture from application architecture. This usually means that security functionality is part of each application, and thus upgrading this functionality means upgrading each application. If application A has its next upgrade scheduled for June, application B is scheduled for September, but new global security functionality (such as incorporating Biometric authentication) is legally required for April, then a new release for each
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 9 of 46

application will be required in April due to the tight coupling between authentication and the application that is inherent in an ASP/Visual Basic style application. Access to processes is based on access to components in much of the DNA model. What if a component was used within two different processes and the user only had access to the first process? An example would be a screen that is used for both creating records and also updating them. One way to restrict the user is to create two identical screens, with different DACLs applied. In order to use all of the functionality provided by web services, various components have been made available for Visual Basic 6.0. However, as mainstream support ends for this product in early 2005, there will be no updates of these components. This is already causing compatibility problems - the current VB6 WSE tools will not work alongside Indigo, the new messaging infrastructure for Longhorn, as the WS-* features are not compatible. Although Windows DNA security had some holes and lacked features, businesses were more concerned with functionality and gaining a presence on the internet than with the details of security. As threats posed by lack of security became more prevalent and business evolved more detailed security requirements, it became clear that new security tools would be required by many organisations.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 10 of 46


.NET Security Model

In 2002, .NET Framework 1.0 was released commercially. Along with Visual Studio.NET 2002, this introduced Microsoft’s commitment to a Service Oriented Architecture for distributed systems. This groups pieces of functionality together as services, with loosely connected communications between each service, improving factors such as scalability. The new technology introduced more advanced security tools which are much easier to implement: ♦ All of the abilities of the Windows DNA model ♦ Role based security separate to the context in which the application is running ♦ HTTP modules ♦ Separation of the IIS security context from the web application security context ♦ Code Access Security ♦ The Common Language Runtime (CLR)


Security features of the Windows DNA model

IIS authentication, NTFS file permissions and COM+ roles are still integral parts of the Windows security architecture. All of the previous advantages of these tools are still there to be used within a Service Oriented Architecture. By using attributes, the configuration of COM+ applications is a great deal easier, and can be controlled more tightly by the development team.


Role based security checking

ASP.NET constructs a principal object on each request and attaches it to the current context. This means that, as authentication takes place, the user identity and its associated roles are made available to the application. Before accessing application functionality, this role membership can be checked to make sure that the user has the appropriate permissions. The principal object can be replaced by a custom principal, which means that authentication and authorisation are quite extensible. The principal object created is quite separate from the identity that the application is running under. A web site may be running under one specific identity (as in a trusted subsystem), but the principal object will contain information about the user that is accessing the site. This means that the site can run under minimum privileges, but still be able to assess the membership of the user when checking permissions prior to calling resources. The principal object is not only an intrinsic part of the .NET security context, but can be replaced with a custom principal. This allows decoupling of authentication from the application, as no dependencies on components or interfaces are required to check role membership against the custom principal. As dependencies are removed, security functionality can be introduced to an application at a different time to the application’s next release phase. Global application of new security functionality is thus facilitated.


HTTP Modules and separation of security functionality from the application

In previous Microsoft architectures, interception of the request before it was processed by the application was achieved using ISAPI filters. This required knowledge of higher level programming languages. HTTPModules allow much of the functionality allowed by ISAPI filters, but with an easier and better documented programming model. This means that good practice is easier to develop and apply.
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 11 of 46

Using HTTP modules, the core security architecture for a web application can be separated from the application architecture. This means that design and testing of the security architecture can be accomplished by a dedicated specialist team, rather than being integrated into an overall development effort. Dependencies can be removed, so that a global change to security functionality across applications will not affect the individual release dates for each application. When using a different provider for storing principals, such as a database, an HTTP module can create the security context and apply it to the application, so that this context can flow through the application. Here are the steps for replacing the security context. ♦ As the browser request arrives at the web server, the HTTP module checks the authentication data. This could be done in a number of ways, such as checking user name and password or consulting the identity that was authenticated by IIS ♦ The HTTP module then consults SQL Server to obtain identity, role and other information for that user ♦ This information is used to construct a principal object ♦ The principal object of the application is then replaced by the new principal object ♦ Finally, the HTTP module hands over to the web application, which performs security checks against the replaced principal where required HTTP modules can also provide a reusable method for caching of security data, so that the security database is only queried once during the session. Information can be persisted, perhaps to an encrypted cookie, and then retrieved during each browser request. It is essential that good key management techniques are used in this instance, and good cryptographic practice applied.


Separation of IIS security context from web application security context

A .NET web application can run under a different security context from that authenticated by IIS, but still have access to the authentication information. This allows a web site to run as a trusted subsystem. This means that the application runs under only one identity, and access to other services and resources is via this identity only. Other services trust the system to make the correct decisions regarding authorisation. The immediate advantages are: ♦ Connection pooling is increased, which increases scalability ♦ Back end services and files are easier to lock down via Access Control Lists (ACLs), as there is only one identity requiring access to all resources ♦ Users cannot access data directly – it can only be accessed via the application ♦ The rich authentication functionality of IIS can still be used When flowing identity (as in Windows DNA), each security mechanism simply asks “do you have a specific role membership?” A trusted subsystem can have a richer, more granular system of security checks by using the context created by an HTTP module (section 4.3). By customising principal classes, the access checks can inspect both the membership of the user and which process is taking place; even taking into account which data is being updated. Another advantage of running under a different security account to that of the user is that the web application account is restricted to the functionality that the application specifically requires, rather than using the security permissions of the user. If the application performed some management function, such as altering Active Directory structure, the flowing of identity would require a great deal of management from the infrastructure side. The team maintaining Active Directory would have to
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 12 of 46

make sure that all of the relevant groups have the correct access to Active Directory – in some cases, this could even mean giving Domain Administrator rights! Great damage could be done by an individual with these rights if they chose to install the adminpak.msi to their system.


Code Access Security

Code Access Security (CAS) adds a layer of protection against the introduction of malicious code, which will not run as it is not able to prove its identity. This means that access to code can be restricted not only by the identity of the user, but also by the identity of the code. Malicious code cannot call application components if it does not provide the correct evidence, which can even be cryptographically verified. For instance, an application component may demand that any code calling it be signed using public key cryptography. Any code not correctly signed that tries to call the component will cause an exception to be thrown. Malicious code introduced to the system will not have access to the private key required for signing, and so will not have access to the application component. There are a variety of different types of evidence that can be used for assessing code identity, including software signing certificates and originating URL of code. A new level of security for an assembly is the Strong Name. This uses the private key from a private/public key pair to sign the code, and the public part is included in the assembly. Thus, code cannot be tampered with without violating the signature, or changing the evidence. Authenticode signatures can also be used as evidence, which links identity to a PKI. Four types of policy are created to control CAS: ♦ Enterprise – for all computers in the enterprise. Always applied. ♦ Machine – for the machine. Always applied. ♦ User – for the specific logged on user. Always applied. ♦ Domain – often not used. The example in Appendix E for an ASP.NET application is an example of a domain-level policy. A security permission must be granted in all of the applied policies for that permission to be available to the code providing evidence. Finally, the permissions granted to code can be locked down, restricting the actions that it can perform. For instance, access can be allowed or refused to: ♦ Specific file system folders ♦ SQL Server databases ♦ message queues ♦ Directory Services There are many other security restrictions that can be applied when locking down an application using CAS. This extra layer of security can help to prevent escalation of privilege attacks. Also, issues introduced by poor coding can be reduced by restricting what that code can access. However, it is also true that there are a number of core .NET assemblies that require full trust to run. In these cases, it is necessary to ‘sandbox’ code that makes certain function calls. This is dealt with in the document available on MSDN: ‘Building Secure ASP.NET Applications’.


Common Language Runtime (CLR)

This is a virtual machine that compiles .NET to native code at runtime, and performs security checks as it does so. Code written with .NET languages is compiled down to MSIL (Microsoft Intermediate Language). This is then further compiled to native code during run time.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 13 of 46

C# and VB.NET do not contain language constructs which cause buffer overruns unless special compilation options are used. By using the defaults, buffer overruns should not be introduced by developers. There is obviously no guarantee that the .NET runtime does not contain any flaws – and this is true of any software. The recent GDI+ issue stressed the need to make sure that security patches are applied in a timely fashion. However, Microsoft actively monitor the security implications for their products, and in this case a patch was introduced quickly and the development community notified immediately. The advantage here for development is that developers are unable to introduce buffer overflows. Microsoft maintains the security baseline as new functionality is introduced to .NET.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 14 of 46


Issues with .NET Framework 1.x

.NET Framework provides a very rich security model, but some aspects were not completed for .NET framework 1.0 and 1.1. These include: ♦ Access to the certificate store for use by the asymmetric cryptography classes ♦ API for using Directory Services ♦ Ability to manipulate file permissions ♦ Ability to impersonate other identities Much of this functionality is available by calling the Windows API directly using interop services, but there are a number of drawbacks to this: ♦ Developers need a higher skill level as regards both security and programming ♦ There will be issues when upgrading to 64 bit operating systems ♦ The unmanaged code permission is applied to code, which means potential security holes if there is a poor implementation When .NET Framework 1.0 was introduced, security for web services was in its infancy. Microsoft’s pattern for protecting a web service was to use the services provided by IIS. ♦ Any communication with the web service was encrypted using SSL. This only provides pointto-point security. ♦ Username and password were passed, in encrypted form, to the web service in SOAP headers. The application thus had to deal with storing and retrieval of passwords – a very difficult operation to secure ♦ If certificates were to be used for authentication, they had to be exported from the certificate store to a file – thus, the private key was further exposed Within a year of the release of .NET Framework 1.0, Web Service Enhancements (WSE) were being formulated in order to protect web services and allow a richer security infrastructure. Although downloads were made available for working with WSE, the incompleteness of cryptographic services meant that Microsoft still recommended using CAPICOM for cryptography. The APIs provided were also incomplete and poorly documented.


New .NET Framework 2.0 features and improvements

.NET Framework 2.0 extends security functionality further. For web services, the following points are most relevant: ♦ The certificate store is integrated into .NET fully – this allows proper integration of certificates, a vital part of WSE and any use of PKI ♦ The new communications technology, Indigo, provides an easy to understand and flexible API for working with the different aspects of WSE. As this is complete and well documented, it will be easier to apply good practice to development. This is not actually part of Framework 2.0, but will be released along similar timelines This means that upgrading to the next version of .NET will mean that all the latest functionality for developing web services will be available to developers: ♦ Use of WS-Federation – authentication services that can validate credentials for users across different enterprises. This is likely to become more prevalent in the future, possibly working in

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 15 of 46

a similar fashion to Certification Authorities providing the facilities for Public Key Infrastructures to extend across horizontal market segments. ♦ Richer authentication features, such as the use of Kerberos tokens ♦ End to end security, separate to the protection offered by SSL. This means that encryption is not removed at each endpoint. As a message is routed through different channels (for instance, using MSMQ), the information stays secure. Many other improvements are available, including: ♦ New classes for working with the Data Protection API (DPAPI). This aids in the storage and retrieval of secrets, such as passwords ♦ Access to file system attributes via the System.Security.AccessControl namespace. This will allow manipulation of file system DACLs ♦ API for programming against Kerberos and SSL authentication systems. ♦ XML encryption and digital signatures have more complete functionality. XML security is becoming more widely adopted in different applications, and so this will allow greater interoperability (see Appendix B ). ♦ Full API for working with Active Directory Although all of this functionality could be accessed using .NET Framework 1.x, it had to be achieved by using interop to communicate with the Windows API or COM. This would cause many problems in the future when upgrading to 64 bit operating systems. .NET Framework 2.0 includes a switch called AnyCPU. As long as there is no interop with unmanaged code, when using this switch the assemblies produced will run on both 64 bit and 32 bit platforms. The next version of Windows, codenamed ‘Longhorn’, will involve new technology for running applications under privileges other than the administrator. An application manifest will be produced when the application is compiled, which details the permissions that the application requires to run. A deployment manifest can then be created by the administrator of the system when installing the application – this details the permissions that the applications is permitted. The administrator will be able to decide whether he/she trusts the application to have the different permissions. The MSBuild tool used in Whidbey integrates with this permissions framework, producing application manifests during compilation. .NET Framework 2.0 offers most of the functionality that is required for security technologies available today and in the near future. The improvements over version 1.x will allow fuller use of web services and fewer issues when running code on newer Windows platforms. The beta versions of Visual Studio.NET Whidbey are available as of the date of this publication. This is a great opportunity to plan and start developing now. Several very large scale applications were built and in production using .NET betas in 2001 before Framework 1.0 was even released to the public.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 16 of 46

A.1 Role based security checking
Within the .NET framework, role based security is checked against the principal of the current thread. It can be checked programmatically (using a function call) or declaratively (using an attribute). The declarative method has some drawbacks: ♦ When using Windows authentication, the full name of the permission including the domain has to be hard-coded. This means that code would have to be altered for each domain used. ♦ If the context does not have the required role membership, an exception is thrown which contains full details of the permission check, including code line. Programmatically, code can be checked in two ways: ♦ Instantiating a PrincipalPermission object and making a Demand. ♦ Calling the IsInRole method of the current thread. Both have their merits, but for this paper the IsInRole method will be used as it returns a Boolean, which means that exceptions do not have to be caught. Here is an example of a check for membership of the “TestManager” group:
IPrincipal p = HttpContext.Current.User; if (p.IsInRole("TestManager")) { //perform functionality }

A problem arises when more than one role has access to the particular functionality. In this example, role membership is checked before functionality is accessed:
IPrincipal p = HttpContext.Current.User; if (p.IsInRole("TestManager") | p.IsInRole("TestDataEntry") | p.IsInRole("TestAdministrator")) { //perform functionality }

The TestManager, TestDataEntry and TestAdministrator roles all have access to this functionality. It can be seen that the matrix for access to this functionality is now contained within code, and not laid out in a very logical way as regards future maintenance. A better way to implement permission checks is to add another layer to the permissions: Permissions AccessUpdateButton AccessConfirmationPage AccessLogs






Identity 1

Identity 2

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 17 of 46

Permissions are the granular access to a resource, such as a page, file, screen control, process. Roles are groupings of those permissions. For instance, a TestManager would have access to the ConfirmationPage, UpdateButton and the Logs. The extra layer in the group membership hierarchy extracts the security matrix from the application into the security database, meaning that maintenance is easier. For instance, the next release of the application would add more functionality, and so more permissions would be created. The only change required would be to make links between the new permissions and the roles, rather than adding permissions to a large number of users. Also, as permissions represent a finer granularity of access control, there would be less change to the application code. The previous lines of code would become:
IPrincipal p = HttpContext.Current.User; if (p.IsInRole("AccessConfirmationPage")) { //perform functionality }


Security within an example application

The web application shown here is extremely basic. It is merely a web form with a role based security check in the Load event:
private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here string roleprefix = Configuration.ConfigurationSettings.AppSettings["roleprefix"] .ToString(); if (HttpContext.Current.User.IsInRole(roleprefix + "AccessPageGroup") == true) { Label1.Text = "access granted"; } else { Label1.Text = "access denied"; } }

The HttpContext object exposes a principal object against which role membership is checked:

This object is available across the application, and is populated during authentication by IIS. The call to the IsInRole method checks role membership against the principal object stored in the context. The screen label then displays a message saying “access granted”; otherwise the message “access denied” is shown.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 18 of 46

This is what the web page shows when the user has the correct permissions:

In a real application, this check would be made before accessing a resource, perhaps even redirecting to another page or throwing an error if the role based check does not return true. However, the above code allows a quick and easy demonstration of checking role membership. Notice also the configurable prefix for the role name. If using Windows authentication, then the prefix of the domain w ill be added to the role. As most applications will be tested in different environments, it is important that this is configurable:
<add key="roleprefix" value="NETSECTEST\" />

The domain name for the test example is NETSECTEST. Active Directory can implement nested groups, allowing the extra layer of membership mentioned in section A.1 . Users are be made members of roles, which are be made members of permission groups:

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 19 of 46


Flowing the identity of the user

In this scenario, the application is required to flow the identity of the user. This means that any DACLs applied to resources will be checked against the security membership of the logged on user. The security of resources becomes a configuration issue, as the team maintaining Active Directory will be able to baseline all access to resources. This is often used in an intranet application. Implementing this is simple. One line of code is added to the web.config file of the application:
<identity impersonate = "true" />

This means that the application will work in the same security context as the user that logged on. IIS is configured as shown below:

As the user logs on and is authenticated, they are given an access token by the operating system. When they access the web application, as they access a resource that is locked down, Internet Explorer will present the appropriate credentials automatically to the web application. By locking down the user account (via group membership), the administrator can create access restrictions that the user cannot exceed. Role based checks within the application can restrict that access further. For the example application, a user called user1 was created in Active Directory, and added to the group “AccessPageGroup”. Access to the page was achieved by logging on as this user and browsing to the web page in IE. No further submitting of credentials was required:


Introducing the trusted subsystem

Sometimes the configuration of access by an administrator is not appropriate. For instance, an application may be created for manipulation of objects within Active Directory. To work with AD, much higher permissions are required (sometimes even Domain Admin!). It is certainly not appropriate to grant these sorts of permission to users – if a user installed the adminpack.msi they would have the capability to create a great deal of damage to corporate resources. One answer is to use a trusted subsystem – this means that the application runs under a specifically created user account. This account has the necessary privileges, and access is controlled via role based checks within the application. Further advantages of this approach are discussed in section 4.5.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 20 of 46

To introduce the trusted subsystem, all that has to be done is to comment out the line in web.config for impersonation:
<!-- <identity impersonate = "true" /> -->

The web site code now no longer runs under the context of the original user, instead using the special account created for administering Active Directory. The principal object within the HttpContext is still populated with the group membership information from the original IIS authentication, and this is used for role based checks within the code.


A trusted subsystem, certificate authentication and a custom security database

Only anonymous access should be enabled for the web application through IIS (Integrated Windows should be turned off). SSL should be configured, and set so that certificates are required.

As the user attempts to access the site, a dialog box appears so that a digital certificate (X509) can be chosen. This is the certificate that is submitted.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 21 of 46

As time goes on, more and more users may be granted access to the application. Eventually, a limit is reached with Active Directory. Although it can contain many thousands (millions) of users, the maintenance of these users becomes more and more difficult. Although SQL queries can be applied to Active Directory, they are only select statements and thus cannot be used to perform updates. This means that scripts for ongoing maintenance have to access the properties of each individual object one at a time, and so migration scripts may run for hours (even days!). As AD transactions can only span relatively small numbers of updates, the directory becomes cluttered with debris due to errors. At this stage a constructive way forward is to construct a security repository using SQL Server. A security database could be based on the schema shown below , although it is likely to be much more complex:

Simple SQL queries can be issued to extract a list of roles given the serial number of the certificate (as a single Certificate Authority is often used in these cases, there is not an IssuerName field in the User table), and also the name of the application. Ironically, although this example is the most complex so far, in this instance the Windows DNA model provided everything that was required to accomplish the task with similar lack of complexity. However, changing from one type of authentication (eg. Windows) to another (in this case, certificates with a custom authentication service) would have required recoding parts of the application. This database is generalised enough for use with Forms authentication (section A.6 ). Services for authentication and authorisation could be provided for use by all web applications within an organisation using such a centralised database. The ideal is to be able to create a security module which can be developed and tested against the different applications, and then applied universally with a simple configuration change. HttpModules are a useful way of achieving this.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 22 of 46

The following code shows how to create an HttpModule:
public class CertificateAuthModule : IHttpModule { public CertificateAuthModule(){} void IHttpModule.Init(HttpApplication app) { app.AuthenticateRequest += new System.EventHandler(this.InitialiseAuthentication); } void IHttpModule.Dispose(){}

public void InitialiseAuthentication(object source, EventArgs e) { AuthService aus = new AuthService(); GenericPrincipal gp = aus.RetrievePrincipalFromCert( HttpContext.Current.Request.ClientCertificate); HttpContext.Current.User = gp; } }

The IHttpModule interface requires two methods to be implemented: ♦ Init – generally used to hook one of the application events to a custom method. In this case, the AuthenticateRequest event of the ASP applicatiuon is hooked up to fire the InitialiseAuthentication event in the HTTPModule. ♦ Dispose – used for clearing up any resources As AuthenticateRequest fires, InitialiseAuthentication retrieves the serial number from the client certificate and passes this to the AuthService. The AuthService returns a custom principal. The final step is to replace the principal held within the context with the new GenericPrincipal. The new principal is now accessible across the application. Here is the code for the AuthService:
public GenericPrincipal RetrievePrincipalFromCert(HttpClientCertificate cert) { string s = cert.SerialNumber; string name = Utils.GetName(s); string[] roles = Utils.GetRoles(s); GenericIdentity gi = new GenericIdentity(name); GenericPrincipal gp = new GenericPrincipal(gi, roles); return gp; }

The serial number is extracted from the certificate, and the user name and roles are taken from the database based on this serial number. A GenericPrincipal is created using the information, and returned to the application. Validation of the certificate did not take place in the service, as IIS would already have validated it on the application server. However, .NET Framework 2.0 allows certificate validation (Appendix B ), and so this could be performed by the service as an extra check.
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 23 of 46

Finally, it is necessary to hook the new module to the application using an entry in web.config. This is the part that allows decoupling of security functionality from application:
<system.web> <httpModules> <add name="MyModule" type="HTTPModuleTest.CertificateAuthModule, HTTPModuleTest" /> </httpModules> . . </system.web>

Within the InitialiseAuthentication method, if any errors occur (for instance, there is no entry corresponding to the serial number) the request can immediately be redirected to an error page and the session ended. Any number of HttpModules can be attached to an application (machine.config contains a list of the ones that ASP.NET adds by default), which extends the functionality further. This could further separate authentication (validation of credentials) from authorisation (applying roles via creation of the GenericPrincipal object).

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 24 of 46


Forms authentication

In this example, forms authentication is used. In keeping with previous examples, we are going to separate the authentication functionality from the application itself. In order to achieve this, a separate web application is created that contains a Logon page, and another class library containing the necessary authorisation code:

The LogonApp is a web application that contains one page, called Logon.aspx. This web page has two text boxes, one for entering the username and one for entering the password. Finally, there is a button for submitting the information. Although crude, this aspx file contains the necessary controls for authentication information, and can be formatted as required for the particular application:

The code behind the submit button is as follows:
private void btnSubmit_Click(object sender, System.EventArgs e) { Authenticator a = new Authenticator(); string userName = txtUserName.Text.Trim(); string passWord = txtPassword.Text.Trim(); if (a.Authenticate(userName, passWord) == true) { FormsAuthentication.RedirectFromLoginPage(userName,true); } }

The Authenticate method validates the user’s credentials. It uses the database shown in section A.5 . The RedirectFromLoginPage method navigates the user back to the page they originally tried to access, and it also stores the user’s name in the forms cookie. On subsequent requests, ASP.NET creates a GenericPrincipal object from this username and assigns it to the current context.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 25 of 46

This creates the cookie and the user context, but it is necessary to add roles to principal used in the ASP.NET context. To do this, another HTTPModule is created. This is similar to the CertificateAuthModule, but the InitialiseAuthentication method is as follows:
public void InitialiseAuthentication(object source, EventArgs e) { if (HttpContext.Current.User != null) { if (HttpContext.Current.User.Identity.IsAuthenticated == true) { string userName = HttpContext.Current.User .Identity.Name; AuthService aus = new AuthService(); HttpContext.Current.User = aus.RetrievePrincipalFromForms(userName); } } }

The username is extracted from the current user context – this was automatically filled by ASP.NET based on the value in the cookie. The AuthService extracts the roles from the database and returns a GenericPrincipal object. The components created so far (web page, HTTPModule and class library) can be used by different web applications. They can be used by our original application (see A.1 ) as follows: ♦ Copy the Logon.aspx page to the web application directory of the original application ♦ Copy the associated DLLs (LogonApp.dll and AuthManager.dll) to the corresponding web application bin directory ♦ Add a reference to the new HTTPModule ♦ Add the necessary line to web.config for the original application:
<authentication mode="Forms"> <forms name="DotNetSec" loginUrl="Logon.aspx" protection="All" timeout="180" path="/" requireSSL="false" slidingExpiration="true" /> </authentication>

This configures the application to use forms authentication for authentication, and to use our previously constructed Logon.aspx page for entering authentication data. There are no changes to the original application. The implementation of forms authentication is achieved by: ♦ adding a logon page and its associated DLLs to the application ♦ adding a new HTTPModule ♦ changing the web.config file


Securing the principal object using Code Access Security

The previous example showed what can be achieved by replacing the principal object. However, it seems that there is a glaring security hole here. If the developers can write code to change the security roles, then any rogue code (introduced, for instance, by a Trojan onto the system) could alter the roles

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 26 of 46

contained within that principal. It seems that, rather than securing the application, it is now more vulnerable. The solution here is to use Code Access Security to only allow our custom HttpModule to change the principal object. The resulting intersection of the Enterprise, Machine, User and ApplicationDomain policy levels gives the set of permissions for the web application. That is, for a permission to be available, it must be granted in all of the different policy levels. The permissions can be restricted by changing the policy level for just the application domain. A number of steps are required to achieve this: ♦ Make sure that the HttpModule assembly AllowPartiallyTrustedCallers attribute added. is StrongNamed and has the

♦ Create a new policy file based on one of the config files contained in C:\WINDOWS\Microsoft.NET\Framework\version\CONFIG. ♦ Create an entry for this new file in machine.config in the trustLevel section:
<system.web> <securityPolicy> <trustLevel name="Full" policyFile="internal"/> <trustLevel name="High" policyFile="web_hightrust.config"/> <trustLevel name="Medium" policyFile="web_mediumtrust.config"/> <trustLevel name="Low" policyFile="web_lowtrust.config"/> <trustLevel name="Minimal" policyFile="web_minimaltrust.config"/> <trustLevel name="CustomAuth" policyFile="web_customauth.config"/> </securityPolicy> <!-- level="[Full|High|Medium|Low|Minimal]" --> <trust level="Full" originUrl=""/> </system.web>

The new policy is “CustomAuth”, and the policy file defining it is called web_customauth.config. ♦ Add a reference to the new trust level under system.web in the application’s web.config:
<system.web> <trust level="CustomAuth" />

The application now references a custom policy file that dictates which permissions are granted to the various components. The policy allows only the assembly containing the custom HttpModule to change the principal. Appendix E gives details of exactly how to create this policy file. When CAS policy is evaluated, all method calls on the function stack where the permission is demanded are checked to make sure that they have the permission. This makes sure that all code involved in the function call has the necessary level of access. However, it is a specific requirement here that the web application does not have the permission to change the principal object. In this case, the permission check will succeed for the HttpModule, but fail for the next caller up the stack (the web application). A SecurityException will be thrown. In order to stop the stack walk being performed further than the HttpModule, an Assert statement is made. Any use of asset within an application must be examined carefully, as this intentionally subverts CAS checking. Careless use can undermine CAS. A recommended pattern is to check for another permission when performing an Assert. The Microsoft Patterns and Practices document ‘Improving Web Application Security’ discusses best practice when using Assert.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 27 of 46

The InitialiseAuthentication module in the CertificateAuthModule in section A.5 becomes:
public void InitialiseAuthentication(object source, EventArgs e) { AuthService aus = new AuthService(); GenericPrincipal gp = aus.RetrievePrincipalFromCert( HttpContext.Current.Request.ClientCertificate); try { SecurityPermission sp = new SecurityPermission( SecurityPermissionFlag.ControlPrincipal); sp.Assert(); HttpContext.Current.User = gp; } catch (Exception ex) { throw new Exception("Cannot assert"); } finally { CodeAccessPermission.RevertAssert(); } }

A SecurityPermission object is created, and initialised in the constructor with a flag indicating that it will be making calls against the ControlPrincipal permission. The Assert method is called on this object. This means that any frames higher on the function stack will not be checked for the relevant permission. Only the component containing this method call will require the ControlPrincipal permission. The principal object is replaced. A new exception is thrown if this component does not have the relevant permission. In production, more complex error logging would be necessary, but this is satisfactory for debugging purposes. The ‘finally’ statement reverts the Assert, so that it does not apply to any further code. The result is that only the HttpModules defined have the permission to replace the principal.


Extending security functionality

Going a stage further, it is possible to add extra functionality to the principal object. A quite common requirement within a large organisation is the implementation of a restricted flag. There are many variations on this, but the basic idea is to prevent certain users seeing specific data. Within many public sector institutions, there are many records held of people belonging to the organisation itself. For instance, the Inland Revenue will have tax records for each of its employees. However, it would not be advisable to allow an employee to see or change his or her own records. In this case, the record would be restricted when the subject attempts to view it. The principal object has to implement IPrincipal or inherit from one of the standard principal objects (GenericPrincipal or WindowsPrincipal). As long as this requirement is fulfilled, there is nothing to stop the principal implementing other interfaces – for instance, an IRestricted interface could be added. The details of this implementation would require careful planning and a great deal of thought. It may be useful to implement more than one HttpModule, with each one applying a different aspect of security functionality.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 28 of 46



All of the changes to both authentication methods and flow of identity have been implemented without changing the code for the application in any way. As HttpModules are applied, it is simply a matter of adding components to the application directory, changing web.config and applying the correct policy file.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 29 of 46

This example demonstrates the method calls required to sign and later verify an XML digital signature produced by .NET Framework 2.0. Appendix D gives information on how to use Windows 2003 Certificate Services to create the necessary certificates. Alternatively, organisations such as Verisign can provide test certificates. Create a Windows Forms application using the beta version of Whidbey. Add a button for signing, and another button for verification. The test application for preparing this code also contained two textboxes – one for entering a file name and path (txtFileName), and another for displaying the resulting XML signature (txtRes). The following two using directives are required:
using System.Security.Cryptography.Xml; using System.Security.Cryptography.X509Certificates;

This is the code that is placed in the click event of the signing button:
private void btnSignXML_Click(object sender, EventArgs e) { X509CertificateEx ct = GetSelectedCertificate(); string fileName = txtFileName.Text.Trim(); txtRes.Text = GetSignedText(fileName, "book", ct); }

The first function, GetSelectedCertificate(), retrieves a certificate from the certificate store:
private X509CertificateEx GetSelectedCertificate() { X509CertificateEx ct = null; X509Store store = new X509Store("My", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509CertificateExCollection certs = store.Certificates.Select("Certificates", "Choose a certificate", X509SelectionFlag.SingleSelection); if (certs.Count == 1) { ct = certs[0]; } return ct; }

The X509Store.Certificates.Select method provided by the .NET Framework brings up a dialog box so that the user can choose a certificate - this requires only one line of code! An X509CertificateEx object is returned – this is a new .NET certificate object, which is fully linked to the Windows certificate store. No more Win32 API calls are necessary for extracting private keys.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 30 of 46

After the filename has been retrieved, the GetSignedText() method is called. Here is the XML that is to be signed:

The GetSignedText() method is as follows:
private string GetSignedText(string fileName, string refURI, X509CertificateEx cert) { XmlDocument doc = new XmlDocument(); doc.Load(fileName); System.Security.Cryptography.Xml.DataObject dobj = new System.Security.Cryptography.Xml.DataObject(); dobj.Data = doc.ChildNodes; dobj.Id = refURI; Reference r = new Reference(); r.Uri = "#" + refURI; SignedXml sx = new SignedXml(); sx.AddReference(r); sx.AddObject(dobj); sx.SigningKey = cert.PrivateKey; KeyInfoX509Data ki = new KeyInfoX509Data(cert, X509IncludeOption.EndCertOnly); sx.KeyInfo.AddClause(ki); sx.ComputeSignature(); string res = sx.GetXml().OuterXml; return res; }

Firstly, the xml document is extracted from a file and loaded into an XMLDocument. Next, and Xml.DataObject is created which contains the child nodes of the original document – this is the data to be signed. An ID is attached to this data object – “book” was passed in as the refURI parameter. A reference is created to the DataObject, with the uri attached preceded by a # symbol. The reference and the object are attached to a SignedXml object.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 31 of 46

The private key from the previously selected X509CertificateEx object is assigned to the SignedXml.SigningKey property. A KeyInfoX509Data object is created based on the X509CertificateEx object. This adds the public key certificate to the signature, which was not possible in .NET Framework 1.1 without using the Win32 API. Finally, calling SignedXml.ComputeSignature() creates the digitally signed XML. Here is the digitally signed XML:

The SignatureValue and X509Certificate fields have been shortened here. Notice the id for the object containing the original XML (“book”). This is referenced by the URI in the Reference tag. This is where the # symbol was inserted in the code. The SignatureMethod contains the names of the algorithms derived from the X509 certificate:

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 32 of 46

The digest based on the hashing algorithm and the final signature can also be seen. These are BLOB fields, as is the field containing the actual certificate. Here is the code for the “Verify” button:
private void btnVerify_Click(object sender, EventArgs e) { MessageBox.Show(VerifyXMLSig(txtRes.Text.Trim()).ToString()); }

The result is simply a MessageBox displaying “True” (if the signature is valid) and “false” if it is not. Here is the code for the VerifyXMLSig() method:
private bool VerifyXMLSig(string signedXML) { XmlDocument doc = new XmlDocument(); doc.LoadXml(txtRes.Text); SignedXml sx = new SignedXml(); XmlNodeList nl = doc.GetElementsByTagName("Signature"); sx.LoadXml((XmlElement)nl[0]); KeyInfo kf = sx.KeyInfo; X509CertificateEx cert = RetrieveCertificate(kf); return sx.CheckSignature(cert, false); }

The signed xml (from the text box) is loaded into an XMLDocument. A SignedXml object is created. The node containing the “Signature” element is loaded into the SignedXml. The KeyInfo is extracted (this can be seen as the “KeyInfo” element in the signed XML on the previous page). The X509 certificate is extracted. The CheckSignature method of the SignedXml object is called, passing the X509CertificateEx object as a parameter). This returns true if the signature is valid. The last parameter allows only the signature to be checked. This is set to false, as we wish to check the validity of the certificate also. If Certificate Services were used, the instructions in Appendix D suggested leaving out the step of installing the CRL from the Certificate Authority. This would make the validation fail (as a check to make demonstrate that certificate checking is taking place). After installation of the latest CRL, the validation will return true. This demonstrates that the new certificate functionality fully checks the certificate chain and CRL. With Framework 1.1, CAPICOM had to be used to achieve this, which had limitations regarding XML Digital Signatures. The RetrieveCertificate method extracts the certificate from the BLOB field in the XML. At present this is the only way to get the certificate, but this may be improved as the final version of .NET 2.0 is released.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 33 of 46

private X509CertificateEx RetrieveCertificate(KeyInfo kf) { string ki = kf.GetXml().OuterXml; XmlDocument doc = new XmlDocument(); doc.LoadXml(ki); XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable); nsm.AddNamespace("digsig", @""); XmlNode n = doc.SelectSingleNode(@"//digsig:X509Certificate", nsm); string ct = n.InnerText; byte[] cb = System.Text.Encoding.UTF8.GetBytes(ct); X509CertificateEx cex = new X509CertificateEx(cb); return cex; }

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 34 of 46

For those moving from Windows DNA to .NET, there are a number of models for the migration, and also tools produced by Microsoft. There are many resources available on MSDN giving different strategies for upgrading. Some of these are given at the end of this appendix. If any custom security solutions are already embedded into the legacy code, it may be best to build a new security architecture using HTTP modules – these classes intercept the browser request before it reaches the application, building the security context for role-based security checks (section 4.3). They can be plugged into any .NET web application, allowing modularisation and reusability. This means that the core security functionality can be developed either before or in conjunction with the application. This separation allows cleaner design, more robust testing and proper baselining for security. Two extremely good resources for implementing the .NET security model for web applications are: ♦ ‘Building Secure ASP.NET Applications’ ♦ ‘Improving Web Application Security’ These are available from the MSDN web site. Although they deal with .NET Framework 1.x, expect these to be updated as Framework 2.0 is released. The beta versions of Visual Studio.NET Whidbey are now available. This is a great opportunity to plan and start developing now. Several very large scale applications were built and in production using .NET betas in 2001 before Framework 1.0 was even released to the public. It is clear that application architecture is becoming more complex, and it is probably unreasonable to expect smaller development teams to understand and apply security good practice without expert guidance. Many of the technologies discussed here require specialist skills in order to make them sound. For instance, developing a security subsystem that relies on SQL Server as the datastore for security information could open the application to new threats if not implemented properly. Involving security consultants in the development of application security will make the transition easier, and this should set standards for good practice to be followed for future development. Any security consultant should leave training materials and documentation, certainly including the basis for evolving coding standards for other developers. Here is a brief selection of references in MSDN regarding upgrading to .NET from Windows DNA based applications. Upgrading to Microsoft .NET: Upgrading from Visual Basic 6.0: Preparing a Visual Basic 6.0 application for upgrading:
17 May 2005 Version 1.0 Security solutions offered by Visual Studio.NET 2005 (Whidbey) Page 35 of 46 Migrating Native Code to the .NET CLR:

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 36 of 46

Firstly, certificates are necessary for signing. These can be produced using Windows 2003 Certificate Services. TechNet has numerous articles detailing how to use this feature: The most useful type of CA for this demonstration is a stand alone root CA. Once this has been created, carry out the following steps to obtain the necessary certificates: ♦ Use the web interface to request an Email Protection certificate, with the private key marked as exportable ♦ Use the Certification Authority interface to issue the certificate ♦ Use the web interface to check the request status for the certificate and download it ♦ Use the Certification Authority applet to publish a new CRL ♦ Export the email protection certificate, including the private key ♦ Export the root CA certificate, without the private key It is assumed here that Certificate Services is installed on a separate server. In order to make sure that the certificate can be verified properly on the development machine, make sure that: 1. The signing certificate is placed in the Current User store, in the Personal folder 2. The certificate for the CA that issued the signing certificate is stored in the Current User store, in the Trusted Root Certification Authorities folder 3. The CRL for the CA that issued the signing certificate is imported into the Current User store, in the Personal folder Leave out step 3 and run the code from Appendix B . You will find that the signature cannot be verified by the method calls. Now carry out step 3 and run the code again. This time you will see that the signature has been verified. This confirms that full checking of the certificate chain has taken place, including checking of the URL.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 37 of 46

The policy file (web_customauth.config) is shown in its entirety here with explanations. Alterations to the original web_mediumtrust.config on which it was based are shown in bold. The first alteration is to the NamedPermissionSet called ASP.Net. Within this permission set, the SecurityPermission class has had ControlPrincipal removed from its set of flags. This change prevents the web application from having the ControlPrincipal permission, and thus it cannot replace the original principal. The second alteration creates a new permission set called AuthPermSet. This contains exactly the same permissions as the original ASP.Net permission set ie. The SecurityPermission class retains the ControlPrincipal flag, as in the web_mediumtrust.config. Further down, a new code group is created which grants the AuthPermSet to any assembly that presents a certain public key blob. This key has been extracted from the assembly containing the custom HttpModule defined in section A.5 . Notice that the new code group is part of a FirstMatchCode group. The first child code group within a FirstMatchCodeGroup is the only child evaluated for this branch of the policy. By placing the new code group here, before the one for the ASP.Net code group, the exact nature of the permissions can be defined separately from the web application. In this instance, a large number of permissions have been granted, but they can be restricted to only what is required by the HttpModule.

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 38 of 46

<configuration> <mscorlib> <security> <policy> <PolicyLevel version="1"> <SecurityClasses> <SecurityClass Name="AllMembershipCondition" Description="System.Security.Policy.AllMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="AspNetHostingPermission" Description="System.Web.AspNetHostingPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="DnsPermission" Description="System.Net.DnsPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="EnvironmentPermission" Description="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="FileIOPermission" Description="System.Security.Permissions.FileIOPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="FirstMatchCodeGroup" Description="System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="IsolatedStorageFilePermission" Description="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="NamedPermissionSet" Description="System.Security.NamedPermissionSet"/> <SecurityClass Name="PrintingPermission" Description="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> <SecurityClass Name="SecurityPermission" Description="System.Security.Permissions.SecurityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="SqlClientPermission" Description="System.Data.SqlClient.SqlClientPermission, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 39 of 46

<SecurityClass Name="StrongNameMembershipCondition" Description="System.Security.Policy.StrongNameMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="UIPermission" Description="System.Security.Permissions.UIPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="UnionCodeGroup" Description="System.Security.Policy.UnionCodeGroup, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="UrlMembershipCondition" Description="System.Security.Policy.UrlMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="WebPermission" Description="System.Net.WebPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <SecurityClass Name="ZoneMembershipCondition" Description="System.Security.Policy.ZoneMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </SecurityClasses> <NamedPermissionSets> <PermissionSet class="NamedPermissionSet" version="1" Unrestricted="true" Name="FullTrust" Description="Allows full access to all resources" /> <PermissionSet class="NamedPermissionSet" version="1" Name="Nothing" Description="Denies all resources, including the right to execute" /> <PermissionSet class="NamedPermissionSet" version="1" Name="ASP.Net"> <IPermission class="AspNetHostingPermission" version="1" Level="Medium"

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 40 of 46

/> <IPermission class="DnsPermission" version="1" Unrestricted="true" /> <IPermission class="EnvironmentPermission" version="1" Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME" /> <IPermission class="FileIOPermission" version="1" Read="$AppDir$" Write="$AppDir$" Append="$AppDir$" PathDiscovery="$AppDir$" /> <IPermission class="IsolatedStorageFilePermission" version="1" Allowed="AssemblyIsolationByUser" UserQuota="9223372036854775807" /> <IPermission class="PrintingPermission" version="1" Level="DefaultPrinting" /> <IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, RemotingConfiguration" /> <IPermission class="SqlClientPermission" version="1"

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 41 of 46

Unrestricted="true" /> <IPermission class="WebPermission" version="1"> <ConnectAccess> <URI uri="$OriginHost$"/> </ConnectAccess> </IPermission> </PermissionSet> <PermissionSet class="NamedPermissionSet" version="1" Name="AuthPermSet"> <IPermission class="AspNetHostingPermission" version="1" Level="Medium" /> <IPermission class="DnsPermission" version="1" Unrestricted="true" /> <IPermission class="EnvironmentPermission" version="1" Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME" /> <IPermission class="FileIOPermission" version="1" Read="$AppDir$" Write="$AppDir$" Append="$AppDir$" PathDiscovery="$AppDir$" /> <IPermission

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 42 of 46

class="IsolatedStorageFilePermission" version="1" Allowed="AssemblyIsolationByUser" UserQuota="9223372036854775807" /> <IPermission class="PrintingPermission" version="1" Level="DefaultPrinting" /> <IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration" /> <IPermission class="SqlClientPermission" version="1" Unrestricted="true" /> <IPermission class="WebPermission" version="1"> <ConnectAccess> <URI uri="$OriginHost$"/> </ConnectAccess> </IPermission> </PermissionSet> </NamedPermissionSets> <CodeGroup class="FirstMatchCodeGroup" version="1" PermissionSetName="Nothing"> <IMembershipCondition class="AllMembershipCondition" version="1"

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 43 of 46

/> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="AuthPermSet"> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100F18C513A754119A5CD523A19ADB7AFC20E446 27446053C88E8140048A4636C0E05A1E904CE3769DE64C86655E2521EB91D4D227144E79EE6D5E5611C36D2A0CA344DF94AD213CEE43DB8F2A6D 8C2079E8079873964F484347D260F931B5559E06C795896E8BAC3008BDF6CE6E9BF673F4866444D3C9BB2F47642418B65867CF0" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="$AppDirUrl$/*" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="$CodeGen$/*" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust">

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 44 of 46

<IMembershipCondition class="UrlMembershipCondition" Url="$Gac$/*" version="1" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="Nothing"> <IMembershipCondition class="ZoneMembershipCondition" version="1" Zone="MyComputer" /> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Microsoft_Strong_Name" Description="This code group grants code signed with the Microsoft strong name full trust. "> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8F D6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A 5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Ecma_Strong_Name" Description="This code group grants code signed with the ECMA strong name full trust. "> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00000000000000000400000000000000"

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 45 of 46

/> </CodeGroup> </CodeGroup> </CodeGroup> </PolicyLevel> </policy> </security> </mscorlib> </configuration>

17 May 2005 Version 1.0

Security solutions offered by Visual Studio.NET 2005 (Whidbey)

Page 46 of 46

Sign up to vote on this title
UsefulNot useful

Master Your Semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master Your Semester with a Special Offer from Scribd & The New York Times

Cancel anytime.