<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Neil Carpenter's Blog : ASP</title><link>http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx</link><description>Tags: ASP</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>SQL Injection Hijinks</title><link>http://blogs.technet.com/neilcar/archive/2008/10/31/sql-injection-hijinks.aspx</link><pubDate>Fri, 31 Oct 2008 23:07:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3145432</guid><dc:creator>neilcar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3145432.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3145432</wfw:commentRss><description>&lt;P&gt;&lt;I&gt;or Why I Keep Harping On Blacklisting&lt;/I&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Summary:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;An incident reveals attempts to get around blacklisting by manipulating behavior in ASP, illustrating the weakness of blacklist approaches.&lt;/P&gt;
&lt;P&gt;A new version of &lt;A href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx" mce_href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx"&gt;UrlScan is shipping today&lt;/A&gt; with a change specifically to address this.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Discussion:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;I was working with a colleague on an incident last week that looked like a garden-variety SQL injection drive-by except for something interesting.&lt;/P&gt;
&lt;P&gt;While looking through the IIS logs from the affected server, I saw this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;abc=120364DEC%LARE%20@S%20VAR%CHAR(4000)%3BS%ET%20@S%...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As I looked at this, "DEC%LARE", "VAR%CHAR", and "BS%ET" immediately stood out to me.&amp;nbsp; Obviously, the percent sign is usually used to escape something in a URL (like the %20's in there, which are spaces); however, this naked percent sign thrown in there didn't seem to have any purpose and should have caused SQL to not execute the code in question.&lt;/P&gt;
&lt;P&gt;When I see somebody do something like this, it's usually for a purpose so I took another look at it.&amp;nbsp; I realized that, if ASP silently stripped that percent sign out of there, then this would be an efficient way to bypass a lot of blacklist-based filters.&lt;/P&gt;
&lt;P&gt;I wrote a quick test ASP page(1) and found that my guess was right on -- ASP drops a percent sign from the query string if it isn't followed by two valid hex characters(0-9, A-F) when it actually interprets it via Request.QueryString.&amp;nbsp; This means that any filter that inspects raw headers using Request.ServerVariables is going to miss "DEC%LARE" if it is looking for "DECLARE" but, on the other hand, the ASP app that actually consumes that string using Request.QueryString("abc") is going to get it without the percent sign.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Conclusion:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;As this incident illustrates, a blacklist approach to SQL injection only works for as long as nobody finds a way around your blacklist.&amp;nbsp; As soon as somebody finds a way around it (and experience suggests that attackers are motivated to do so), the value of your blacklist is zero.&lt;/P&gt;
&lt;P&gt;The right approach is to fix the actual vulnerability in the code using parameterized queries.&amp;nbsp; See the articles below for more information and examples.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A title=http://msdn.microsoft.com/en-us/library/cc676512.aspx href="http://msdn.microsoft.com/en-us/library/cc676512.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc676512.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc676512.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A title="SQL Injection Mitigation- Using Parameterized Queries" href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx"&gt;SQL Injection Mitigation- Using Parameterized Queries&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A title="SQL Injection Mitigation- Using Parameterized Queries part 2 (types and recordsets)" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;SQL Injection Mitigation- Using Parameterized Queries part 2 (types and recordsets)&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The IIS team is releasing an update to UrlScan today that includes changes to address this in their filtering product.&amp;nbsp; Of course, as I've said over and and over, no filter-based approach is going to be perfect, but UrlScan is still an excellent defense-in-depth tool and a way to mitigate SQL injection vulns in the short term while your developers fix them.&lt;/P&gt;
&lt;P&gt;For more information on the UrlScan update, Wade Hilmo has all the details:&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx" mce_href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx"&gt;http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;(1)&lt;/P&gt;
&lt;P&gt;&amp;lt;HTML&amp;gt; &lt;BR&gt;QUERY_STRING = &amp;lt;%= Request.ServerVariables("QUERY_STRING") %&amp;gt; &amp;lt;BR&amp;gt;&amp;nbsp; &lt;BR&gt;test =&amp;lt;%= Request.QueryString("test") %&amp;gt; &amp;lt;BR&amp;gt; &lt;BR&gt;&amp;lt;/HTML&amp;gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3145432" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Tool/default.aspx">Tool</category></item><item><title>SQL Injection:  Trends &amp; Guidance</title><link>http://blogs.technet.com/neilcar/archive/2008/05/30/sql-injection-trends-guidance.aspx</link><pubDate>Fri, 30 May 2008 19:17:11 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3063668</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3063668.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3063668</wfw:commentRss><description>&lt;p&gt;I've been working with the SWI team to write a comprehensive overview of the SQL Storm attacks with guidance for IT administrators, developers, and end users.&amp;#160; That article is posted at &lt;a title="sql-injection-attack.aspx" href="http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx"&gt;sql-injection-attack.aspx&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For developers, specifically, Bala Neerumalla has written an excellent overview of SQL injection and classic ASP code for MSDN at &lt;a title="cc676512.aspx" href="http://msdn.microsoft.com/en-us/library/cc676512.aspx"&gt;cc676512.aspx&lt;/a&gt;.&amp;#160; This is well worth a read for any developer who has legacy ASP code running -- it covers a variety of scenarios and how to resolve them.&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3063668" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item><item><title>SQL Injection Mitigation: Using Parameterized Queries part 2 (types and recordsets)</title><link>http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx</link><pubDate>Fri, 23 May 2008 19:18:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3060009</guid><dc:creator>neilcar</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3060009.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3060009</wfw:commentRss><description>&lt;P&gt;(Part 1 is &lt;A href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx"&gt;here&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;Previously, I provided a simple example of using parameterized queries in classic ASP; however, that sample lacked a few things such as explicit typing for the parameters.&amp;nbsp; It also created a read-only ADODB.RecordSet which, obviously, isn't one-size-fits-all.&lt;/P&gt;
&lt;H2&gt;Typing&lt;/H2&gt;
&lt;P&gt;In the last installment, we had worked up this code to do our query:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;objCommand.Parameters(0).value = strSearch &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As I noted then, this code has a minor performance issue because ADODB is going to have to made a round-trip to SQL to figure out the parameter type before it can execute the query.&amp;nbsp; We can fix this and do input validation by explicitly typing our parameters like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;&lt;STRONG&gt;set objParameter = objCommand.CreateParameter("search", adVarChar, adParamInput, 20) &lt;BR&gt;objCommand.Parameters.Append objParameter &lt;BR&gt;obParameter.value = strSearch&lt;/STRONG&gt; &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Here, we are creating an explicit parameter with a type of adVarChar (ie, it's a string) that is an input parameter with a maximum length of 20.&amp;nbsp; We append the parameter to our ADODB.Command object and set the parameter's value to the search string we want in our command.&amp;nbsp; More info about ADODB.Parameter objects is &lt;A href="http://msdn.microsoft.com/en-us/library/ms681010(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms681010(VS.85).aspx"&gt;here&lt;/A&gt;, more info about the possible types is &lt;A href="http://msdn.microsoft.com/en-us/library/ms675318(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms675318(VS.85).aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;RecordSets&lt;/H2&gt;
&lt;P&gt;We may want to be able to write to the ADODB.RecordSet that we create; however, the code above won't work for that because it creates a recordset with the default parameters (Set objSearchResults = objCommand.Execute()).&amp;nbsp; If we want to be able to update the recordset, we have to create it with explicit parameters:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;set objParameter = objCommand.CreateParameter("search", adVarChar, adParamInput, 20) &lt;BR&gt;objCommand.Parameters.Append objParameter &lt;BR&gt;obParameter.value = strSearch &lt;BR&gt;&lt;STRONG&gt;Set objSearchResults = Server.CreateObject("ADODB.RecordSet") &lt;BR&gt;objSearchResults.Open objCommand,null,adOpenDynamic,adLockOptimistic&lt;/STRONG&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, we are explicitly providing parameters to indicate that we want a dynamic cursor (adOpenDynamic) and that we want optimistic locking (adLockOptimistic).&amp;nbsp; This creates a recordset that can be updated via the RecordSet.Update method (&lt;A title=http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx href="http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx&lt;/A&gt;).&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3060009" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item><item><title>SQL Injection Mitigation: Using Parameterized Queries</title><link>http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx</link><pubDate>Wed, 21 May 2008 16:05:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3058592</guid><dc:creator>neilcar</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3058592.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3058592</wfw:commentRss><description>&lt;P&gt;Michael Howard wrote an excellent article yesterday on &lt;A href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx" mce_href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx"&gt;how the SDL addresses SQL injection&lt;/A&gt;.&amp;nbsp; He walks through three coding requirements/defenses:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Use SQL Parameterized Queries &lt;/LI&gt;
&lt;LI&gt;Use Stored Procedures &lt;/LI&gt;
&lt;LI&gt;Use SQL Execute-only Permissions &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As Michael points out, only the first, parameterized queries, remedies the problem.&amp;nbsp; The other two provide additional defense.&lt;/P&gt;
&lt;P&gt;The good news is that changing your ASP pages to use parameterized queries instead of just dynamically building the query is dead simple.&amp;nbsp; The bad news is that MSDN doesn't have a lot of samples of how to do parameterized queries in ASP so I thought providing one would be helpful.&lt;/P&gt;
&lt;P&gt;As an example, I'm sure that a lot of the websites that have been compromised recently via SQL injection have something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSQL = "SELECT name, info FROM [companies] WHERE name =" &amp;amp; strSearch &amp;amp; "';" &lt;BR&gt;Set objSearchResults = objConnection.Execute(strSQL)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This code is going to be extremely vulnerable to SQL injection since it's just taking the user input (which was passed in via a query string from a web form) and pasting it into the SQL statement.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The good thing about parameterization is that it separates the 'executable' code ("SELECT name, info...") from the 'data' (strSearch) we're using.&amp;nbsp; With a few changes, we can make this code use parameters for the query and, with this small change, defend against being exploited in this way.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection&lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;objCommand.Parameters(0).value = strSearch &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;All that we needed to do was:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Replace the query string in our SQL squery statement with a ? (which is the placeholder for a parameter). &lt;/LI&gt;
&lt;LI&gt;Create a new Command object for our command. &lt;/LI&gt;
&lt;LI&gt;Assign our active connection and command text to the Command object. &lt;/LI&gt;
&lt;LI&gt;Set the first parameter in the parameters collection to our dynamic string. &lt;/LI&gt;
&lt;LI&gt;Execute the command. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If we needed to use multiple parameters in our query, we'd add additional question marks to strSQL and additional parameters to the Parameters collection.&amp;nbsp; For example:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "AND info = ?;" &lt;BR&gt;... &lt;BR&gt;objCommand.Parameters(0).value = strName &lt;BR&gt;objCommand.Parameters(1).value = strInfo &lt;BR&gt;...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;There is a BIG caveat on this -- the method I show above has a performance hit because I haven't specified the types of the parameters.&amp;nbsp; This means that ADO has to make a roundtrip to the SQL server to figure out the type before actually using it.&amp;nbsp; You can fix this by creating parameters objects with the appropriate type which would have the added bonus of doing simple input validation as well.&amp;nbsp; If there's interest, I'll write a followup in the next few weeks with some samples of typed, parameterized queries.&amp;nbsp; (EDIT:&amp;nbsp; Written, it's &lt;A class="" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;here&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;Additional info is available on MSDN &lt;A href="http://msdn.microsoft.com/en-us/library/ms808739.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms808739.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; NomadPete has a fuller walkthrough &lt;A href="http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/" mce_href="http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/"&gt;here&lt;/A&gt; that covers parameterized queries and stored procedures.&lt;/P&gt;
&lt;P&gt;As always, this is only part of the job in securing against SQL injection; however, it is probably the single most useful change you could make.&lt;/P&gt;
&lt;P&gt;(Big thanks to &lt;A class="" href="http://msdn.microsoft.com/en-us/magazine/cc301140.aspx" mce_href="http://msdn.microsoft.com/en-us/magazine/cc301140.aspx"&gt;Bala Neerumalla&lt;/A&gt; for tech reviewing this for me.)&lt;BR&gt;(Edit:&amp;nbsp; Fixed two minor issues with the code examples.&amp;nbsp; Thanks, Steve!)&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;Continue on to Part 2&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3058592" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item></channel></rss>