ADO.NET Security Best Practices
The .NET Framework provides many useful classes and services that enable developers to enhance the security of their applications. Following secure data access coding practices limits the damage that can be inflicted by a potential attacker. However, writing secure code does not guard against self-inflicted security holes when working with unmanaged resources such as databases. Most server databases, such as SQL Server, have their own security systems, which enhance security when implemented correctly. However, even a data source with a robust security system can be victimized in an attack if it is not configured appropriately.
Security as a Process
Securing an application is an ongoing process. There will never be a point where a developer can guarantee that an application is safe from all attacks, because it is impossible to predict what kinds of future attacks newer technologies will bring about. Conversely, just because nobody has yet discovered (or published) security flaws in a system, does not mean that none exist or could exist. You need to plan for security during the design phase of the project, as well as plan how security will be maintained over the lifetime of the application. This section discusses the following topics:
-
Design for Security
-
Practice Threat Modeling
-
Administer and Maintain Security
-
Run with Least Privilege
-
Use Integrated Security with SQL Server
-
Use Parameterized Commands
-
Handle Exceptions and Log Errors
-
Use Cryptography to Protect Data
-
Use Hash Codes for Data Integrity
Design for Security
One of the biggest problems in developing secure applications is that security is often an afterthought, something to implement after a project is code-complete. Not building security into an application at the outset leads to insecure applications because little thought has been given to what makes an application secure. When security is implemented at the last minute, it also leads to more bugs, as software breaks under the new restrictions or has to be rewritten to accommodate unanticipated functionality. Every line of revised code contains the possibility of introducing a new bug. For this reason, you should consider security early in the development process so that it can proceed in tandem with the development of new features.
The best practice for creating secure applications is to start with no permissions at all and then add the narrowest permissions for the particular task being performed. Starting with all permissions and then denying individual ones, by contrast, leads to insecure applications that are difficult to test and maintain, because security holes may exist from unintentionally granting more permissions than required.
| Topic | Description |
|---|---|
| Provides links to resources for creating secure applications. | |
| Provides links to resources for creating secure applications. | |
| Provides links to external resources available online and in print. |
Practice Threat Modeling
The process of evaluating security threats, called threat modeling, is necessary to determine the likelihood and ramifications of security breaches in your ADO.NET application. You cannot protect a system against attack unless you understand all the potential attacks that it is exposed to. Threat modeling is an iterative approach to assessing vulnerabilities in your application to find those that are the most dangerous because they expose the most sensitive data. Once you identify the vulnerabilities, you rank them in order of severity and create a prioritized set of countermeasures to counter the threats.
| Topic | Description |
|---|---|
| Describes threat modeling and best practices for ASP.NET applications. | |
| Threat Modeling, Microsoft Security Developer Center | Provides links to additional resources and information on threat modeling. |
Administer and Maintain Security
Improperly administering code access security (CAS) policy can potentially create security weaknesses. Once an application is deployed, techniques for monitoring security should be used and risks evaluated as new threats emerge. Make sure that you subscribe to security bulletins and alerts, and that all service packs and patches are up to date.
| Topic | Description |
|---|---|
| Provides information on creating and administering security policy. | |
| Provides external links to other papers and resources for maintaining security. | |
| Provides links describing how to administer security policy. | |
| Describes the Windows Update Service, an essential tool for keeping up to date with security. | |
| Provides security tools, security response information such as security bulletins and virus alerts, as well as prescriptive guidance for security your applications. |
Run with Least Privilege
When you design, build, and deploy your application, you must assume that your application will be attacked. Often these attacks come from malicious code that executes with the permissions of the user running the code. Others can originate with well-intentioned code that has been exploited by an attacker. When planning security, always assume the worst-case scenario will occur. One counter-measure you can employ is to try to erect as many walls around your code as possible by running with least privilege.
The principle of least privilege says that any given privilege should be granted to the least amount of code necessary, for the shortest duration of time that is required to get the job done. To minimize the amount of damage that can occur if an attack succeeds, choose a security context for your code that grants access only to the resources it needs to get its work done, and no more.
| Topic | Description |
|---|---|
| Describes the interactions between code access security, role-based security, and partially trusted environments. | |
| Describes best practices in the context of Visual Studio Team System. The concepts are applicable to all applications. | |
| MSDN content discussing how writing applications using a least privilege account can help you uncover security holes that an attacker might exploit. | |
| Developing Software in Visual Studio .NET with Non-Administrative Privileges | MSDN content discussing how to develop software while logged on to Windows with non-administrative privileges. |
| "Context Switching" in SQL Server Books Online | Describes how to change the execution context to explicitly impersonate another user in a SQL Server 2005 database. |
Use Integrated Security with SQL Server
When connecting to Microsoft SQL Server, you can use Windows Authentication, also known as Integrated Security, which uses the identity of the current active Windows user rather than passing a user ID and password. Using Windows Authentication is highly recommended because user credentials are not exposed in the connection string. If you cannot use Windows Authentication to connect to SQL Server, then consider creating connection strings at run time using the SqlConnectionStringBuilder. For more information, see Building Connection Strings.
Use Parameterized Commands
Using parameterized commands helps guard against SQL injection attacks, in which an attacker "injects" a command into a SQL statement that compromises security on the server. Parameterized commands guard against a SQL injection attack by ensuring that values received from an external source are passed as values only, and not part of the Transact-SQL statement. As a result, Transact-SQL commands inserted into a value are not executed at the data source. Rather, they are evaluated solely as a parameter value. In addition to the security benefits, parameterized commands provide a convenient method for organizing values passed with a Transact-SQL statement or to a stored procedure.
| Topic | Description |
|---|---|
| Describes how to use parameters with a DataAdapter. | |
| Describes how to specify parameters and obtain a return value. | |
| Describes how to use parameters with ASP.NET data source controls. | |
| Mapping Data Provider Data Types to .NET Framework Data Types | Describes how to map .NET data types to provider-specific data types. |
| Describes how to use selection and update parameters and how to work with parameter objects and collections for the .NET Framework data providers. | |
| Describes how to work with parameterized command objects using SQL statements or stored procedures. |
Note |
|---|
| If you are creating an ASP.NET application, you will also want to guard against script exploits. For more information, see Script Exploits Overview. |
Handle Exceptions and Log Errors
Attackers often use information from an exception, such as the name of your server, database, or table to mount an attack on your system. Because exceptions can contain specific information about your application or data source, you can help keep your application and data source better protected by only exposing essential information to the client.
| Topic | Description |
|---|---|
| Describes exception handling for .NET Framework applications. | |
| Describes best practices for handling exceptions. | |
| Describes displaying safe error messages in the context of Web site security. |
Use Cryptography to Protect Data
The classes in the .NET Framework System.Security.Cryptography namespace can be used from your ADO.NET applications to prevent data from being read or modified by unauthorized third parties. Some classes are wrappers for the unmanaged Microsoft CryptoAPI, while others are managed implementations.
| Topic | Description |
|---|---|
| Provides an overview of cryptography in the .NET Framework, describes how cryptograph is implemented, and how to perform specific cryptographic tasks. | |
| Encrypting Configuration Information Using Protected Configuration | Describes how to use protected configuration to encrypt configuration files. |
| Describes how to encrypt connection strings stored in configuration files using protected configuration. |
Use Hash Codes for Data Integrity
Unlike cryptography, which allows data to be encrypted and then decrypted, hashing data is a one-way process. Hashing data is useful when you want to prevent tampering by checking that data has not been altered: given identical input strings, hashing algorithms always produce identical short output values that can easily be compared.
| Topic | Description |
|---|---|
| Describes how you can generate and verify hash values. |
Note