Script Exploits Overview
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 <b> and <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. If an application 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 <script> block and executes it.
There are other ways that malicious users can exploit script. Most script exploits require the application to accept the malicious input and inject it (or 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, running native code on the user's computer.
For information about preventing script exploits, see How to: Protect Against Script Exploits in a Web Application by Applying HTML Encoding to Strings.
ASP.NET helps protect against script exploits that are disguised as URLs by checking for potentially dangerous strings, such as "<!", "</", and "<?".
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.
The primary defense against scripting exploits is to 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 that 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 help protect against scripting exploits:
ASP.NET performs request validation against query-string and form variables as well as cookie values. By default, if the current Request contains HTML-encoded elements or certain HTML characters (such as — for an em dash), the ASP.NET page framework raises an error.
If you want to display strings in your application but do not trust them, apply HTML encoding to them when the strings are written back in a response. For example, with encoding, the tag <b> becomes <b>. You might do this if the strings that you are displaying are from a database whose contents you are not sure that you can trust.
If you want your application to accept some HTML (for example, some formatting instructions from users), you should encode the HTML at the client before it is submitted to the server. For more information, see How to: Protect Against Script Exploits in a Web Application by Applying HTML Encoding to Strings.
To help protect against SQL statement exploits, never create SQL queries using string concatenation. Instead, use a parameterized query and assign user input to parameter objects.
Always validate form input against a set of expected values and string formatting/type validation. For example, if a specific form variable is expected to be an integer, use the Int32..::.TryParse method to verify that the value really is an integer and use range checking to help ensure that the value is within an acceptable range.