Return to
HomePage
Encoding Output within a DataTable (VB.NET)
Applies To
* ASP.NET 2.0
* VB.NET
Summary
This code demonstrates how to implement security output encoding when using the .NET
DataTable object to display application data. Output encoding mitigates against client-side script vulnerabilities by representing output data using escape character equivalents for values that might otherwise be interpreted by the browser, such as those characters used in the formatting of HTML pages (<,>,&,",').
Objectives
* Protect application users from client-side scripting attacks
* Ensure that malicious data that may pre-date input validation routines or have been missed through poor validation does not render as application output
Scenarios
* Database-backed web application that uses data tables to present output
* Application that uses data tables to present input from an untrusted source
Solution Example
'Solution Example #1: Looping through the DataTableThe following code illustrates the use of output encoding accomplished
by looping through the
DataRow object and calling
Server.HtmlEncode for
each output value we wish to encode.
Public Sub
LoadEncodedPeopleTableEvent(ByVal adapter As
SqlDataAdapter)
' Build a Data Grid to house our data and add to the set of page controls
Dim dataGrid As [DataGrid] = New [DataGrid()]
Me.Controls.Add(dataGrid)
' Create a new data table and fill our that table with names from the adapter
Dim names As [DataTable] = New [DataTable()]
adapter.Fill(names)
' Manually register the event-handling method for the
' [ItemDataBound] event of the [DataGrid] control.
[AddHandler] [dataGrid.ItemDataBound,] [AddressOf] dataGrid_EncodeItem
' Present the data to the user in the previously created Data Grid
[dataGrid.DataSource] = names
[dataGrid.DataBind()]
End Sub
Private Sub dataGrid_EncodeItem(ByVal sender As Object,
ByVal e As
DataGridItemEventArgs)
' Encode each actual data row presented within the Data Grid
If [e.Item.ItemType.Equals(ListItemType.Item)] Or [e.Item.ItemType.Equals] [(ListItemType.AlternatingItem)] Then
e.Item.Cells(0).Text = [Server.HtmlEncode(e.Item.Cells(0).Text)]
End If
End Sub
This approach is flexible and can be used in a variety of different data presentation settings. For the example data above, the row containing malicious Javascript will be encoded and presented as escaped HTML output.
The following code illustrates the use of output encoding accomplished by associating a custom encoding handler within the
ItemDataBound event support by the
DataGrid in use for rendering the application output.
Public Sub
LoadEncodedPeopleTableLoop(ByVal adapter As
SqlDataAdapter)
' Build a Data Grid to house our data and add to the set of page controls
Dim dataGrid As [DataGrid] = New [DataGrid()]
Me.Controls.Add(dataGrid)
' Create a new data table and fill our that table with names from the adapter
Dim names As [DataTable] = New [DataTable()]
adapter.Fill(names)
Dim row As [DataRow]
For Each row In names.Rows
row("Name") = Server.HtmlEncode(CType(row("Name"), String))
[row.EndEdit()]
Next
' Present the data to the user in the previously created Data Grid
[dataGrid.DataSource] = names
[dataGrid.DataBind()]
End Sub
This solution takes advantage of the event-driven architecture of .NET and eliminates the requirement to loop through the
DataTable in order to access individual data items. Where presentation of data makes use of an object such as a
DataGrid that supports data binding events, we recommend this approach for reasons of performance and architectural consistency.
Problem Example
The following example demonstrates the use of a
DataTable to query data without the use of any output encoding:
' Build a datagrid to house our data and add to the set of page controls
Dim dataGrid As
DataGrid = New
DataGrid() Me.Controls.Add(dataGrid)
' Create a new database connection using Integrated Security and open that connection
Dim connectionString As String = "Initial Catalog=snippets;Data Source=vm-win2003\sqlexpress;Integrated Security=SSPI;"
Dim cn As
SqlConnection = New
SqlConnection(connectionString) cn.Open()
' Create a new SQL Command object with a query to execute the stored procedure
Dim cmd As
SqlCommand = New SqlCommand("exec spFullNames",cn)
Dim adapter As
SqlDataAdapter = New
SqlDataAdapter(cmd) ' Create a new data table and fill our that table with names from the adapter
Dim names As
DataTable = New
DataTable() adapter.Fill(names)
' Present the data to the user in the previously created Data Grid
dataGrid.DataSource = names
dataGrid.DataBind() * Any HTML data present within the database query output will be rendered as part of the application HTML output
* Any Javascript data present within the database query output will be rendered as part of the application HTML output
* Code is vulnerable to client-side script attacks such as cross-site scripting (XSS)
Test Case
The following classes must be included in any project making use of the sample code provided above:
Imports System.Data
Imports
System.Data.SqlClient Imports System.Web
Create a new VB ASP.NET application and use the following Page_Load method to test the provided example methods (adjust database code for your example):
Protected Sub Page_Load(ByVal Source As Object,
ByVal E As
EventArgs) Handles
MyBase.Load
If Not [Page.IsPostBack] Then
' Create a new database connection using Integrated Security and open that connection
Dim connectionString As String = "Initial Catalog=snippets;Data Source=vm-win2003\\sqlexpress;Integrated Security=SSPI;"
Dim cn As [SqlConnection] = New [SqlConnection(connectionString)]
cn.Open()
' Create a new SQL Command object with a query to execute the stored procedure
Dim cmd As [SqlCommand] = New SqlCommand("exec spFullNames",cn)
Dim adapter As [SqlDataAdapter] = New [SqlDataAdapter(cmd)]
[LoadEncodedPeopleTableEvent(adapter)]
End If
End Sub
Expected Result
<table cellspacing="0" rules="all" border="1" style="border-collapse:collapse;">
<tr><td>Name</td></tr>
<tr><td>Elvin Jones</td></tr>
<tr><td>Gene Krupa</td></tr>
<tr><td>Tony Williams</td></tr>
<tr><td><script>alert('XSS!');</script> XSS</td></tr>
</table>
More Information
* In addition to output validation, developers should always validate any input that originates from untrusted sources, such as application users or external feeds.
Additional Resources
* Preventing Cross-Site Scripting Attacks (.NET): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000001.asp
* Anti-Cross Site Scripting Library (.NET): http://www.microsoft.com/downloads/details.aspx?familyid=9A2B9C92-7AD9-496C-9A89-AF08DE2E5982&displaylang=en
Attributes
*
Applies To: .NET Framework 2.0, VB
*
Category: Data Validation
*
Author: Jonathan Bailey
Return to
HomePage