Escape!

What do you think the most common mistake when writing ASPs is? (Apart from not using Option Explicit). Anyone?

Consider this snippet of code

	<%
		variable = rstSomething.Fields("whatever").Value
	%>
	<h1><%=variable%></h1>
Do you see the mistake? Or does that look exactly like your own code?!?

What happens if the value contains a les-then-sign? Heh? Do you see now what did you forget? This is something people tend to forget. They keep blindly inserting whatever values they get into CODE. Yes code, keep in mind that even plain HTML is a code. It has a certain format, some characters have a specific meaning, ... Even if it's not really executed you have to be careful before you insert anything into it.

You have to be double careful because of one thing. HTML may contain some JavaScript or VBScript, and that WILL be executed. So if you go and insert some text entered by someone into the page you generate, you are opening a security hole. Some part of the entered text can get executed.

Consider for example that you have created a guestbook. Anyone can come, write a few sentences and have them stored in a database. Then next time as someone else comes to the guestbook and wants to see the remarks you blindly insert the texts from the database into the generated HTML and ... BOOOOOOOM. What if someone entered this:

	Hi there.
	<script>while(1) {};</script>
or this
	Hi there.
	<script>while(1) {window.open()};</script>

If you used <%=Server.HTMLEncode(variable)%> you'd be safe.

Server.HTMLEncode() is not enough

Now consider this:

	<%
		variable = rstSomething.Fields("whatever").Value
	%>
	<input type=text name="whatever" value="<%=variable%>">

What happens if the variable contains a doublequote? Well again ... you have a problem. If you are lucky than you only loose part of the value. If you are not ... BOOOOOOM:

	This'll be a value" onFocus="while (1) {}"
You see? Here you are inserting the value into a different place in HTML, into a different context. So you have to escape it differently. You have to take care of the double quotes as well:
	<%
		variable = rstSomething.Fields("whatever").Value
	%>
	<input type=text name="whatever" value="<%=Replace(Replace(Server.HTMLEncode(variable),"""", "&dblquote;" ), "'", "&apm;#39;")%>">

Even that's not enough

There is still one more context in HTML, the JavaScript code. There you have to escape the value even more. Consider this.

	<%
		variable = rstSomething.Fields("whatever").Value
	%>
	<a href="JavaScript:doSomething( '<%=variable%>')">

What happens if the variable contains a singlequote? Well, you got an error when you click on that link. The problem is that the single quote in variable WILL be escaped as &#39;. But that'll only ensure it's not special for HTML. The JavaScript/JScript engine will get it converted back to literal singlequote. So the code it'll try to execute will be

 doSomething( 'O'Brien')
You would not expect that to work, would you?

So for JavaScript you have to prepend a backslash to all singlequotes as well to be safe.

What about SQL

SQL is the same beast ... and can actually be even more vital. You do not want anyone to run whatever SQL commands he wishes against your database, do you? ;-)

While it's always better to use placeholders or stored procedures sometimes it's easier to construct a SQL query in a string and then have it executed. You have to be careful before you insert a variable into the string of course. If the variable is supposed to be a number, DO test whether it really is. If it's supposed to be a string, double whatever singlequotes that are included :

	<%
		sql = "SELECT * FROM Users WHERE UserName = '" & Replace( UserName, "'", "''") & "'"
		...
	>

	<%
		if IsNumeric(UserId) then
			sql = "SELECT * FROM Users WHERE UserId = " & UserId
			...
		else
			ReportError "User Id is not numeric!"
			Response.End
		end if
	>

It's always better to spend a few processor cycles testing and escaping then to leave a security hole open and your data in danger.

Escape.inc

Here you will find an include I use to escape the values.