Tip 2Determine What Is Valid InputUsing regular expressions in VBScript, Jscript, and Perl you can define rules for which user input is valid. Do not parse out invalid input because an attacker will find a way around your checks. For example, imagine you look for "<" and ">" symbols to prevent attempts to post HTML data to your site:
strInput = strInput.replace(/[<>]/,"");
This little code snippet replaces "<" and ">" with empty strings. So when an attacker posts some HTML it gets neutered and rendered ineffective, right?
Nope! All an attacker needs to do is replace the "<" and ">" with the HTML tags for those symbols and your parsing code no longer catches the HTML. The lesson here is to determine what is legal, verify that input is legal, and toss out everything else. To this end, add the following line just before the try{} body in the
isPasswordOK() function:
if (strName.search(/[^A-Za-z 0-9]/) != -1) return false;
This code will search strName and if it contains anything other than uppercase letters, lowercase letters, whitespace , or numbers (that's what the ^ means), then the input is rejected.
Watch out for bogus filenames too. Attackers will try to post data to funny locations, or request filenames that may return source code and so on. The following regular expression allows only a highly restrictive filename. The rules for the name are:
- One or more 0-9a-zA-Z or _ followed by
- One or more 0-9a-zA-Z, -, \, / and _ followed by
- A period followed by
- '', 'txt', 'jpg', 'jpeg', 'gif', 'htm', 'html',
'png', 'bmp', 'zip'
Everything else is invalid. It's not perfect and it's strict, but it works. You'll notice that the filename cannot start with a back slash because this is the root of the disk drive. Why would anyoneother than an attackerwant to start from the root of your drive? Every attempt at file access should be relative to the root location of the Web site:
var strInput = Request.form("filename");
var re = /^[\w]{1,}[\w\-\/\\]{1,}\.(txt|jpg|jpeg|gif|htm|html|png|bmp|zip)
{0,1}$/i;
var fIsFilenameValid = (re.test(strInput)) ? true : false;