THE ASP.NET View State Dino Esposito Download The Code for this article: cuttingedge0302.exe (39KB)
I n ASP.NET pages, the view state represents the state of the page when it was last processed on the server. It's used to build a call context and retain values across two successive requests for the same page. By default, the state is persisted on the client using a hidden field added to the page and is restored on the server before the page request is processed. The view state travels back and forth with the page itself, but does not represent or contain any information that's relevant to client- side page display. in this column, I'll take a tour of the view state implementation in ASP.NET and show how to keep your Web pages fit and trim and a bit more secure.View State Pros and Cons View state has pros and cons that you might want to weigh carefully before making a decision to use it. First, view state does not require any server state resources and is simple to implement. View state, though, does require computational effort on the server and the cost of sending The Extra Data Ove . R the wire Since it's a physical part of the page, it's fast to retrieve and use; for this same reason, though, it can become a weakness that can be exploited Because the view state is packed with the page, it inevitably adds. a few extra kilobytes of data to the payload. A complex, real-world page-especially one that does not optimize and restrict the use of the view state-can easily find 10KB of extra stuff packed in the HTML code sent to the browser. BECAUSE IT '
s composed of plain text, the view state could be tampered with. Although programmers are not supposed to store sensitive data in the view state (credit card numbers, passwords, or connection strings, for example), it goes without saying that the view state can be used to carry out attacks on the server. View state is not a security hole per se, but just like query strings and other hidden fields you may have used in the past, it's a potential vehicle for malicious code. Since the view state is encoded, protected, and validated, it does provide more security features than other hidden fields that you may use for your own programming purposes. View state is one of the most important features of ASP.NET, not so much because of its technical relevance , but more because it makes the magic of the Web Forms model possible. However, if used carelessly, view state can easily become a burden.The StateBag Class StateBag implements the view state and manages the information that ASP.NET pages a nd embedded controls persist across successive posts of the same page instance. The class works like a dictionary object and implements the IStateManager interface. The Page and the Control base classes expose the view state through the ViewState property. So you can add or remove items from Statebag as you would with any Dictionary Object: ViewState ["fontsize"] = value;
You should start writing to the view state only after the Init event is fired for a page request. You can read from the view state during any stage of the page lifecycle, but not after the page enters rendering mode-that is, after the PreRender event is fired. Figure 1 lists the properties and the methods defined for StateBag. Each item in the StateBag class is represented by a StateItem object. An instance of the object is implicitly created when you set the Item indexer property with a value or when you call the Add method. Items added to the StateBag object are tracked until the view state is saved to the storage medium using the page's SaveViewState method. If a state item has not been saved, IsDirty property will be True. The IsItemDirty method represents an indirect way to call into the IsDirty method of a StateItem object. The contents of the StateBag collection are first serialized to a string, then Base64 encoded, and finally assigned to a hidden field in the page that is ser ved to the client. The view state for the page is a cumulative property that results from the contents of the ViewState property of the page plus the view state of all the controls hosted in the page.Security Issues Architecturally speaking, the importance of the view state can not be denied since it is key to setting up the automatic state management feature of ASP.NET. A couple of hot issues surround its use, however. Most of the frequently asked questions about it are related to security and performance. Let's tackle security First. Many Developers Are HeSitant To Use View State Because IT '
s stored in a hidden field and left on the client where it has the potential for compromise. As Figure 2 shows, the information can be read by viewing the source of the page. While this action alone is not a threat to the application, having the view state on the client is a potential security issue because it is information that all ASP.NET pages contain and transmit to the Web server for processing.Figure 2 ViewState is Visible in Source Although freely accessible in a hidden field called __VIEWSTATE, the view state information is not clear text. By default, a machine-specific authentication code is calculated on the data and appended to the view state string. The resulting text is then Base64 encoded only, but not encrypted. If data confidentiality is desired, however, then SSL is the only solution since it protects not only view state, but all the data that travels to and from the page Decoding view state is still possible, but a number of steps must be accomplished;. not only mus t several undocumented and internal structures be disassembled, but a number of circumstances must also occur. In addition, consider that a tampered view state is normally detected on the server and a security exception is thrown. Finally, and most important of all, the view State Contains Data, Not Code. Unless Security Settings for the Default Security Settings for the Default Security Settings for the Page, There '
s not much a hacker can do to modify the view state. If you change the default security settings, though, you should be careful about the view state. A hacker could modify the data that represents the state of the page. This is not a bug per se and opens holes for attacks only if the basic rules of data validation and data checking are not enforced. But this, you understand, is a more general problem when you're trying to write secure code. The view state internal implementation is quite complex and layered enough to discourage attacks. Encryption is the most important element in protecting view state information. in order to make the view state more secure, the ASP.NET @Page directive supports an attribute called EnableViewStateMac whose only purpose is detecting any possible attempt at corrupting original data. (The "Mac" in EnableViewStateMac stands for machine authentication check and, despite what some documentation claims, it is enabled by default.) When serialized, and if Enab leViewStateMac is set to True, the view state is appended with a validator hash string based on the algorithm and the key defined in the
s Local Security Authority (LSA) subsystem. The LSA is a protected component of Windows NT®, Windows® 2000, and Windows XP. It provides security services and maintains information about all aspects of local security on a system. If EnableViewStateMac is True, then when the page posts back the encrypted view state is algorithmically checked to verify that it has not been tampered with on the client. The net effect is that you might be able to read the contents of the view state, but to replace it you need the encryption key, which is in the Web server's LSA. The EnableViewStateMac directive attribute corresponds to a protected page member with the same name. The EnableViewStateMac property defaults to True. The following excerpt comes from the source code that the ASP.NET runtime generates for A Running .aspx page. (You can ketain it by adding the debug = true attribute to the @Page Directive and search for the source code in the temporary system folder of your asp.net application.) Protected Override void frameworkinitialize () {this .__ BuildControlTree (this);
THIS.FILEDEPENDENCIES = __FILEDEpendencies;
THIS.ENABLEVIEWSTATEMAC = TRUE;
}
If you're particularly concerned about attacks through the view state, simply make sure that EnableViewStateMac is on. You should look carefully at your own view state. If you maintain the default settings you should be OK. Later, after discussing performance issues, I 'll return to security. At that time I'll discuss a possible alternative implementation of the view state that addresses both security concerns and bandwidth overhead.Performance Issues Keeping the default view state settings is fine from a security perspective, but not in terms of performance. The view state can reach a considerable size, especially for feature-rich pages that make use of plenty of controls. This extra burden can cause serious overhead for the application as a whole. By default, the view state is enabled for all server Controls, But this Doesn't Mean That You Need The Time. View State Saves You a Lot of Coding and, More Importantly, Makes Your Job Simpler. But if you find you're paying too much for this feature, drop view state altogether and reinitialize the state of the server controls at every postback. In this case, disabling view state saves processing time and speeds up the download process. You can disable the view state for an entire page by setting the EnableViewState Attribute of The @Page Directive To False: <% @Page EnableViewState = "false"%>
While this is not usually recommended, you should definitely consider it for read-only pages that either do not post back or do not need state to be maintained. A better approach entails disabling the view state only for some of the server controls hosted In the page. To Disable View State ON A Per-Control Basis, Set The EnableViewState Property of The Control To False, As Shown Here:
ask: DataGrid>
While developing the page, you can keep the size of the view state under control by enabling tracing on the page. Once you have set the @ Page's trace attribute to true, look under the ViewState column of the control tree, as shown in Figure 3 . The tracer does not show the total size of the view state for the page, but it gives you a precise idea of what each control does. In Figure 3, the page is made of a relatively simple DataGrid control. As you can see , the cells of the grid take up a large part of the view state. The TableCell control, in particular, saves complete user interface information in the view state, including text, column and row span, and style attributes. Contrary to what many developers think, the DataGrid server control does not store its data source in the view state. It caches almost all of its public properties, but the amount of space required is in no way related to the data source. However, the DataGrid uses child controls , Like the Tablecell, Which Store THEI r text and style in view state, too. The text displayed in the cells is a subset of the DataGrid's data source.Figure 4 Retrieve ViewState String In Figure 4, I've reworked the page in Figure 3 to add a client-side button That Retrieves The View State String And Calcript Code for this Is Pretty Simple: