<% '******************************************************************************* ' VALIDATE CLASS ' Author: Jason Beaudoin ' ColdFire Designs ' http://www.coldfiredesigns.com ' ' Date: 19 October 2011 ' Description: Checks the contents of a variable to ensure that it passes various validation parameters. ' Requires: errorClass.asp ' Returns: the var itself or NULL if it fails validation, or as an option, it can return a boolean parameter. ' Features: ' . Validates every single character based on a parameter that you set (like 'alphanum', 'number', 'date', etc); ' . Validates against illegal words (like 'script', 'update', 'delete', etc); ' . Checks the length (if you set it to be no larger than 10 then a string of 11 length would trigger a fail); ' . Detects and decodes hexadecimally encoded strings and launders them just the same; ' . By default, if the validation fails for any reason, the variable is dumped and set to NULL; ' . Error trapping and storing to find out where your variable is failing (useful for debugging purposes); ' Options: ' . Return boolean (turned off by default): returns true or false as the return value; ' . Return error: on error, it will return the error message as the return value; ' . Allow nulls: if true, it will not generate errors if a null value is passed to this validator class; ' . Trim Input: trim the input (delete the spaces on the left and right) before validating; ' METHODS ' . Validate ' . validates a variable to ensure that it's reasonably safe to send to the database. ' Requires: ' . input (string): the string that you want to validate; ' . dataType (string): must be 'name', 'email', 'password', 'number', 'session' or 'desc'; ' . length (string or integer): a number representing the length of the input string to validate; ' PROPERTIES ' Read/Write ' . ReturnBool (boolean) ' . Determines if you want the class to return a boolean value as the return. ' If this value is set to false, it will return the input value exactly as it was sent or it will ' strip the variable clean of all content if it fails the validation. ' . Default: FALSE = It will dump the variable by default ' . ReturnError (boolean) ' . If set to TRUE and if an error is triggered, the error message is returned as the value instead ' of a boolean value or null. ' . Default: TRUE ' . AllowNulls (boolean) ' . If set to TRUE, using a null or blank value in the input parameter will not trigger an error. A null value will be passed back. ' . Default: TRUE ' . TrimInput (boolean) ' . If set to TRUE, all inputs are trimmed (meaning that the spaces on either end are deleted). ' . Defualt: TRUE ' Read Only ' . failedOn (string) ' . Returns a message containing some information on how the contents of your variable failed validation ' . Input (string) ' . Returns the last input validated ' . isValid (boolean) ' . Returns the last validation ' . dataType (string) ' . Returns the last datatype used ' . Length (integer) ' . Returns the length that was used against validation ' . isHex (boolean) ' . Returns the whether the input value was a hexadecimally encoded ' . isError (boolean) ' . Returns whether an error occured ' . ErrorMsg (string) ' . Returns the error message that was generated in the event of an error ' USAGE ' ' Dim checkTool ' Dim myString ' Set checkTool = New Validate ' checkTool.ReturnBool = TRUE ' myString = "For every thing, there is a time and a season for every purpose of under heaven.'SELECT * FROM TABLE;" ' checkTool.validate(myString, "desc", 100) 'Returns False because the string contains the illegal word "select ". ' '******************************************************************************* Class validate 'Variable Declarations Private c_ALPHACHARS Private c_NUMCHARS Private c_SPECIALCHARS Private c_EMAILCHARS Private c_URLCHARS Private c_HEXCHARS Private c_DESCCHARS Private c_SESSIONCHARS Private c_NAMECHARS Private c_PASSWORDCHARS Private c_ALPHANUM Private c_SERIALNUM Private c_USERNAME Private p_input Private p_validated Private p_dataType Private p_length Private p_returnBool Private p_isHex Private p_ascValue Private p_trimInput Private p_failedOn Private p_allowNulls Private p_hexValue 'Error Handling Private p_error Private p_isError Private p_errorMsg Private p_returnError 'INITIALIZE CLASS 'Sets the class defaults. Private Sub Class_Initialize 'Initialize Constants c_ALPHACHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" c_NUMCHARS = "0123456789." c_ALPHANUM = c_ALPHACHARS & c_NUMCHARS c_SPECIALCHARS = "éèëêãàáäâõóòöôíìïîúùüûýÿñçÉÈËÊÃÀÁÄÂÕÓÒÖÔÍÌÏÎÚÙÜÛÝÑÇ" c_EMAILCHARS = c_ALPHANUM & ".@-_" c_URLCHARS = c_ALPHANUM & ".-_:/?&=%" c_HEXCHARS = c_NUMCHARS & "ABCDEF" c_DESCCHARS = c_ALPHANUM & c_SPECIALCHARS & ".@-_:/?!#$%&()=+|/\,' " c_SESSIONCHARS = c_HEXCHARS & "-" c_NAMECHARS = c_ALPHACHARS & c_SPECIALCHARS & "'- ." c_PASSWORDCHARS = c_ALPHANUM & "!@#$%&*?" c_SERIALNUM = c_ALPHANUM & "- ./\:,(){}" c_USERNAME = c_ALPHANUM & c_SPECIALCHARS & ".-!?#$%'" 'Initialize Vars p_input = NULL p_validated = NULL p_dataType = NULL p_length = NULL p_failedOn = NULL p_isHex = FALSE p_hexValue = NULL 'Default Settings p_returnBool = FALSE 'Will return the input value on positive validation, and null on failed ones. p_trimInput = TRUE 'Will trim spaces from inputs p_allowNulls = TRUE 'Won't throw an error on null inputs p_returnError = TRUE 'On an error, it will return the error as a return on the input parameter. 'Error Settings p_isError = FALSE p_errorMSG = NULL End Sub '---------------------------------------------------------------------------------------------------------- ' CORE VALIDATING FUNCTION ' Requires: ' . input (string): the string that you want to validate ' . dataType (string): must be 'name', 'email', 'password', 'number', 'session' or 'desc' ' . length (string or integer): a number representing the length of the input string to validate '---------------------------------------------------------------------------------------------------------- Public Function validate(input, dataType, length) 'Check for null input value. If the input is null and allowNulls is True, exit the function. No error message will be displayed. If ((input = "" OR IsNull(input)) And p_allowNulls) Then validate = NULL : Exit Function 'Error handling. Check the functions values. If input = "" OR IsNull(input) Then Call HandleError("No input value was provided.") : Exit Function If dataType = "" OR IsNull(dataType) Then Call HandleError("No dataType value was provided.") : Exit Function If length = "" OR IsNull(length) Then Call HandleError("No length value was provided for " & input & ".") : Exit Function If IsNumeric(length) Then p_length = CInt(length) If p_length = 0 Then Call HandleError("The length value cannot be zero in length.") : Exit Function Else Call HandleError("The length value must be numeric.") : Exit Function End If If p_trimInput Then p_input = Trim(input) Else p_input = input p_dataType = dataType p_validated = TRUE p_failedOn = "Security precaution raised at " 'Validate against good characters. Select Case LCase(p_dataType) Case "name" p_validated = validateChars(c_NAMECHARS) Case "username" p_validated = validateChars(c_USERNAME) Case "email" p_validated = validateChars(c_EMAILCHARS) Case "url" p_validated = validateChars(c_URLCHARS) Case "password" p_validated = validateChars(c_PASSWORDCHARS) Case "number" p_validated = validateChars(c_NUMCHARS) Case "session" p_validated = validateChars(c_SESSIONCHARS) Case "desc" p_validated = validateChars(c_DESCCHARS) Case "alphanum" p_validated = validateChars(c_ALPHANUM) Case "date" p_validated = IsDate(p_input) Case "serial" p_validated = validateChars(c_SERIALNUM) Case "off" 'Turns this portion off. Use with discretion. p_validated = TRUE Case Else p_validated = FALSE Call HandleError("The dataType """ & p_dataType & """ is invalid. It can only be 'name', 'email', 'password', 'number', 'session', 'date', 'serial' or 'desc'.") End Select 'Validate against dangerous word list If p_validated Then p_validated = launderVar(p_input) If (p_validated AND detectHex(p_input)) AND LCase(p_dataType <> "serial") Then 'Disable hex validation for serial numbers. p_ascValue = hex2asc() p_validated = launderVar(p_ascValue) If Not p_validated Then p_failedOn = p_failedOn & " Detected in Hex." End If 'Check Length if validation is still true If p_validated Then p_validated = validateLength(p_input, p_length) 'If validation fails, dump the input. If p_validated = FALSE Then p_input = null 'Return the input value, or a boolean value representing a pass or fail. If p_returnBool Then validate = p_validated Else validate = p_input End Function '----------------------------------------------------- ' VALIDATES INDIVIDUAL CHARACTERS OF A STRING ' This will check every single character in a given ' string against a list of valid characters. ' o Returns true or false '----------------------------------------------------- Private Function validateChars(goodChars) Dim validate Dim i, c validate = TRUE For i = 1 to len(p_input) c = mid(p_input, i, 1) If (InStr(goodChars, c) = 0) Then validate = FALSE Exit For End If Next If Not Validate Then p_failedOn = p_failedOn & "validateChars on character """ & C & """. This character is not allowed. Chars that were used: " & goodChars validateChars = validate End Function '----------------------------------------------------- ' DETERMINE IF A STRING CONTAINS DANGEROUS WORDS ' Returns true or false '----------------------------------------------------- Private Function launderVar(input) Dim clean Dim dangers Dim delimiters Dim word Dim z, i dangers = Array("script", ";--", "/*", "*/", "@@", _ "nchar", "varchar", "nvarchar", _ "delete", "execute", _ "sysobjects", "syscolumns", _ "information_schema") delimiters = Array(" ", "(") clean = TRUE For z = 0 To UBound(delimiters) For i = 0 To UBound(dangers) If InStr(LCase(input), dangers(i) & delimiters(z)) > 0 Then clean = FALSE word = dangers(i) & delimiters(z) Exit For End If Next Next If Not clean Then p_failedOn = p_failedOn & "launderVar on word """ & word & """. That word is illegal." launderVar = clean End Function '----------------------------------------------------- ' CHECK THE LENGTH OF A STRING ' Returns true or false '----------------------------------------------------- Private Function validateLength(input, length) Dim pass pass = Len(input) <= length If Not pass Then p_failedOn = p_failedOn & "validateLength. The length of your string is " & Len(input) & " and the max length is " & length & "." validateLength = pass End Function '----------------------------------------------------- ' DETECT HEXADECIMAL STRING ' Determines whether a string is encoded in ' hexadecimal format. This is not 100% accurate as ' it merely runs the string through a check to see ' if there are any alpha characters from ranging ' from G-Z. Small strings may not contain any of ' these characters. ' Returns true or false '----------------------------------------------------- Private Function detectHex(input) Dim nonHexChars: nonHexChars = "ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ" Dim isHex Dim i, c isHex = TRUE For i = 1 to len( input ) c = mid( input, i, 1 ) If ( InStr( nonHexChars, c ) > 0 ) Then isHex = FALSE End If Next detectHex = isHex End Function '----------------------------------------------------- ' CONVERT ASCII TO HEX VALUE '----------------------------------------------------- Private Function ascToHex(input) for x = 1 to len(input) target = target & hex(asc(mid(input,x,1))) next ascToHex = target End Function '----------------------------------------------------- ' CONVERT HEX TO ASCII '----------------------------------------------------- Private Function hex2asc() ON ERROR RESUME NEXT For y = 1 To Len(p_input) num = Mid(p_input, y, 2) Value = Value & chr(CLng("&H" & num)) y = y + 1 Next hex2asc = Value End Function ' '----------------------------------------------------- 'ERROR HANDLER ' This is dependent upon the Error Class '----------------------------------------------------- Private Sub HandleError(msg) Response.write msg ' Set p_error = New ErrorMsg ' p_error.Title = "VB Validate Class Error" ' p_error.Throw msg ' p_isError = TRUE ' p_errorMsg = msg ' p_input = NULL ' If p_returnError Then Response.Write p_errorMsg End Sub '----------------------------------------------------- ' READ/WRITE PROPERTIES '----------------------------------------------------- Public Property Let ReturnBool(boolValue) p_returnBool = boolValue End Property Public Property Get ReturnBool() returnBoolValue = p_returnBool End Property Public Property Let returnError(boolValue) p_returnError = boolValue End Property Public Property Get returnError() returnError = p_returnError End Property Public Property Let allowNulls(boolValue) p_allowNulls = boolValue End Property Public Property Get allowNulls() allowNulls = p_allowNulls End Property Public Property Let TrimInput(boolValue) p_trimInput = boolValue End Property Public Property Get TrimInput() TrimInput = p_trimInput End Property '----------------------------------------------------- ' READ PROPERTIES '----------------------------------------------------- Public Property Get failedOn() If p_validated = false Then 'check to see if an error indeed occurred. failedOn = p_failedOn Else failedOn = "No error detected." End If End Property Public Property Get Input() input = p_input End Property Public Property Get isValid() isValid = p_validated End Property Public Property Get dataType() dataType = p_dataType End Property Public Property Get Length() length = p_length End Property Public Property Get isHex() isHex = p_isHex End Property Public Property Get isError() isError = p_isError End Property Public Property Get errorMessage() errorMessage = p_errorMsg End Property End Class %>