Return to
HomePage
Encoding Output within a DataTable (C#)
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 (<,>,&,",').
Applies to
* ASP.NET 2.0
* C#
* Server-side
* SQL Server
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 void
LoadEncodedPeopleTableEvent(SqlDataAdapter adapter)
{
// Build a Data Grid to house our data and add to the set of page controls
[DataGrid] dataGrid = new [DataGrid();]
this.Controls.Add(dataGrid);
// Create a new data table and fill our that table with names from the adapter
[DataTable] names = new [DataTable();]
adapter.Fill(names);
// add an event handler to our [DataGrid] to encode the data
[dataGrid.ItemDataBound] += new DataGridItemEventHandler(dataGrid_EncodeItem);
// Present the data to the user in the previously created Data Grid
[dataGrid.DataSource] = names;
[dataGrid.DataBind();]
}
public void dataGrid_EncodeItem(object sender,
DataGridItemEventArgs e)
{
// Encode each actual data row presented within the Data Grid
if [(e.Item.ItemType.Equals(ListItemType.Item)] ||
[e.Item.ItemType.Equals(ListItemType.AlternatingItem))]
{
e.Item.Cells[0].Text = Server.HtmlEncode(e.Item.Cells[0].Text);
}
}
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.
Solution Example #2: Using the DataGrid ItemDataBound eventThe 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 void
LoadEncodedPeopleTableLoop(SqlDataAdapter adapter)
{
// Build a Data Grid to house our data and add to the set of page controls
[DataGrid] dataGrid = new [DataGrid();]
this.Controls.Add(dataGrid);
// Create a new data table and fill our that table with names from the adapter
[DataTable] names = new [DataTable();]
adapter.Fill(names);
foreach [(DataRow] row in names.Rows)
{
row["Name"] = Server.HtmlEncode((string)row["Name"]);
[row.EndEdit();]
}
// Present the data to the user in the previously created Data Grid
[dataGrid.DataSource] = names;
[dataGrid.DataBind();]
}
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
DataGrid dataGrid = new
DataGrid(); this.Controls.Add(dataGrid);
// Create a new database connection using Integrated Security and open that connection
string connectionString = "Initial Catalog=snippets;Data Source=vm-win2003\\sqlexpress;Integrated Security=SSPI;";
SqlConnection cn = new
SqlConnection(connectionString); cn.Open();
// Create a new SQL Command object with a query to execute the stored procedure
SqlCommand cmd = new SqlCommand("exec spFullNames", cn);
SqlDataAdapter adapter = new
SqlDataAdapter(cmd); // Create a new data table and fill our that table with names from the adapter
DataTable names = 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:
using System.Data;
using
System.Data.SqlClient; using System.Web;
Create a new C# ASP.NET application and use the following Page_Load method to test the provided example methods (adjust database code for your example):
protected void Page_Load(object sender,
EventArgs e)
{
if (!Page.IsPostBack)
{
// Create a new database connection using Integrated Security and open that connection
string connectionString = "Initial Catalog=snippets;Data Source=vm-win2003\\sqlexpress;Integrated Security=SSPI;";
[SqlConnection] cn = new [SqlConnection(connectionString);]
cn.Open();
// Create a new SQL Command object with a query to execute the stored procedure
[SqlCommand] cmd = new SqlCommand("exec spFullNames", cn);
[SqlDataAdapter] adapter = new [SqlDataAdapter(cmd);]
[LoadEncodedPeopleTableEvent(adapter);]
}
}
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, C#
*
Category: Data Validation
*
Author: Jonathan Bailey
Return to
HomePage