Maintaining a Security Checklist
As a developer, it is recommended that you maintain a list of security issues that you can update as you gain experience in writing secure applications. The following table is meant to provide a starting point for your own list.
The information in this table comes from multiple chapters in the book titled Writing Secure Code (ISBN 0-7356-1722-8).
Security issue |
Applicable technology or language |
---|---|
Validate all data that crosses boundaries between trusted and untrusted resources. An example of an untrusted resource is a Web application that accepts user input. Always test only for acceptable characters and deny everything else. Watch for Unicode and UTF-8 characters. If you use regular expressions to check input, the .NET Framework and Perl 5.8.0 support Unicode regular expressions by using the /p switch. Malicious users can use escape codes or HTML tagging to inject script into form data, display URLs that look valid but are not, and so on. |
Any |
Make no important decisions in application code based on header data. Headers contain information about a client such as cookie data, server names, and so on. Headers are a part of each request that is sent to a Web server. Malicious users can impersonate other users by manipulating header data and sending the response to a Web server. |
Any |
Store no sensitive or secure data in cookies or other headers that are sent in the response. An example of sensitive data is customer user names, passwords, or credit card numbers. Malicious users can use tools that watch Internet traffic for this kind of information. |
Any |
Configure an application to grant access only to a security account that has the least amount of privileges necessary to run the application. For information about what types of applications run under which accounts, see IIS Application Identities. |
Any |
Force code pages and character sets to protect against encoding mismatches. This restricts the ways that strings can be represented, further protecting against script injection and other issues. In ISAPI applications, use Unicode when possible and avoid converting between Unicode and other code pages. In ASP pages, declare the code page and check that the HTTP_ACCEPT_LANGUAGE server variable includes the language that you expect. |
Any |
Encode any data that crosses boundaries between trusted and untrusted resources. An example of an untrusted resource is a Web application that accepts user input. In ASP pages, you can use Server.HTMLEncode or Server.URLEncode to safely encode data. Use double-quotes around all tag attributes. When creating cookies, apply a Message Authentication Code (MAC). |
Any |
When working with files, canonicalize and verify all resource names such as file names, server names, user names, and so on. When creating files, use CreateFile with dwFlagsAndAttributes != 0, or call GetFileType after calling CreateFile to verify that a file is of the correct type (FILE_TYPE_DISK). In ISAPI applications, use the SCRIPT_TRANSLATED server variable to get a canonicalized filename from the URL. Canonicalization refers to the practice of converting resource names to a common format, for example, converting 8dot3 names and relative file paths to full physical paths before working with the path name. Malicious users can use 8dot3 representations of paths to gain access to files that they would otherwise be denied. They might also be able to force an application to create a different file type, such as a names pipe, mailslot, or other communication resource. |
Any |
When working with files or user input, put your security checking code in all subroutines that handle data, not just in the first subroutine. In the future, your code might be reused or moved, so keeping the checks in all places protects against security bugs appearing later on. |
Any |
If your application uses SQL server, replace the default "sa" administrator account with an administrator account that has a long name and strong password. Too many people know that the "sa" account exists, and that the password is blank by default. |
ADO |
If your application connects to a database, set Trusted_Connection to True in the connection string to allow ADO to take advantage of the native authentication schemes. |
ADO |
If your application connects to a database, use parameterized commands and queries. These are also known as placeholders. Not only are they faster during run-time, but they protect against a user injecting script into a query string. |
ADO |
If your Web application allows content in different frames to interact in powerful ways by scripting with the DHTML object model, then consider applying rules that will protect the integrity of your application. For example, navigating across frames that are hosted by different domains can allow a cross-site scripting attack. For more information, please see About Cross-Frame Scripting and Security and Security Considerations: Dynamic HTML. |
ASP |
If your Web application uses include files, do not store sensitive data in the include files. On IIS 5.0 and earlier, the .inc file extension was in the MimeMap, allowing clients to request an include file directly and view the contents. It is a good practice to ensure that the .asp and .inc file extensions are not in the IIS MIME map. Additionally, you can change the ScriptMaps for .inc file extensions from SSINC.dll to ASP.dll, which makes IIS process include files in the ASP engine. |
ASP |
Validate the sizes of strings and arrays before using string functions or manipulating arrays. Be careful when using both ANSI and Unicode strings in the same application, because buffer sizes are not the same. String functions that take a buffer size as a parameter are often safer than those that do not. Consider using the functions in Strsafe.h. Array indexing errors and string buffer size mismatches can cause buffer overruns in applications. If the buffer overrun is exploitable, a malicious user can redirect the application to run undesirable code. |
C++ |
Always check return codes when returning from a function, for example, or when applying impersonation or removing impersonation tokens with the RevertToSelf function. If impersonation fails, the privilege of the application can be elevated to an account that has access to sensitive data. |
C++ |