Avoid ASP/IIS security errors without reducing security

If you work with ASP.NET web apps, and you’re creating input fields that may contain html (like the one I’m typing on right now),you may receive the following error when submitting anything with an angle bracket followed by a letter, such as <a

A potentially dangerous Request.Form value was detected from the client…

Thank you, Microsoft, for saving me from this potential hack! Now, you can simply turn off the security settings, which is explained quite well in this article. However, that leaves you open to all sorts of potential injection attacks, plus it’s against the rules for a lot of sites. You can’t do any string replacements in your code-behind, because this error fires off before any page events have occurred. So my trick is to use jQuery to capture the text before it gets sent to the server, convert any nasty symbols to something safe, then reverse the conversion when the content is displayed.

Just include jquery, add this script anywhere and baddaboom! No more errors.

jQuery(document).ready(function() {

$(“input[type=’text’],textarea”).each(function() {
var str = $(this).val();
$(this).val(convertOutput(str));
});

// make inputs safe
$(“input[type=’submit’],button”).click(function(event) {
$(“input[type=’text’], textarea”).each(function() {
var str = $(this).val();
$(this).val(convertInput(str));
});
});
});

function convertInput(str) {
str = str.replace(/</g, “{{LEFTBRACKET}}”);
str = str.replace(/>/g, “{{RIGHTBRACKET}}”);
return str;
}
function convertOutput(str) {
str = str.replace(/{{LEFTBRACKET}}/g, “<“);
str = str.replace(/{{RIGHTBRACKET}}/g, “>”);
return str;
}

Why not use the built in encode/decode functions?
The thing I hate about using html entities is the fact that the ampersand is used within the symbol it represents! When building custom CMS’s and dealing with outputting text to textareas as well as html blocks, you inevitably trip yourself up if you happen to call encode or decode one too many times, ending up with symbols like this:

&&&lt;

By using a unique string like {{LEFTBRACKET}}, and limiting string replacement to the angle brackets, I find this solution to be a lot more sturdy. If you have a problem with quotes or backslashes, just add them into the conversion functions one at a time.

This entry was posted in uncategorized. Bookmark the permalink.

4 Responses to Avoid ASP/IIS security errors without reducing security

  1. John Pencola says:

    Good topic, definitely try to restrict & sanitize your input on the client as best you can before handing it off to the server and letting it do the heavy lifting. But always keep in mind that JavaScript can be a false sense of security! What happens when I disable JavaScript in the browser, visit the page in question and inject scripts into the input field? In this case it would either fail with the .NET error or allow me to post malicious data to the server ;) In the article you referenced it appears you can just use .NET’s ‘HttpUtility.HtmlEncode’ correct? Couldn’t you just turn off the default security setting on a page-by-page basis and have your submit handler (presumably in the code-behind) do something along the lines of: HttpUtility.HtmlEncode(myInputField.Text));
    prior to writing the response?
    Also, for those that don’t want to use jQuery but want a JavaScript equivalent ( there’s a million ways to skin it but… ) it’s pretty clean to just use the good ‘ol encodeURIComponent() method. Keep up the good work man! Looking forward to more posts.

  2. mindstor says:

    Excellent points. If you disable javascript, the IIS bouncers will not let your shady angled brackets through the door, so you will get a 500 server error, but it does not compromise the security of the site.

    As for turning off security for that page, it can be done (even though it’s not allowed in my environment), but that puts you on the defensive, trying to catch every potential hack. This way, if there’s something I’ve overlooked, it will only cause a user error, which is preferred to a security violation.

    As for developers who like javascript but hate jQuery (namely, Santa Claus and the Tooth Fairy), they can surely accomplish the same thing with just a few more lines of code.

  3. John Pencola says:

    “…so you will get a 500 server error, but it does not compromise the security of the site.”
    Exactly! So, presuming you can leave the security settings on and do your HtmlEncode/Decode in the code-behind on the submit handler then you get the best of both worlds. Also, since the logic is simple and isolated, you shouldn’t have to worry about multiple calls to encode. You can still sprinkle on some client side validation via JavaScript but if its disabled, the user doesn’t have the app blow up on them. If you can have it work both ways (with minimal effort in this case) isn’t that preferred and what progressive enhancement is all about?

    “As for developers who like javascript but hate jQuery”
    Just to clarify, I have nothing against jQuery, In fact I used to work with it often back in the “whats jQuery??” days. I was just offering an example of how to do en/decoding without all the sugar.

  4. Good topic, definitely try to restrict & sanitize your input on the client as best you can before handing it off to the server and letting it do the heavy lifting. But always keep in mind that JavaScript can be a false sense of security! What happens when I disable JavaScript in the browser, visit the page in question and inject scripts into the input field? In this case it would either fail with the .NET error or allow me to post malicious data to the server In the article you referenced it appears you can just use .NET’s ‘HttpUtility.HtmlEncode’ correct? Couldn’t you just turn off the default security setting on a page-by-page basis and have your submit handler (presumably in the code-behind) do something along the lines of: HttpUtility.HtmlEncode(myInputField.Text));prior to writing the response? Also, for those that don’t want to use jQuery but want a JavaScript equivalent ( there’s a million ways to skin it but… ) it’s pretty clean to just use the good ‘ol encodeURIComponent() method. Keep up the good work man! Looking forward to more posts.
    +1