<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/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>Tales from the Evil Empire : Security</title><link>http://weblogs.asp.net/bleroy/archive/tags/Security/default.aspx</link><description>Tags: Security</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>How to choose a client template engine</title><link>http://weblogs.asp.net/bleroy/archive/2009/02/05/how-to-choose-a-client-template-engine.aspx</link><pubDate>Thu, 05 Feb 2009 08:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6884165</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6884165</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/02/05/how-to-choose-a-client-template-engine.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Water lenses, (c) 2007 Bertrand Le Roy" border="0" alt="Water lenses, (c) 2007 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/WaterLenses_40562071.jpg" width="244" height="164" /&gt; Disclaimer:&lt;/strong&gt; I worked on the &lt;a href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=AJAX"&gt;Microsoft Ajax 4.0&lt;/a&gt; template engine, so my criteria are of course heavily influenced by our own design.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Templates are a data rendering method that server-side developers have enjoyed since the old days of classic ASP and PHP. The idea was quite simple (add code blocks and dynamic expressions directly into HTML markup) but it revolutionized web development, which before that relied on the opposite method (spitting HTML from CGI code).&lt;/p&gt;  &lt;p&gt;On the client-side, the browser provides two ways to generate HTML: innerHTML and the DOM API. Template rendering is of course possible, but only using a JavaScript library. To be honest, one should mention XSLT here, which is standard and widely supported but whose somewhat unusual syntax has had limited success convincing web developers.&lt;/p&gt;  &lt;p&gt;There are literally dozens of template engines available today, using many different markup conventions and algorithms. Template engines are not equal, they have different levels of complexity, different feature sets, different security models. It can be quite hard to pick one, and it really depends on the requirements of your application and also on taste.&lt;/p&gt;  &lt;p&gt;I’ll try to go over a few things that you might want to check on a template engine. You will want to cherry-pick what’s important to you and what’s not so that you can pick the tool that’s best adapted to your problem.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. Expression delimiter&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A template system is adding new semantics to an existing language. This is not completely harmless as you have to give a new meaning to sequences of characters that were understood before as plain literals. That means that an escaping mechanism must exist to express the literal contents that were given a new meaning. For example, if the expression delimiters are &amp;lt;%= and %&amp;gt;, how do you express the “&amp;lt;%=” and “%&amp;gt;” sequences of characters as literals?&lt;/p&gt;  &lt;p&gt;&amp;lt;%= and %&amp;gt; are by far the most common and familiar delimiters (they have been used by ASP, PHP, JSP, ASP.NET and many others), but they have one flaw that couldn’t be seen back in 1996: XHTML compliance. Granted, you may not care at all about XHTML. If you don’t, just skip this. But if you do, any template engine that uses &amp;lt;%= %&amp;gt; simply can’t have template code that is XHTML-compliant. Now this may still not be a big deal if you don’t care that the template code is compliant, but only care about the generated markup.&lt;/p&gt;  &lt;p&gt;But there is another reason why &amp;lt;%= %&amp;gt; is a bad choice: it’s conflicting with the server-side. A client-side engine must be able to coexist peacefully with whatever server-side technology you’re using. If your server technology of choice is using &amp;lt;%= %&amp;gt; like it very likely does, it will be conflicting with your client templates. The server-side engine will kick in when it sees these delimiters and will fail one way or another.&lt;/p&gt;  &lt;p&gt;We chose {{ }} as the expression delimiter (and also {expr } for extensible markup expressions such as {binding }), which happens to be the same choice that Django made (and Dojo, as they implement Django on&amp;#160; the client-side, and by the way I don’t know how they manage conflict with server-side Django; if you know, drop me a comment). It works fine with XHTML and it doesn’t conflict with ASP or PHP. If you want to express the “{{“ literal, we don’t provide an escape sequence per se, but you can still do it by writing {{ “{{“ }}.&lt;/p&gt;  &lt;p&gt;On a final note, there are a few template engines that do not have expression delimiters but instead rely on microformats. While this absolutely preserves the HTML semantics, it’s often clumsier to use and quite limiting. It’s a matter of taste, but microformats also can look like markup within markup.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. Expression language&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the simplest cases, you’ll want to inject a simple data field into the template, like {{ Price }}. But many times, you’ll want to go beyond those simple cases and embed a more complex expression into the markup. For example, you might want to display that price with two decimal places, like $42.00. In order to handle that case and more complex ones, it is necessary to have a full expression language.&lt;/p&gt;  &lt;p&gt;In the same way, if the template engine allows for code blocks to introduce control structures such as conditional execution or loops, it needs a full programming language.&lt;/p&gt;  &lt;p&gt;Some template engines, such as Django, introduce their own new language. Others, such as ours, just use what’s already available and familiar: JavaScript. In addition to being familiar, it eliminates the need to write a parser and interpreter, which reduces library code size and gives better performance.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Protection against injection attacks&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you don’t know what an injection attack is… wow. Just wow. Go read &lt;a href="http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx"&gt;this&lt;/a&gt;, now. Seriously.     &lt;br /&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The frightening thing about almost any single one of the client template engines out there is that they have no mechanism in place to protect against injection attacks, which puts the responsibility to encode and check contents in the hands of the application developer. That’s you.&lt;/p&gt;  &lt;p&gt;Most of the engines out there are using a very simple algorithm to build HTML: array joining, and then injecting the result using innerHTML. This is very similar to building SQL by concatenating strings: in a nutshell, you shouldn’t do that. In the same way that SQL is better built using parameterized queries, HTML is more securely built using the DOM API which just eliminates the need for encoding.&lt;/p&gt;  &lt;p&gt;Even when using encoding or the DOM API, there is a number of attributes that still present a fair amount of danger if user data gets injected in them. For example, if you bind the href attribute of a link to a piece of user data, no amount of encoding will protect the application against a user injecting “javascript:doSomeEvil();”.&lt;/p&gt;  &lt;p&gt;To prevent that kind of attack, we white-list the protocols in all known URL attributes to relative URLs, http and https. It is possible for the application to extend this white list as needed (available in Microsoft Ajax 4.0 Preview 4 and later).&lt;/p&gt;  &lt;p&gt;One thing to understand is that the dangerous contents here is the &lt;em&gt;data&lt;/em&gt;, not the template itself, which is trusted as application code is.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. Template location&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Depending on the library, the template can be embedded in comments, in script tags or just be part of the DOM. It can also be included from a separate file.&lt;/p&gt;  &lt;p&gt;Putting the template in comments or script tags easily hides its markup from initial rendering, but it makes it harder to design with existing tools and puts it out of the reach of markup validation tools.&lt;/p&gt;  &lt;p&gt;Including from a separate file adds one more request to the server, which might be a problem or not: it might also improve performance by allowing partial caching. The best is to have a choice here, so I’d reject an engine where external files is the only possibility, knowing that all other engines allow external files with minimal effort by feeding a simple XHR’s result into the system.&lt;/p&gt;  &lt;p&gt;Instead of using script tags or comments, we chose to embed the template as real HTML contents anywhere in the document and just hide it from initial rendering using CSS. This makes the code designable using any existing tool, and enables us to use the browser’s native HTML parser to understand the structure of the markup.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;5. Hooking up events and instantiating components&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In a modern Web application, you won’t just create plain HTML, you’ll want to hook up events and instantiate components. The template engine might let you do this inline, which is obtrusive but convenient, or it might require you to enrich the DOM after template instantiation through code, or it might give you a choice between the two.&lt;/p&gt;  &lt;p&gt;One thing to look for is how much knowledge of the template markup’s shape must be injected into the code in order to enrich the DOM.&lt;/p&gt;  &lt;p&gt;For a picture of the different possibilities using our engine, read this post:    &lt;br /&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2008/11/28/instantiating-components-on-template-markup.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2008/11/28/instantiating-components-on-template-markup.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;6. Live bindings&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One big advantage of client rendering is that the data remains under raw data form until it reaches the template engine. That means that you have a representation of the data on the client. This in turn means there is an opportunity to monitor changes to the data and to bind UI directly to it, eliminating round-trips to the server along the way.&lt;/p&gt;  &lt;p&gt;We call this ability live bindings and it makes for very responsive applications that are still easy to build.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;7. Constraints on markup shape&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One thing you should try with any template engine is to repeat a row in a table, using IE. This may sound trivial, but innerHTML doesn’t work on IE in a number of places, which puts a constraint on the markup that you need to write to render certain shapes of HTML. There is almost always a workaround but it can be more or less painful to implement. Try and compare, see what you find reasonable.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;8. Ease of data field access&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This one is quite simple. Some template engines force you to access the current data item’s field through some special syntax such as “$T.price”. In our engine and several others, you just write “price”.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;9. Readability&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This one is quite subjective, but when choosing a template engine, just look at a few samples. Does the code hurt your eyes? Can you understand it right away?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;10. Performance&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A template engine must be able to render a reasonable number of data items with a reasonably complex template under the perception threshold. What’s “reasonable” pretty much depends on your application design, but I’d say a hundred items in a typical grid layout should be hardly noticeable. So before you choose, do a mock-up of your design and data and try it. Increase the number of items and see where rendering starts to get noticeable. Usually rendering performance is not linear so this should give you a good idea of how far you can go with each engine. Better to determine that before you invest heavily in one engine.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;11. XHTML compliance&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As I said above, this is one you might not care about. Don’t leave yet, it actually goes both ways, as an engine, by enforcing XHTML compliance, might potentially get in the way of writing HTML the way you want.&lt;/p&gt;  &lt;p&gt;The lowest level of compliance is that the rendered output is compliant. Being template engines, most if not all engines enable you to create compliant or horribly broken markup, depending on your own style. What it must absolutely not do is &lt;em&gt;prevent&lt;/em&gt; you from generating compliant markup.&lt;/p&gt;  &lt;p&gt;The second level of compliance is that the template code itself, before data is injected, is compliant. This is much less common. Even less common is that the compliance requirement does not impose too strong a constraint on the markup you have to write.&lt;/p&gt;  &lt;p&gt;In other words, a good template engine lets you write XHTML but doesn’t force you to.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;12. Nested templates&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Rendering a template within a template might look like a whacky scenario at first if the engine understands control structures such as loops. In reality, if you include something like live bindings into the mix, you will want for example an inner template to be re-drawn when the outer data item changes. This will be much easier to achieve with nested templates.&lt;/p&gt;  &lt;p&gt;So if this is a scenario that you care about, make sure that your engine handles that case gracefully.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In conclusion&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There are many engines to choose from, and many criteria to check. I’m quite convinced that &lt;a href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=AJAX"&gt;our own offering is pretty solid&lt;/a&gt; for all these criteria and offers a good compromise of features against simplicity and performance.&lt;/p&gt;  &lt;p&gt;There is another engine that I quite like because it’s an impressively small bit of code that remains useful, and that is John Resig’s micro-template engine, which is only 20 lines of code. Like our own engine, it “compiles” the template into a reusable function that takes the data as a parameter. But unlike ours, it has no security mechanism and has issues with some markup, which may or may not be an issue for you. It’s a different kind of compromise that puts code size and simplicity before any other consideration.&lt;/p&gt;  &lt;p&gt;I hope this helps in making a choice.&lt;/p&gt;  &lt;p&gt;A good resource on client templates:    &lt;br /&gt;&lt;a href="http://ajaxpatterns.org/Browser-Side_Templating"&gt;http://ajaxpatterns.org/Browser-Side_Templating&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;John Resig’s micro-templates:    &lt;br /&gt;&lt;a href="http://ejohn.org/blog/javascript-micro-templating/"&gt;http://ejohn.org/blog/javascript-micro-templating/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;ASP.NET 4.0 Ajax Preview 3:    &lt;br /&gt;&lt;a title="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=AJAX" href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=AJAX"&gt;http://www.codeplex.com/aspnet/Wiki/View.aspx?title=AJAX&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;added performance and XHTML compliance to the list from Dave Reed’s feedback, and nested templates from Keith’s.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6884165" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Security/default.aspx">Security</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Injection/default.aspx">Injection</category></item><item><title>New tools to prevent SQL injection attacks</title><link>http://weblogs.asp.net/bleroy/archive/2008/06/25/new-tools-to-prevent-sql-injection-attacks.aspx</link><pubDate>Wed, 25 Jun 2008 17:00:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6319353</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6319353</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2008/06/25/new-tools-to-prevent-sql-injection-attacks.aspx#comments</comments><description>&lt;P&gt;I've &lt;A class="" href="http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx" mce_href="http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx"&gt;blogged in the past about injection attacks&lt;/A&gt;. Microsoft publishes additional new tools to detect and protect against injection attacks. The first tool, developed by HP, crawls web sites to automatically detect possible attacks, the second blocks dangerous requests from being executed, and the last one analyzes code to look for dangerous practice.&lt;/P&gt;
&lt;P&gt;&lt;A title=http://www.microsoft.com/technet/security/advisory/954462.mspx href="http://www.microsoft.com/technet/security/advisory/954462.mspx" mce_href="http://www.microsoft.com/technet/security/advisory/954462.mspx"&gt;http://www.microsoft.com/technet/security/advisory/954462.mspx&lt;/A&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6319353" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/IIS/default.aspx">IIS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Security/default.aspx">Security</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Injection/default.aspx">Injection</category></item><item><title>Please, please, please, learn about injection attacks!</title><link>http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx</link><pubDate>Thu, 19 Aug 2004 00:37:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:216861</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>48</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=216861</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2004/08/18/please-please-please-learn-about-injection-attacks.aspx#comments</comments><description>&lt;DIV&gt;I answer a lot of posts on the forums of the &lt;A title="" target=_blank href="http://www.asp.net/" mce_href="http://www.asp.net"&gt;ASP.NET&lt;/A&gt; site. And more often than I would like to, I answer a different question than the one the poster asked, because I happened to easily spot a potential injection attack in the posted code.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Now, what is an injection attack? If you don't know and you're a web developer, you're in trouble. Read on.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;There are mainly two types of injection attacks, but both use the same vector of penetration: unvalidated user input.&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Rule #1: User input is EVIL&lt;/STRONG&gt; (pronounced eyveel, like the doctor of the same name) and should never be trusted. &lt;STRONG&gt;Validate all user input&lt;/STRONG&gt;.&amp;nbsp;In the case of a web application, user input is form fields, headers, cookies, query strings, or any thing that was input or sent&amp;nbsp;by users (that may include some database data, or other sometimes&amp;nbsp;more exotic input like mail or ftp).&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The first type of injection attack, and the most deadly for most web sites are SQL Injection Attacks. It happens most of the time when the developer injects user input into a SQL query using string concatenation. For example:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008080 size=1 face="Courier New"&gt;&lt;BR&gt;SqlCommand&lt;FONT color=black&gt; cmd = &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;SqlCommand&lt;/FONT&gt;&lt;FONT color=black&gt;(&lt;BR&gt;&amp;nbsp; "SELECT ID, FullName FROM User WHERE Login='"&lt;BR&gt;&amp;nbsp; + &lt;/FONT&gt;&lt;FONT color=#008080&gt;Login&lt;/FONT&gt;&lt;FONT color=black&gt;.Text&lt;BR&gt;&amp;nbsp; + "' AND Password='" &lt;BR&gt;&amp;nbsp; + &lt;/FONT&gt;&lt;FONT color=#008080&gt;Password&lt;/FONT&gt;&lt;FONT color=black&gt;.Text &lt;BR&gt;&amp;nbsp; + "'");&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;This is C#, but I'm sure our VB programmer friends will get the idea (+ means &amp;amp;). This code is simply frightening, but I've seen it or a variation on it so often I just can't count. OK, why is it frigtening? Well, try to enter these strings into the login and password&amp;nbsp;textboxes:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=1 face="Courier New"&gt;' OR ''='&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;There, you're authenticated! What happens is simple. Instead of being the simple text that you expected, the user input some evil text that contains the string delimiter and some SQL code that you're very generously executing.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Of course, this is not the worse that could happen. Any SQL command could be executed, especially if you've been careless enough not to restrict the rights of the &lt;A title="" target=_blank href="http://www.asp.net/" mce_href="http://www.asp.net"&gt;ASP.NET&lt;/A&gt; user on your database. For example, the user could very well steal all the information in your database, completely obliterate it or even take complete control of the server. This leads us to rule #2, our fisrt counter measure:&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Rule #2: Secure your database&lt;/STRONG&gt;: don't use the sa user to connect to the database from your application, have a strong password on the sa user (and on any user), preferably use integrated authentication to keep all secrets out of your connection string and config file, and restrict the authorizations on your database objects to what's absolutely necessary (don't give writing rights to internet users except on log tables or forum tables, for example). This way, even if you accidentally write injectable code, the database will refuse to execute anything harmful beyond information disclosure (which could still be pretty bad). Please note that the above injection example&amp;nbsp;will still work even if the database is secured.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;So it may seem at first that the quotes are the usual suspects in this case. Actually, if you use this kind of code, you may have noticed a few glitches for example if people have legitimate quotes in their names. So what many people have been doing for a long time is to double the quotes in the input strings, something like &lt;FONT size=2 face="Courier New"&gt;Login.Text.Replace("'", "''")&lt;/FONT&gt;, or replace them with another harmless character (you can recognize these sites usually because they use the ` character instead of quotes). This gives &lt;EM&gt;a false sense of security&lt;/EM&gt;, which is sometimes worse than no security at all. Consider this request:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=1&gt;&lt;FONT face="Courier New"&gt;&lt;BR&gt;"SELECT FullName FROM User WHERE ID=" + &lt;FONT color=#008080&gt;Identity&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=black size=1 face="Courier New"&gt;.Text&lt;BR&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Here, no need for quotes to inject code, all you need is space and letters. Enter &lt;FONT size=2 face="Courier New"&gt;0 DELETE * FROM&amp;nbsp;User&lt;/FONT&gt; into the textbox, and there goes your User table. And I'm sure a hacker creative enough could come up with wicked injections that don't even need spaces. Escape sequences in particular&amp;nbsp;are a usual&amp;nbsp;way to pass characters that were thought to be invalid&amp;nbsp;in many applications (including, yes, &lt;A title="" target=_blank href="http://www.microsoft.com/" mce_href="http://www.microsoft.com"&gt;Microsoft&lt;/A&gt; products whose name have two letters,&amp;nbsp;begin with I and end with E).&amp;nbsp;This leads us to the third rule:&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Rule #3: Black lists are always incomplete&lt;/STRONG&gt; (because hackers are many and potentially smarter than you). If you have to, rely on white lists, but never black lists.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;A black list is a list of all characters you consider evil (like the quote). There will always be something missing in it. Consider this as a fact (even though of course it &lt;EM&gt;can&lt;/EM&gt; be complete, but you should act as if this was not the case).&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;A white list is a list of authorized characters. What's great about it is that you know precisely what's permitted (what's in the list) and what's is forbidden (everything else). In the last example, restricting &lt;FONT size=2 face="Courier New"&gt;ID.Text&lt;/FONT&gt; to numeric characters is enough to secure the request.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;And now for the good news. While it is useful to know all this about SQL Injections, the .NET framework (and all modern development frameworks, like Java) provide an excellent way to prevent injections: parametrized queries. Parametrized queries are safer, cleaner and make your code easier to read. Here are the two previous examples, rewritten as parametrized queries:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=1&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;FONT size=1&gt; cmd = &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;new&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=1&gt;("SELECT ID, FullName FROM User WHERE Login=@Login AND Password=@Password");&lt;BR&gt;cmd.Parameters.Add("@Login", &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlDbType&lt;/FONT&gt;&lt;FONT size=1&gt;.NVarChar, 50).Value = &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;Login&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=1&gt;.Text;&lt;BR&gt;cmd.Parameters.Add("@Password", &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlDbType&lt;/FONT&gt;&lt;FONT size=1&gt;.NVarChar, 50).Value = Password.Text;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;FONT size=1&gt; cmd = &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;new&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=1&gt;("SELECT FullName FROM User WHERE ID=@ID");&lt;BR&gt;cmd.Parameters.Add("@ID", &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlDbType&lt;/FONT&gt;&lt;FONT size=1&gt;.Int).Value = &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;int&lt;/FONT&gt;&lt;FONT size=1&gt;.Parse(Identity.Text);&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;This way, there is no need to escape any characters because the parameter values are directly communicated in a strongly typed manner to the database.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;N.B. In the second example, you may also want to use validator controls on the Identity TextBox, and check the validity of the page server-side before you build and execute the SQL query using Page.IsValid.&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Rule #4:&amp;nbsp;Use parametrized queries whenever possible.&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Whenever possible? Does that mean that it's not always possible? Well, here's &lt;A href="http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&amp;amp;PostID=660447#670652" mce_href="http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&amp;amp;PostID=660447#670652"&gt;a little problem&lt;/A&gt; I got from the &lt;A title="" target=_blank href="http://www.asp.net/" mce_href="http://www.asp.net"&gt;ASP.NET&lt;/A&gt; forums: you have a list of checkboxes on a page that have numeric identifiers as their values. Let's say that you must extract all the database rows that have the checked values. You'd want to write something like that (pseudo-code here):&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=1&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;FONT size=1&gt; cmd = &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;new&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=1&gt;("SELECT FullName FROM User WHERE ID IN(@IdArray)");&lt;BR&gt;cmd.Parameters.Add("@IdArray", &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlDbType&lt;/FONT&gt;&lt;FONT size=1&gt;.IntArray).Value = &lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;Convert&lt;/FONT&gt;&lt;FONT size=1&gt;.ChangeType(Request.Form["Identities"], &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;typeof&lt;/FONT&gt;&lt;FONT size=1&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;int&lt;/FONT&gt;&lt;FONT size=1&gt;[]));&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;Unfortunately, there is no such thing as an array type for Sql. So in this case, unfortunately, unless someone comes up with something better, you have to rely on concatenation:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=1&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=1&gt;&lt;FONT size=1&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;FONT color=#0000ff size=1&gt;string&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;idList = Request.Form["Identities"];&lt;/FONT&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;if&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;(IntListValidate(idList)) {&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#000000&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;FONT size=1&gt; cmd = &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;new&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;SqlCommand&lt;/FONT&gt;&lt;FONT color=#000000 size=1&gt;("SELECT FullName FROM User WHERE ID IN(" +&amp;nbsp;idList + ")");&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;else&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;{&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;throw&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;new&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#000000 size=1&gt;InvalidDataException&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT color=#000000&gt;("The posted data contains illegal characters.");&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;}&lt;BR&gt;...&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;private&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;bool&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;IntListValidate(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;string&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;input) {&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;&lt;FONT color=#008080&gt;&amp;nbsp; &lt;/FONT&gt;for&lt;/FONT&gt;&lt;FONT size=1&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;int&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;i = 0; i &amp;lt; input.Length; i++) {&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;if&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;FONT color=#000000&gt;(!&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=1&gt;Char&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT color=#000000&gt;.IsDigit(input, i) &amp;amp;&amp;amp; input[i] != ',')&lt;/FONT&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;return&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;false&lt;/FONT&gt;&lt;FONT size=1&gt;;&lt;BR&gt;&lt;FONT color=#000000&gt;&amp;nbsp; }&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;return&lt;/FONT&gt;&lt;FONT size=1&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=1&gt;true&lt;/FONT&gt;&lt;FONT size=1&gt;;&lt;BR&gt;&lt;FONT color=#000000&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT size=1&gt;&lt;/FONT&gt; 
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;Of course, here, you have to use a white&amp;nbsp;list, digits and comma in this case. Not even space is allowed. That's pretty safe, but I wish you could do that with parameters.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#a52a2a&gt;Update 8/19/2004:&lt;/FONT&gt;&lt;/STRONG&gt; Kyle Heon just pointed me to &lt;A href="http://msdn.microsoft.com/en-us/library/aa496058.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa496058.aspx"&gt;this great Sql article&lt;/A&gt;&amp;nbsp;that explains just how to do that with a parameter. Thanks for the link, Kyle! So now, there's one less reason not to use parameters everywhere.&lt;BR&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/aa496058.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa496058.aspx&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The second common type of injection attack is Cross-Site Scripting, or X-Site Scripting. Consider this simple piece of asp page:&lt;/P&gt;&lt;FONT size=1&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Bonjour, &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;&amp;lt;%=&lt;/SPAN&gt;&amp;nbsp;Request.Form("Name") &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;%&amp;gt;&lt;/SPAN&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;What if the user enters &lt;FONT size=2 face="Courier New"&gt;&amp;lt;script&amp;gt;alert("5tUp1dH4k3R ownz you");&amp;lt;/script&amp;gt;&lt;/FONT&gt; in the Name form field? Well, he successfully displayed an alert on his browser using your page. Nothing to be afraid about for the moment, as he'll be the only one to see it. But what if instead of directly displaying the user input we store it in a database for other users to see, in a forum application, for example? What if the parameter is passed in the querystring parameters of a hyperlink in a mail that &lt;EM&gt;seems&lt;/EM&gt; to come from your bank?&lt;/P&gt;
&lt;P&gt;Well, then a lot of nasty things can happen (by the way, these are real scenarios, stuff that happened and continues to happen every day). For example, the attacker can inject script that will post all your cookies or some confidential information that's displayed on the page to some remote site that he owns. This can include your social security number, your authentication cookies, your credit card number, or any sensitive information that may be displayed on the page.&lt;/P&gt;
&lt;P&gt;It is usually relatively harmless for many sites because they just don't have any information that's confidential or that&amp;nbsp;could allow for other, more dangerous attacks.&lt;/P&gt;
&lt;P&gt;Once again, &lt;A title="" target=_blank href="http://www.asp.net/" mce_href="http://www.asp.net"&gt;ASP.NET&lt;/A&gt; gives a first line of defense out of the box. Since v1.1, all form and querystring data is validated on the server before the page is executed. So the above example does not work on &lt;A title="" target=_blank href="http://www.asp.net/" mce_href="http://www.asp.net"&gt;ASP.NET&lt;/A&gt; 1.1, it will just throw an exception. Now, this feature is sometimes deactivated by controls such as rich text editors.&lt;/P&gt;
&lt;P&gt;The second thing we're doing, which is what you should do in your own pages and controls, is to HtmlEncode any property that comes from user input. That includes the value of an input tag that's rendered from a TextBox. It protects this particular textbox from script injections and also makes it robust against legitimate characters in the contents, such as quotes.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule #5: Encode all rendered properties that come from user input when rendering them.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The above example would then become:&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1 face="Courier New"&gt;Bonjour, &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;&amp;lt;%=&lt;/SPAN&gt;&amp;nbsp;Server.HtmlEncode(Request.Form("Name")) &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;%&amp;gt;&lt;/SPAN&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;There's another often overlooked rule:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule #6: Don't display any secrets in error messages.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;ASP.NET limits by default the complete error messages to calls from the local machine. A complete error message sent to any machine can reveal table names or other secrets that could give clues for some attacker to use. And usually, an error message gives an indication as to how to make this application fail, which can be repeated and improved on the basis of all the information the error message contains.&lt;/P&gt;
&lt;P&gt;And of course, probably the most important rule:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule #7: Encrypt any page that contains sensitive data.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Of course, these rules are all important and the order in which they are presented here is irrelevant. Did I forget something?&lt;/P&gt;
&lt;P&gt;If you need more information, here's some more reading:&lt;/P&gt;
&lt;P&gt;On Sql Injections: &lt;A href="http://www.governmentsecurity.org/articles/SQLInjectionModesofAttackDefenceandWhyItMatters.php" mce_href="http://www.governmentsecurity.org/articles/SQLInjectionModesofAttackDefenceandWhyItMatters.php"&gt;http://www.governmentsecurity.org/articles/SQLInjectionModesofAttackDefenceandWhyItMatters.php&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;On Cross-Site Scripting: &lt;A href="http://www.net-security.org/dl/articles/xss_anatomy.pdf" mce_href="http://www.net-security.org/dl/articles/xss_anatomy.pdf"&gt;http://www.net-security.org/dl/articles/xss_anatomy.pdf&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;And of course, Google is your friend.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE: &lt;/STRONG&gt;I've used the word "quote" in this article for both the apostrophe (or single quote) and double quote. Todd pointed out in the comments that was somehow ambiguous. The point is that anything that can be used as a string delimiter, or as a delimiter in general, should be considered suspicious. Double-quotes are more frequent, but some languages such as JavaScript use both single and double quotes. SQL uses single quotes. Bottom line: beware of delimiters, and remember you may not even know the list of possible delimiters.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; we just released new tools that aim at helping developers scan their code for potential injection attacks.&lt;BR&gt;&lt;A href="http://www.microsoft.com/technet/security/advisory/954462.mspx"&gt;http://www.microsoft.com/technet/security/advisory/954462.mspx&lt;/A&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=216861" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/PHP/default.aspx">PHP</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/SQL/default.aspx">SQL</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Security/default.aspx">Security</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Injection/default.aspx">Injection</category></item></channel></rss>