From the perspective of a browser, a Web page is simply a long string of characters. The browser processes the string sequentially, displaying some characters while interpreting other characters such as
<script> according to special rules. If a malicious user can insert some of those special characters into a page, the browser will not know that the characters are not supposed to be there, and it will process them as part of the page.
A simplistic script exploit might work as follows. Imagine an application that allows users to post comments about the latest movies for other users to read. The exploit steps might be:
- The application displays a form where users enter comments. The malicious user writes a comment that includes a
<script>block in it.
- The form is posted and the malicious user's comment is stored in a database.
- Another user visits the site. When the page is constructed, it reads comments out of the database and puts them into the page. The malicious user's
<script>block is written into the page as if it were a text comment.
- When the second user's browser displays the page, it gets to the
scriptblock and executes it.
There are other ways that malicious users can exploit script as well. The common thread is that most script exploits require the application to accept the malicious input and inject it (echo it) into a page where it will be executed by the browser. The potential damage from such an exploit depends on the script that is executed. It can be trivial, such as an annoying message that pops up in the browser. But it can also do serious damage by stealing cookies, stealing user input (such as a password), and if Internet security is lax, even running native code on the user's computer.
For information about preventing scripting exploits, see Protecting Against Script Exploits in a Web Application.
SQL Statement Exploits
A variation on a script exploit is one that causes malicious SQL statements to be executed. This can occur if an application prompts users for information and then concatenates the user's input into a string representing the SQL statement. For example, an application might prompt for a customer name with the intention of executing a statement such as the following:
"Select * From Customers where CustomerName = " & txtCustomerName.Value
But a malicious user who knows something about the database could use the text box to enter an embedded SQL statement with the customer name, resulting in a statement like the following:
Select * From Customers Where CustomerName = 'a' Delete From Customers Where CustomerName > ''
When the query is executed, the database is compromised.
Guarding Against Scripting Exploits
The primary defense against scripting exploits is to simply never trust information coming from a user. Assume that any data posted to your application from a browser can contain malicious script.
Similarly, any time that you write a string into a page, you should assume the string could contain malicious script. (Unless you programmatically created the string yourself.) For example, when you read strings out of a database, you should assume that they can contain malicious script. The most security-conscious developers distrust even their own databases, on the theory that a malicious user might have found a way to tamper with the database.
ASP.NET provides you with several ways to protect against scripting exploits:
- ASP.NET protects you against this automatically with request validation. By default, if the Request object contains HTML-encoded elements or certain HTML characters (such as
—for an em dash), the ASP.NET page framework raises an error. It is recommended that you create a handler in your application for this error.
- If you want to display strings in your application but do not trust them, apply HTML encoding to them. For example, with encoding, the tag
<b>. You might do this if the strings you are displaying are from a database whose contents you are not sure you can trust.
- If you want your application to accept some HTML (for example, some formatting instructions from users), turn off automatic checking and create a filter that defines exactly what HTML the application will accept.
Security Note Never disable automatic request validation without adding your own checks or filter.Note Do not create a filter that attempts to filter out only unacceptable elements, because it is difficult to anticipate every possible bad input. Instead, if you do create a filter, create one that has a defined list of acceptable input.
- To protect against SQL statement exploits, never create SQL queries using string concatenation. Instead, use a parameterized query and assign user input to parameter objects. For details, see Parameters in Data-Adapter Commands.