ASP.NET Coding Standards Details
1. AJAX programming, controls, and frameworks are not to be used
Understandability, Learnability, Complexity
Some of the reasons to avoid AJAX include:
- Increased coding and debugging complexity
- Not fully supporting web browser history integration (i.e.
Backbutton will not work as expected)
- Difficult to bookmark a URL representing a particular state in the application
- Introduces difficulties with Web Analytics solutions as user actions are harder to track
- Harder to have pages indexed by search engines unless Site Maps are provided
AJAX programming techniques and associated frameworks are not to be used in development of web applications.
- Search for
MSXML2.XMLHTTPfor use of AJAX-related browser objects
- Search for
- Search for
scriptaculousstring to identify use of script.aculo.us (script.aculo.us) library
Examine ASP.NET page files (
.aspx) for inline server script or
code-behind files (
.aspx.vb) for use of AJAX frameworks:
- Search for
MSXML2.XMLHTTPfor use of AJAX-related browser objects
- Search for
- Search for
scriptaculousstring to identify use of script.aculo.us (script.aculo.us) library
- Search for
System.Web.UIto identify use of ASP.NET AJAX Framework (asp.net/ajax/documentation/live/) classes such as "UpdatePanel", "Timer", "ScriptControl", etc
2. Web site is partitioned into restricted areas (protected using SSL) and public areas
Web sites containing both restricted and public areas should be partitioned so that all restricted pages are placed under one or more subdirectories under the root web virtual directory. Each subdirectory which is part of the restricted area of the web site must be configured to require authenticated access.
URL Authorization (msdn2.microsoft.com/en-us/library/wce3kxhd(vs.80).aspx) can be used to restrict access to secure
subdirectories. To restrict access to a subdirectory, place
<authorization> elements in a
Web.config file. Either multiple
<authorization> elements within separate
<location> elements can be used in the application-level
Web.config file or separate
files can be placed in each restricted subdirectory with their own
Separating public areas from restricted areas avoids incurring SSL performance overheads across the entire site.
Restricted areas must always use SSL to mitigate the risk of session hijacking by always sending authentication keys to HTTPS connections - not HTTP connections.
Any redirects from a HTTP (public, anonymous) page to a HTTPS (restricted, secure) page (and vice-versa) must use absolute URLs.
must not be used to transfer from an anonymous page to a secure page since
authentication checks are bypassed by the .NET Framework.
- Web sites that consist of both public (anonymous) and restricted (secure) areas should be partitioned to separate the restricted content into one or more subdirectories.
- Restricted subdirectories are protected by requiring
authenticated access (configured in the
<authorization>section of the
- All links referencing a restricted page must use HTTPS URLs to protect authentication keys.
- Redirects from an anonymous page (HTTP) to a secure page (HTTPS) must use absolute URLs to protect against transferring authentication keys in plain text.
Server.Transferis not used to redirect from an anonymous page to a secure page to prevent bypassing of authentication checks.
- Unauthenticated access to restricted pages (e.g. expired session) should redirect to the default login page.
Sample of application-level Web.config with URL Authorization
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <!-- The <authentication> section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --> <authentication mode="Forms"> <forms name="security" loginUrl="login.aspx?access=denied" /> </authentication> <!-- The virtual directory root folder contains general pages. Unauthenticated users can view them and they do not need to be secured with SSL. --> <authorization> <allow users="*" /> </authorization> </system.web> <!-- The restricted folder (named "Secure") is for authenticated and SSL access only. Deny access to unauthenticated users and force a redirect to the login page that is specified on the <forms> element. --> <location path="Secure" > <system.web> <authorization> <deny users="?" /> <allow roles="contractor, employee, manager, administrator" /> </authorization> </system.web> </location> </configuration>
Sample of placing a separate Web.config in the restricted folder named "Secure"
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <authorization> <deny users="?" /> <allow roles="contractor, employee, manager, administrator" /> </authorization> </system.web> </configuration>
If the web site has only anonymously accessible content then there is no need to partition the site.
Check that restricted areas of the site are partitioned into separate subdirectories:
- All restricted pages and controls are located in these subdirectories.
Check restricted subdirectories are configured to require authenticated access in a Web.config file.
Check that the restricted subdirectories are configured in IIS to require SSL:
- Navigate to the restricted subdirectory in IIS
- Open up the Properties dialog for that subdirectory
- Click the
- Click the
Editbutton in the "Secure communications" area
- Require secure channel (SSL) should be checked to require HTTPS to be used (note: a certificate must be installed for the web site in order for SSL to be usable)
Check that all URLs that reference restricted pages use HTTPS
Check that any redirects (
in ASP.NET code-behind files use absolute URLs:
- Redirects to restricted pages use HTTPS (
- Redirects to anonymous pages use HTTPS (
Check ASP.NET code-behind files do not use
Server.Transfer is to redirect from an anonymous pages (
to a secure page (
Check that unauthenticated access to restricted pages redirects to the default login page.
- ASP.NET Authorization (msdn2.microsoft.com/en-us/library/wce3kxhd(vs.80).aspx) (MSDN Library)
- Chapter 10 - Building Secure ASP.NET Pages and Controls (msdn2.microsoft.com/en-us/library/aa302426.aspx) (MSDN Library)
- How To: Set Up SSL on a Web Server (msdn2.microsoft.com/en-us/library/aa302411.aspx) (MSDN Library)
3. Code-behind files are used rather than inline server-side script blocks
Modularity, Complexity, Understandability, Learnability
ASPX (page) and ASCX (user control) files should not contain any inline
server-side scripting. ASPX and ASCX files should only contain the
visual elements of the page such as HTML and server controls, static text,
CSS, etc. The programming logic for the page should be contained in a
separate file called a
Code-behind file. Programming logic consists
of event handlers and other .NET code.
Note: The code-behind model is the default model used for new pages when working in Visual Studio .NET.
It is considered bad practice to mix HTML/XHTML and programming code in
the same physical file. Inline programming code appears in
> blocks with the
runat="server" attribute value. Inline programming mixed with HTML/XHTML is harder to
understand, maintain, and reuse.
Code-behind files provide a clean separation of UI programming logic from presentation elements. Another advantage is that designers can work on the ASPX files in parallel to developers working on the code-behind file. Designers do not see the inline programming logic in their files.
Note: Commonly used code in page code-behind files can be moved to a base class so that other page code-behind classes derive from this base class and inherit common functionality. This allows code to be reused and avoids duplication of code in every page.
Every ASP.NET Page should use the Code-Behind Model by separating UI
presentation element into the
file and programming logic into a
.aspx.vb file (in the
case of Visual Basic).
Every ASP.NET Web User Control should use the Code-Behind Model by
separating UI presentation element into the
.ascx file and programming logic into a
.ascx.vb file (in the case of Visual Basic).
... </script> blocks appear in the
.aspx (page) file:
runat="server"should be found.
- A corresponding Code-behind file should existing with the same
.aspx.vbextension (in the case of Visual Basic).
.ascx (user control) file:
runat="server"should be found.
- A corresponding Code-behind file should existing with the same name but .ascx.vb extension (in the case of Visual Basic).
4. Code-behind files are not used as a container for Business Logic and/or Data Access Logic
Complexity, Modularity, Generality, Scalability, Understandability, Learnability
Do not place data-access or business-logic code in code-behind files. Code-behind
files should only contain UI programming logic such as event handlers for
ASP.NET server controls and page events. Place data-access code and
business-logic into classes located in a separate class library (called an
assembly in .NET).
Note: If business logic is performed solely in stored-procedures in the database then data-access code should still be located in a separate assembly which accesses these stored procedures.
Code-behind files form what is known as the "presentation" layer in a three-layer programming model. Business logic code and data-access code should be placed in separate layers. Separating these "concerns" into different layers is a tenet of good software design.
Separating the business-logic and data-access logic into separate class libraries allows deployment of this logic into a separate physical tiers (such as an Application Server) and supports scaling out the web application if required.
Code-behind files should only contain presentation-related programming logic such as event handlers which work with the UI elements (ASP.NET Server Controls, HTML Controls).
- Code-behind files can make use of data-access and/or business logic classes referenced in separate class libraries.
Code-behind files must not directly contain data-access code (such as ADO.NET classes or the Data Access Application Block) or business logic rules
- Input validation for form fields, query strings, etc, is allowed.
Typed or untyped DataSets (and associated classes like DataTables,
DataRows, DataColumns, DataViews, etc) can be used from the ADO.NET
System.Data for data binding to GridView, DataList,
and Repeater controls. Other ADO.NET classes should not be used in
the presentation logic.
Check code-behind files for use of ADO.NET classes:
- Check for references to namespaces starting with
- Namespaces other than
System.Datashould not be referenced (e.g.
- Classes other those forming part disconnected ADO.NET
Constraint, etc) should not be used.
IDataReaderinterface should not be used (since it relies on the connected model of data access via a stream)
- Namespaces other than
- Check for references to the Data Access Application Block
- Search for
- Search for
Embedded Code Blocks in ASP.NET Web Pages (msdn2.microsoft.com/en-us/library/ms178135(VS.80).aspx) (MSDN Library)
5. Master Pages are used as a means to create a consistent layout for web applications
Generality, Complexity, Understandability
Master Pages are the preferred method of creating standard layout templates in ASP.NET 2.0 when creating a consistent layout for a site.
In a typical web application, some areas of the page are common to all pages such as the header, footer, menus, etc. A Master Page allows the factoring out of common features to be shared by all pages and each specific page using the Master Page can then add its own unique content to the designated content placeholders.
Master Pages are only supported in ASP.NET 2.0 or higher. Previously, Server-Side Include (classic ASP), or referenced User Controls (ASP.NET 1.x) were used to create common layout templates.
Some disadvantages with Server-Side Includes:
- No IDE support for editing files that have SSI directives
- Easy to have unbalanced tags or insert content into wrong location
- Difficult for pages to alter elements in the includes templates (e.g. setting the page title)
Some disadvantages with referencing and using User Controls on each page:
- Requires each page to use the
@Registerdirective to reference each User Control
- User Controls do not specify the layout themselves, they are merely
reusable components to appear on pages
- Changing the position of a User Control on one page requires a change to multiple pages across the site
- There is no concept of a shared layout; each page must specify the location of each referenced control
- No Visual Studio designer integration for viewing templated page using User Controls (VS.NET 2003)
- Requires "clever" custom programming techniques to achieve shared templates by injecting controls into well-know locations in the page control hierarchy
Reasons to use Master Pages for creating consistent layouts:
- Visual Studio 2005 integrated designer support
- Standard way to create templated sites in ASP.NET 2.0
- Master Pages act as templates for Content Pages which fill in the content placeholders
- Master Pages use
Visual Inheritancerather than
- Master Pages can be nested within other Master Pages
- Master Pages can provide default content for their content placeholders
- Use Master Pages for creating a shared common layout for the web application.
- Do not use User Controls outside of a Master Page to create a common
layout for a group of pages.
- User Controls can be used within Master Pages.
Master Pages were introduced in ASP.NET 2.0. Versions prior to this do not support Master Pages and a custom method of templating must be used. Typically, this involves adding User Controls to every page in a consistent fashion in order to achieve a standard layout.
Check for presence of
.master files which indicate Master Pages.
Check to see that the other ASP.NET pages (.aspx) reference these
master pages (via the
MasterPageFile attribute of
@Page directiveat the top of the page):
<%@ Page MasterPageFile="~/SiteTemplate.master" %>
If Master Pages are not used, search the ASP.NET pages (.aspx files)
@Register directive at the top of the file.
Note down the controls which are being used on each page and determine if any of these is repeated on all or a subset of pages such that the controls always appear in the same location on all the pages (look for headers, footers, menus, navigation bars, and similar controls).
- Master Your Site Design with Visual Inheritance and Page Templates (http://msdn.microsoft.com/en-au/magazine/cc163967.aspx) (MSDN Magazine)
- Master Pages in ASP.NET 2.0 (msdn2.microsoft.com/en-us/library/ms379585(VS.80).aspx) (MSDN Library)
- Master Pages (www.asp.net/learn/moving-to-asp.net-2.0/module-04.aspx) (The Official Microsoft ASP.NET 2.0 site)
6. Commonly used page elements are separated into Web User Controls and/or Web Custom Controls
Commonly used page elements should be placed in separate controls to avoid duplication of code, facilitate code/component reuse, improve maintainability, and caching effectiveness.
Web User Controls should be used to group several ASP.NET server controls (and HTML) together to form a single composite control which can be reused throughout the application (e.g. on Master Pages).
Web User Controls are recommended as they are easier to implement and have integrated designer support.
Web Custom Controls can also be used if controls are to be shared across multiple web applications, however, they must be implemented programmatically without integrated designer support.
Web User Controls can take advantage of fragment caching if content does not vary often which can improve the web application performance.
When factoring out common functionality in controls, try to separate static content from dynamic content to allow page output and fragment caching to be use more effectively.
Commonly used page elements should be placed in separate web user or custom controls.
Examine the web application pages in Visual Studio:
- For content which appears to be similar across more than one
page, check that web user controls or custom controls have been used to
avoid duplication of code and mark-up.
- Web user controls are contained in files ending in
.ascxand control the
@Controldirective at the top of the file.
- Other pages (including Master Pages) can use the controls by
referencing them via the
@Registerdirective near the top of the file.
- Web user controls are contained in files ending in
- Building Maintainable Web Interfaces with ASP.NET (msdn2.microsoft.com/en-us/library/ms978615.aspx) (MSDN Library)
- Recommendations for Web User Controls vs. Web Custom Controls (msdn2.microsoft.com/en-us/library/aa651710(VS.71).aspx) (MSDN Library)
- Look for parts of the application which appear to function dynamically without posting back to the server (thus avoiding a full page refresh).
- Check that the application functions correctly.
8. Server-side validation is performed on all user inputs from sources such as HTML controls, Query String, and Cookies
Server side validation of user input is required to help prevent invalid or malicious data getting into the system. Malicious data can include Script injection or SQL injection attacks.
User inputs can come from sources such as:
- HTML form controls (including hidden fields)
- Query Strings
- View State
- HTTP Headers
All input form fields should be validated using the ASP.NET validation server controls. These built-in server controls save the developer a lot of time and effort in validating their HTML form inputs.
Client-side validation of input form fields can save round-trips to the
server which improves performance, however, custom validation scripts should
be avoided when an ASP.NET validation server control can do the job. The ASP.NET validation server controls automatically detect if the browser
client-side validation scripts behind the scenes when the page is loaded
without any work from the developer (except for the
The validation code should check that the length, type, and range of data
is valid. For enumerations, check against a known legal set of values.
For data type checking, use
TryParse methods and check the
Boolean result, rather than
Parse which throws an exception
upon invalid data.
Any problems found with the input data should be communicated back to the user in a clear and concise manner. When echoing user inputs back to the user always HTML encode the echoed values to foil any maliciously injected scripts.
For multi-tier applications where the business logic and/or data access layer code reside on a middle-tier (e.g. an Application Server) it is important to re-validate any inputs since you cannot rely on inputs having come from a known source (such as the Web Server). The Validation Application Block (msdn2.microsoft.com/en-us/library/bb410105.aspx) can be used for coding validation rules into your business logic and/or data access layer code.
All user inputs are validated server-side.
A HTML form MyForm contains a text field MyField that expects a mandatory value between 10 and 30.
When the data is submitted to the server it must be checked for the following:
- There is a value submitted
- The value is an integer
- The value is >= 10
- The value is <= 30
Check the server-side code for evidence of input data validation.
ASP.NET validation server controls:
- Validating ASP.NET Server Controls (msdn2.microsoft.com/en-us/library/Aa479013.aspx) (MSDN Library)
- Validation Form Input Controls (quickstarts.asp.net/QuickStartv20/aspnet/doc/validation/default.aspx) (ASP.NET QuickStart Tutorials)
Validating inputs in other tiers:
- Validation Application Block (msdn2.microsoft.com/en-us/library/bb410105.aspx) (MSDN Library)
9. Input form field values are retained when form is redisplayed to the user after input validation fails
When data validation is performed and an incorrect scenario has been detected an appropriate message is returned to the user. In this instance the data that had previously been entered by the user must be preserved.
Data entered by the user is to be preserved when submission of the form input data fails due to input validation errors.
Enter the application and perform the following:
- Fill out a form of the application with at least on field containing invalid data.
- Submit the data to the application.
- After the validation message has been received check that the original form is displayed and that it contains the data previously entered.
10. Data paging is used for unbounded or long lists of data
The nature of some applications means there is potential for large amounts of data to be returned to the browser. Very long lists of data returned to the client browser can cause problems with performance and scalability due to the increased network traffic and server utilisation while sending back the response. There are also usability issues as it is hard to navigate a page which displays too many records.
To mitigate these problems data paging should be used to limit the number of records that can be retrieved and displayed at any given point.
Data paging is the practice of displaying a limited number of records per page with links to the next, previous, or a specific page of records that are returned by a query.
The number of records returned per page is dependent on many factors (msdn2.microsoft.com/en-us/library/ms978510.aspx#daag_datapaging) of the system and the nature of the data being displayed. However, as a guide each page should not exceed 50 records.
Data paging must be used if a query can return more than 50 records.
Access the application and perform the following steps:
- Navigate to a search page.
- Enter criteria that will return a large number of records.
- Run the search.
- Check that the search results are limited to a reasonable number of records and there is a method of navigating to any records not currently displayed.
- Data Paging (msdn2.microsoft.com/en-us/library/ms978510.aspx#daag_datapaging) section of .NET Data Access Architecture Guide (msdn2.microsoft.com/en-us/library/ms978510.aspx) (MSDN Library)
- Efficiently Paging Through Large Amounts of Data (www.asp.net/learn/data-access/tutorial-25-vb.aspx) (The Official Microsoft ASP.NET 2.0 site)
11. Data that is frequently used but changes infrequently is cached using ASP.NET Caching
Data that is frequently accessed by the application and is common for all users should be cached using ASP.NET Caching.
ASP.NET caching can significantly improve performance and scalability of a web application under specific scenarios.
Scenarios where ASP.NET Caching is a good fit:
- Data that is accessed frequently by the application
- Data that is common/shared amongst all/many users of the application
- Data that is expensive to retrieve and/or compute
- Data that changes infrequently or only needs to be refreshed after a specific interval (e.g. every 5 mins)
Scenarios where ASP.NET Caching is not a good fit:
- Data that changes per request and stale versions of the data are not acceptable
- Data which is user-specific
- Data which contains sensitive information
- Data which must survive application restarts
- Data that is transactional
Cache object provides programmatic access to
a shared data cache and should be used over the
object for caching data as it supports features such as cached item
dependencies, priorities, and expiration policies.
When an ASP.NET application runs low on memory resources a process known as scavenging executes which removes cached items based on their priorities.
Application object does not support any of these
advanced features. However, it can still be used as a read-only memory
cache for small amounts of global data that are populated only at
application start up which are guaranteed to be in memory rather than
possibly requiring database access.
ASP.NET Pages or User Controls which are dynamically built from static or
infrequently changing data can use Page Output or Fragment Caching as an
alternative to programmatic use of the ASP.NET
Static or infrequently changing data that is frequently accessed by the application should be cached using ASP.NET Caching, if the following criteria are met:
- Data to be cached is common/shared amongst all/many users of the application - not user specific
- Data to be cached is expensive to retrieve and/or compute
- Data to be cached does not contain sensitive information
- Loss of cached data due to application restarts is not an issue
Sensitive data should not be cached.
Pages or User Controls which display sensitive data should not be cacheable.
care should be taken when caching Large datasets as memory resources may be compromised
Identify areas of the application where frequently accessed non-user-specific data is being used:
- Check that the data is not being retrieved and/or constructed for each user request.
- Check to see that a caching mechanism is being used.
- The ASP.NET
Cachecan be identified by searching for the
- Page output and fragment caching can be identified by
searching ASP.NET pages (.aspx) and user controls (.ascx) for
- The ASP.NET
Use of the intrinsic Application object for storing read/write data can be identified using the Practices Checker (www.codeplex.com/PracticesChecker) tool on the web site project and selecting the "Use Application State to Share Static, Read-Only Data" rule.
- Using the ASP.NET Cache (msdn2.microsoft.com/en-us/library/ms978500.aspx#cachingarchch2_usingaspnetcache) section of Caching Architecture Guide for .NET Framework Applications (msdn2.microsoft.com/en-us/library/ms978500.aspx) (MSDN Library)
- ASP.NET Caching (msdn2.microsoft.com/en-us/library/xsbfdd8c(vs.80).aspx) (MSDN Library)
- Caching ASP.NET Pages (msdn2.microsoft.com/en-us/library/06bh14hk(VS.80).aspx) (MSDN Library)
- @ OutputCache (msdn2.microsoft.com/en-us/library/hdxfb6cy(VS.80).aspx) (MSDN Library)
12. Pooled resources (e.g. Database connections) are not cached
Pooled resources such as database connections should not be cached as this reduces the availability of the pooled resource for other users of the application leading to scalability issues.
Pooled resources are not to be cached.
Check the code to ensure that pooled resources are released as soon as their job is completed.
The Practices Checker (www.codeplex.com/PracticesChecker) tool can be used to detect caching of pooled resources by selecting the "Do Not Cache or Block on Pooled Resources" rule.
13. Sensitive data is not cached using ASP.NET caching or in the Application state
Sensitive or confidential data should not be cached using ASP.NET caching or Application state as data stored in this manner is available to all users of the application and presents a security and privacy risk.
If sensitive data needs to be cached it is recommended that it is stored in the Session State for each user.
Sensitive data (such as passwords) must not be cached in using ASP.NET caching or Application state.
Identify senseitive data used in the web application.
Check the code to ensure that sensitive data is not being
stored in the ASP.NET
Cache object or
Check ASP.NET Pages (.aspx) and User Controls (.ascx) to ensure they
do not cache sensitive data (with the
<%@ OutputCache Duration="100" VaryByParam="None" %>- caches the page for 100 seconds.
<%@ OutputCache Location="None" %>- indicates page output/fragment caching is disabled.
Caching Architecture Guide for .NET Framework Applications (msdn2.microsoft.com/en-us/library/ms978500.aspx) (MSDN Library)
14. Sensitive information such as passwords and connection strings are not stored in any client-side state
Sensitive information must not be stored client side as it can be easily viewed or tampered with which can compromise the security of the application and related systems.
Do not store sensitive information (even if encrypted) using the client-side state such as Query Strings, Hidden form fields, Cookies, and View State.
Identify sensitive data used by the web application.
Check the code to ensure sensitive data such as passwords or connection strings are not assigned to any client-side state.
15. Web site is fully-functional when cookies are disabled in the browser
Cookies can represent a security risk for some users and so cookies may be disabled in the client browser. This cannot be controlled by the application so the application must be designed in such a way that it does not depend on cookies to function correctly.
The web site must operate normally if cookies are disabled in the browser.
Disable cookies in the browser then access the application.
Ensure that all functionality performs as expected.
16. Session state is disabled for web applications and only enabled for individual pages that require it
Session state should only be enabled for the pages that require it. This minimises the server resources used (e.g. memory) and improves performance as session state does not be retrieved, de-serialised, updated, serialised, and finally stored per user request.
Performance impact becomes more noticeable when out-of-process session state such as a SQL Server database is used for persisting session state.
Session state is disabled in the
web.config file and only enabled for individual pages that require it.
Session state is set to
ReadOnly for pages that do not modify session
state but need read access to it.
web.config, disable session state by default
<configuration> <system.web> <pages enableSessionState="False" /> </system.web> </configuration>
For pages that both read and update session state
<%@ Page EnableSessionState="True" %>
For pages that only read session state
<%@ Page EnableSessionState="ReadOnly" %>
Check that session state has not been enabled for pages that do not require it.
Checker (www.codeplex.com/PracticesChecker) tool can be used to detect pages that have session state enabled but that could potentially have session state disabled by selecting the
Disable Session State If You Do Not Use It rule.
17. View State is disabled for web applications and only enabled for individual controls that require it
View state should only be enabled for the controls that require it. This minimises the server resources used and improves performance of the application. Large amounts of view state increases the page size so sending content to the client takes longer.
View state can be disabled on a page if the following conditions are true (msdn2.microsoft.com/en-us/library/ms998549.aspx#scalenetchapt06_topic19):
- The page does not post back to itself
- The page code behind does not handle server control events
- Server controls on the page have their data repopulated with every page refresh
View state is disabled in the
web.config file and only enabled for individual
controls that require it.
A control that needs to retain its state during a post back of data should have view state enabled.
web.config,disable view state by default
<configuration> <system.web> <pages enableViewState="false" /> </system.web> </configuration>
For controls that require view state enabled
<asp:checkbox EnableViewState="true" runat="server" />
Check that controls that are not required to maintain state do not have view state enabled.
The Practices Checker tool can be used to detect pages that have view state enabled but that could potentially have view state disabled by selecting the "Disable view state if you do not need it" rule.
18. View State is not enabled for data bound controls such as drop-down lists, check box lists, grid views, repeaters, etc
View state should not be enabled for data bound controls as they should rebind their data each time the page is refreshed. The amount of data that may need to be maintained in the view state can become prohibitive for these controls. This can lead to resource and performance issues as a large View State needs to be sent back and forth between the client and server.
ASP.NET Data bound controls include:
- GridView (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview(VS.80).aspx) (which replaces the DataGrid (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.datagrid(VS.80).aspx))
- FormView (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.formview(VS.80).aspx)
- DetailsView (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview(VS.80).aspx)
- Repeater (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater(VS.80).aspx)
- DataList (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.datalist(VS.80).aspx)
Data bound controls such as drop-down lists, grid views etc must not have view state enabled.
Search for data bound server controls in the ASPX files (.aspx extension).
- For example, to check for the GridView (msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview(VS.80).aspx) control, search for
<asp:gridview id="CustomersGridView" datasourceid="CustomersSqlDataSource" autogeneratecolumns="true" autogeneratedeletebutton="true" autogenerateeditbutton="true" datakeynames="CustomerID" runat="server"> </asp:gridview>
Check that data bound controls do not have view state enabled (see standard View State is disabled for web applications and only enabled for individual controls that require it for how to check if view state is enabled).
19. The DataGrid server control is not used
The DataGrid control has been superseded in the .NET Framework 2.0 by the GridView control. This new control should be used in place of the DataGrid as it has several improvements (msdn2.microsoft.com/en-us/library/05yye6k9(VS.80).aspx) over the DataGrid.
A secondary problem is that some parts of the DataGrid will not work correctly if View State is disabled. These include Editing, Sorting, and Paging since the server-side events for these features will not fire. However, it is possible to get around this issue with some additional work (msdn2.microsoft.com/en-us/library/aa478966.aspx#aspnet-commondatagridmistakes_topic8).
The DataGrid control is not to be used.
Check that any grids within the application make use of the GridView and not the DataGrid control:
- Search for
asp:datagridto see if DataGrids are used.
- Comparing the GridView and DataGrid Web Server Controls (msdn2.microsoft.com/en-us/library/05yye6k9(VS.80).aspx) (MSDN Library)
- Enduring an Over-sized ViewState (msdn2.microsoft.com/en-us/library/aa478966.aspx#aspnet-commondatagridmistakes_topic8) section of Common Datagrid Mistakes (msdn2.microsoft.com/en-us/library/aa478966.aspx) (MSDN Library)
20. Objects are not stored in the session state
Objects should not be stored in the session state as serialisation/de-serialisation of objects is slower than serialisation of primitive types such as String, DateTime, Integer, Double, Guid, etc.
If the application uses objects to represent data kept in the session state, store the individual attributes as key/name pairs rather than the whole object as a single key/value pair. When retrieving the session state, rebuild the object from the constituent attribute key/name pairs.
Flattening an object's attributes into separate session key/value pairs provides an additional performance advantage: on-demand de-serialisation. Only those attributes which are accessed will be de-serialized. Similarly, only those key/value pairs which are modified will be serialised back into the session state (and any out-of-process session store such as SQL Server or ASP.NET State Server).
Do not store objects using session state.
Only store primitive types in the session state.
Check the code to ensure that objects are not being stored in session state:
- Search for code that stores data in the
Session("accountDetails") = accountInfo
- Fast, Scalable, and Secure Session State Management for Your Web Applications (msdn.microsoft.com/msdnmag/issues/05/09/SessionState/default.aspx) (MSDN Magazine)
21. Application state is only used for sharing application-wide read-only data for all clients
Application state should only be used for storing application-wide
read-only data that can be shared by all clients. The recommended
approach is to load the required static data in the
Application_Start event in an ASP.NET Application file (
Data should not be written to the Application state since changes are not synchronised across servers in a web farm.
User-specific data should not be stored in the Application state, use Session state for that purpose.
Sensitive data should not be stored in the Application state as it is globally accessible by all code in the application and access is not constrained to a specific user.
Avoid storing large amounts of data in the Application state as the memory cannot be reclaimed when system resources are low. Use the ASP.NET Cache instead for caching large amounts of read-only data as it supports scavenging cached items when memory is low.
Application state must only contain read-only application-wide data.
Application state is only populated at application start up.
Application state is not used for storing:
- User-specific data
- Sensitive data
- Large amounts of data (e.g. >10MB)
Check that all data stored using application state is applicable to the application as a whole:
- Search for code that stores data in the
Application("dbConnectionString") = connectionString
- ASP.NET Application State Overview (msdn2.microsoft.com/en-us/library/ms178594(VS.80).aspx) (MSDN Library)
22. HTTP error codes are handled using custom error reporting pages
HTTP errors that occur when a client request is processed should be handled using custom error reporting pages.
Custom error messages retain the look and feel of the site (rather than the default error pages presented by the browser) and provide an opportunity to display additional information to the user (such as tech support information).
Custom error pages are set up in the
Web.config file in
customErrors (msdn2.microsoft.com/en-us/library/h0hfz6fc(vs.80).aspx)> section.
A default redirect page should be provided for displaying a generic error
message (used when a specific error page is not provided). This is done via
Specific error pages should be provided for common HTTP Error codes such as:
Note: Never set the
mode attribute to
Off as detailed errors are then shown directly to remote
Custom error reporting pages are enabled in the
A default redirect page is provided for generic error reporting.
Specific error pages are provided for common HTTP error codes.
mode attribute is not set to
customErrors element (
RemoteOnly are acceptable).
Example of enabling customer errors (in the
web.configfile) with a default redirect page and specific errors pages.
<customErrors mode="RemoteOnly" defaultRedirect="AppErrors.aspx"> <error statusCode="404" redirect="NoSuchPage.aspx"/> <error statusCode="403" redirect="NoAccessAllowed.aspx"/> </customErrors>
web.config file to see that custom error
reporting is turned on and a default redirect page is provided.
Specific error pages are provided for common HTTP error codes (see above).
Best Practice Analyzer for ASP.NET (msdn2.microsoft.com/en-us/vstudio/aa718345.aspx) tool can be used to check a
customErrors section is set correctly for a production environment.
23. Unhandled exceptions are caught using an application-level global error handler
Unhandled exceptions within an application should be caught and managed in a consistent and safe manner. This can be best achieved by using a global error handler that can trap all unhandled exceptions, log the details, then present a safe error page to the user (without exposing any sensitive data).
Note: If you redirect to another page in a Global Error
Handler, it takes precedence over the
customErrors element of a
file. If you do not redirect to another page in the Global Error
defaultRedirect page is used (so ensure one is specified).
Exceptions are processed using an application-level global error handler.
Sample Global Error Handler (Visual Basic)
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) ' Get the error message of the unhandled exception. Dim errorMessage As String = Server.GetLastError.Message ' TODO: Do something with the error, e.g. ' - Send an email ' - Log the error details, stack trace, etc. ' Transfer to custom error page. Server.Transfer("ReportError.aspx") End Sub
Check the project for the presence of a Global.asax file which contains a Global Error Handler (Application_Error event handler).
- This can also be checked using the Practices Checker (www.codeplex.com/PracticesChecker) tool by using the "Implement a Global.asax error handler" rule.
Check that the Global Error Handler does at least the following tasks:
- Logs the server exception
- Redirects to a safe error page (either explicitly or via the defaultRedirect attribute of the customErrors element in the web.config file, see standard HTTP error codes are handled using custom error reporting pages)
- Creating a Global Error Handler section of How to: Display Safe Error Messages (msdn2.microsoft.com/en-us/library/994a1482(VS.80).aspx) (MSDN Library)
24. Configurable application settings are stored in the web application's Web.config file
Application settings which are subject to change when the application is
deployed into different environments should be placed in an
ASP.NET Configuration File (msdn2.microsoft.com/en-us/library/ms178684(VS.80).aspx) (named
web.config file has many pre-defined sections for commonly
configured settings such as database connection strings. Additional
application settings can be added to the
The .NET Framework provides the
(located in the
System.Web.Configuration namespace) class
for working with web application settings.
Configurable application settings should be stored in the
Do not use the Windows Registry or custom files (e.g. INI files) for storing web application settings.
Check the web application for deployed files that are used for storing application settings.
- Only the
web.configfile should be used for application settings
Search the source code for use of the Windows Registry:
25. Request validation is enabled to prevent scripting attacks
Request validation should be enabled to protect against Script Injection
attacks. Request validation prevents processing of a client request when
it detects embedded HTML elements (such as
or reserved characters.
If HTML input is required from users then care should be taken to constrain the allowed HTML tags to a small set of "safe" tags. This requires manual server-side checking (e.g. using Regular Expressions (msdn2.microsoft.com/en-us/library/ms998267.aspx)).
Request validation is always enabled.
If HTML input is required from users, request validation can be turned off at the page level. However, adequate server-side validation and sanitisation of the input data must be done.
Sanitizing Free-Text Fields and
Allowing Restricted HTML Input in
To: Protect From Injection Attacks in ASP.NET (msdn2.microsoft.com/en-us/library/bb355989.aspx) for further
web.config file to ensure request
validation is enabled for the entire web application:
<configuration> <system.web> <pages validateRequest="true" /> </system.web> </configuration>
Check for individual pages that have disabled request validation:
<%@ Page validateRequest="false" %>
- Ensure necessary validation has been implemented on the server-side to protected against Script Injection attacks.
- Request Validation - Preventing Script Attacks (www.asp.net/learn/whitepapers/request-validation/) (The Official Microsoft ASP.NET 2.0 Site)
- How To: Use Regular Expressions to Constrain Input in ASP.NET (msdn2.microsoft.com/en-us/library/ms998267.aspx) (MSDN Library)
- How To: Protect From Injection Attacks in ASP.NET (msdn2.microsoft.com/en-us/library/bb355989.aspx) (MSDN Library)
26. Page output buffering is enabled
Page output buffering reduces server round trips thus avoiding chatty communication between client and server. There is a significant performance cost for disabling buffering of pages.
Page output buffering is enabled for all pages.
Check output buffering has not been disabled at the application level by checking the web.config file:
<pages buffer="true" .>
Check output buffering has not be disabled at the page (.aspx) level by check all pages:
<%@ Page Buffer = "false" %>
Check output buffering has not been disabled in source code programmatically by checking all source for:
Response.BufferOutput = True
Or you can use the Practices Checker (www.codeplex.com/PracticesChecker) tool to ensure page output buffering is enabled by selecting the "Enable Buffering" rule.
References go here...
27. ASP.NET tracing and debugging are disabled
ASP.NET tracing and debugging should be disabled for web applications in a production environment.
Debugging reduces the performance of an application.
Tracing is a potential security risk as sensitive application tracing data and server variables can be viewed from an ordinary web browser.
ASP.NET Tracing and Debugging should be disabled in a production environment.
web.config file to ensure ASP.NET Tracing
and Debugging are disabled:
<configuration> <system.web> <trace enabled="false" pageOutput="false" /> <compilation debug="false" /> </system.web> </configuration>
Check individual ASP.NET pages (.aspx) to ensure tracing and debugging have not been turned on, thus overriding the setting in the web.config file.
<%@ Page Debug="True" Trace="True" ... %>
Best Practice Analyzer for ASP.NET (msdn2.microsoft.com/en-us/vstudio/aa718345.aspx) tool can check a
web.config file to verify ASP.NET tracing and debugging are set
correctly for a production environment.
28. Database connection string should be encrypted
Encrypting the database connection string in a web.config to prevent the exposure of the database login and password.
Database connection string in Web.Config file MUST be encrypted
web.config file to ensure
<configProtectedData> is used.
Liaise with WebFarm Administrator to arrange for web.config encrypted in Production.
- Encrypting Sections of the Web.config File (msdn2.microsoft.com/en-us/library/y13fw6we(vs.80).aspx) (MSDN Library)