Tech Issues
.NET
.NET FrameWork
ASP.NET FrameWork
Cross Platform
C Sharp
VB.NET
ADO.NET
Managed C++
Remoting
Smart Client
SOAP/XML
Threading
XML Web Services
Windows Services
.NET General
Active Directory
ADO.NET
Applications
ATL Server
BizTalk Server
COM Interop
Compact Framework
Databases
Deployment
Encryption
Exception Handling
Forth .NET
Fortran .NET
GDI+
General
How To
Instrumentation
Internet & Network
J# .NET
MFC/ATL for VC++ 7
MSIL
Office Development
Parsers
Patterns and Practices
Printing
Purgatory
Samples
Security
Unedited Stuff
Utilities
Visual Basic .NET
VS.NET Add-Ins
VS.NET Macros
XAML
ASP.NET
Application
ASP.NET Controls
Caching
Content Management
Custom Controls
Data & Database
Debugging
Design & Architecture
HTML Controls
Images & Multimedia
Reporting
Security
Server Management
Session & Session State
User Controls
Validation
Viewstate
Web Forms
XML/XSL
MS SQL Server
Backup & Recovery
Constraints
Data Types
Design Issues
DTS (Data Transformation)
Full Text Catalog
Functions
Indexing
Job Scheduling
Maintenance
Meta Data Services
Processes
Profiler
Query Analyzer
Replication
Security
Stored Procedures
Support Services
System Databases
Tables
Triggers
T-SQL
Tuning
Views
C#
Algorithms
Applications
Attributes
Beginners
COM / COM+
COM Interop
Computational Geometry
Controls
Data Structures
Database
DataSets, DataGrids etc
Debug and Tracing
Delegates and Events
Design and Architecture
Distributed Apps
Files and Directories
Fuzzy Logic
Games
GDI+
General
Generics
Graphics
How To
Internet
Libraries
Longhorn
Memory Management
Multimedia
Network
Office Programming
Parsers
PInvoke
Printing
Purgatory
Registry
Regular Expressions
Remoting
Samples
Security
Shell Programming
System
Threading
Threads
Unedited Reader Contributions
Utilities
VS.NET Addins
Web Services
Windows Forms
XML/XSLT
Tech >> DOTNET >> ASP.NET
Client and server side input validations using ASP
1.0 Introduction

One of the integral part of any site is the feedback form. But along with utility of the form it can be exploited as well to enter junk data including scripts. These scripts execute in the browser context of the user viewing the posted data. The scripts could be the attacker's choice which include but not limited to
1. flooding unwanted alerts on the browser screen

2. Redirecting to a web site. If the data posted in the feedback form contains a script such as <script>navigate(http://www.yahoo.com)</script>

then this could redirect the user viewing the feedback to the web site as mentioned. This could make the feedback data unavailable to the person viewing the posted feedback.

 

2.0 Input Validations

To avoid the above situations we perform input validation.

Input validation is of two types

            2.1 client side validation

            2.2 server side validation

 

2.1 Client side validation

It acts on the form itself. It checks out whether the field which the user has filled in is compliant with what we want, as in the case of the telephone number, it should have digits, name should have alphabets only. Thus in all it acts on the user interface or on the web page itself.

 

2.2 Server side validation

  We know that the web page interacts with the web server before the data is entered in the database. Thus the intruder can place a proxy (HTTP interceptor. Several such tool are available for download on the internet) in between the web browser  and the web server and can easily perform injections or change the data and bypassing the input validations rule imposed on the client web pages. Thus causing unwanted data to be uploaded to the database which could lead to unwanted results. Thus to avoid such a situation we perform server side validation.

 

3.0 Illustration

To elaborate more on the above written facts we illustrate a feedback form

 

3.1 With no client side validation

You can fill in any data and it will not be entered anywhere. This is just for illustration purpose

 

Click here to view the form. When you view the form click View->Source from the browser menu. The following is a dump of the source for the feedback form without client side validations.

 

3.2 With no server side validation

This form has only client side validation and no server side validation. This form also will not be submitted anywhere. This is just for the illustration purpose.

 

 

click here for the form. A preview of the source for the client side validations implemented is as follows. You can see the details by clicking View->Source on the form.

 

3.3 With client side and server side validation

This is a complete form which illustrates the client side and server side validation.

 

click here for the form

You will find the code for the following

3.3.1 Feedback form

 

3.3.2 client side validation

 

3.3.3 server side validation

 

3.3.4 connection with the database

 

 

3.3.1 Feedback form

The Form

The Code

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"  "http://www.w3.org/TR/html4/strict.dtd">

<HTML lang="EN">

<HEAD>

    <TITLE>Javascript form validation - doing it right</TITLE>

    <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

    <META NAME="description" CONTENT="">

    <META NAME="keywords" CONTENT="">

 

    <LINK href='../basic.css' rel='stylesheet'>

    <LINK rel="shortcut icon" href="../img/siteicon.ico" type="image/x-icon">

 

    <LINK REL=Contents HREF="index.html">

    <LINK REL=Home     HREF="../index.html">

    <LINK REL=Search   HREF="../search.htm">

    <LINK REL=Author   HREF="contact.html">

 

    <SCRIPT TYPE="text/javascript" src=formval.js>

    </SCRIPT>

 

    <STYLE TYPE="text/css">

      @import url(../extrastyles.css);

      @import url(../formval.css);

            .runinhdr { font-weight: bold; font-size: 120%; padding-right: 1em; }

    </STYLE>

</HEAD>

 

<BODY  BGCOLOR=PINK TEXT=BLUE   >

 

<DIV ID="page">

 

<DIV ID="wmbanner"><U><B><CENTER>FEEDBACK FORM</CENTER></B></U>

</DIV>

 

 

 

 

<SCRIPT TYPE="text/javascript" >

// Only script specific to this form goes here.

// General-purpose routines are in a separate file.

 

function validateOnSubmit() {

    var elem;

    var errs=0;

    // execute all element validations in reverse order, so focus gets

    // set to the first one in error.

    if (!validateTelnr  (document.forms.demo.telnr, 'inf_telnr', true)) errs += 1;

    if (!validatename   (document.forms.demo.from,  'inf_from', true))  errs+=1;

    if (!validateEmail  (document.forms.demo.email, 'inf_email', true)) errs += 1;

            if (!validatedesig  (document.forms.demo.from,  'inf_from', true))  errs+=1;

            if (!validatedesig  (document.forms.demo.from,  'inf_from', true))  errs+=1;

            if (!validatePresent(document.forms.demo.from,  'inf_from'))        errs += 1;

 

    if (errs>1)  alert('There are fields which need correction before sending');

    if (errs==1) alert('There is a field which needs correction before sending');

 

    return (errs==0);

  };

</SCRIPT>

 

 

 

 

<FORM NAME=demo onsubmit="return validateOnSubmit()"  ACTION="add_to_guestbook41.asp" METHOD="POST" >

<TABLE CLASS=formtab SUMMARY="Demonstration form">

  <TR>

    <TD STYLE="width: 10em">

        <LABEL FOR=from>Your name:</LABEL></TD>

    <TD><INPUT TYPE=text NAME="from" ID="from" SIZE="35" MAXLENGTH="50"

         ONCHANGE="validatename(this, 'inf_from',true);"></TD>

    <TD id="inf_from">Required</TD>

  </TR>

 

 

<TR>

    <TD STYLE="width: 10em">

        <LABEL FOR=from>Organization:</LABEL></TD>

    <TD><INPUT TYPE=text NAME="organization" ID="organization" SIZE="35" MAXLENGTH="50"

         ONCHANGE="validatedesig(this, 'inf_org',true);"></TD>

    <TD id="inf_org">Required</TD>

  </TR>

 

 

<TR>

    <TD STYLE="width: 10em">

        <LABEL FOR=from>Designation:</LABEL></TD>

    <TD><INPUT TYPE=text NAME="designation" ID="designation" SIZE="35" MAXLENGTH="50"

         ONCHANGE="validatedesig(this, 'inf_desig',true);"></TD>

    <TD id="inf_desig">Required</TD>

  </TR>

 

 

 

 

 

  <TR>

    <TD><LABEL FOR=email>Your e-mail address:</LABEL></TD>

    <TD><INPUT TYPE=text NAME="email" ID="email" SIZE="35" MAXLENGTH="50"

         ONCHANGE="validateEmail(this, 'inf_email', true);"></TD>

    <TD id="inf_email">Required</TD>

  </TR>

 

 

<!-- Note: the element to receive error messages must contain some data (for most,

     if not all, browsers). A &nbsp; is sufficent. -->

 

  <TR>

    <TD><LABEL FOR=telnr>Your telephone number:</LABEL></TD>

    <TD><INPUT TYPE=text NAME="telnr" ID="telnr" SIZE="35" MAXLENGTH="25"

         ONCHANGE="validateTelnr(this, 'inf_telnr', true);"></TD>

    <TD id="inf_telnr">Required. You can use spaces or hyphens if you wish.</TD>

  </TR>

 

 

 

  <TR>

    <TD>&nbsp;</TD>

    <TD><INPUT TYPE="Submit" NAME="Submit" VALUE="Send">

    <INPUT TYPE="reset" NAME="reset" VALUE="Reset"></TD>

    <TD>&nbsp;</TD>

  </TR>

 

 

</TABLE>

</FORM>

 

<HR> <!-- ====================================== -->

 

 

</BODY>

</HTML>

 

 

3.3.2  client side validationThe following is the code for client side validation

 

// ----------------------------------------------------------------------

// Javascript form validation routines.

// Author: Stephen Poley

//

// Simple routines to quickly pick up obvious typos.

// All validation routines return true if executed by an older browser:

// in this case validation must be left to the server.

//

// Update Aug 2004: have tested that IE 5.0 and IE 5.5 both support DOM model

// sufficiently well, so innerHTML option removed (redundant).

//

// Update Jun 2005: discovered that reason IE wasn't setting focus was

// due to an IE timing bug. Added 0.1 sec delay to fix.

// ----------------------------------------------------------------------

 

var nbsp = 160;    // non-breaking space char

var node_text = 3; // DOM text node-type

var emptyString = /^\s*$/

var glb_vfld;      // retain vfld for timer thread

 

// -----------------------------------------

//                  trim

// Trim leading/trailing whitespace off string

// -----------------------------------------

 

function trim(str)

{

  return str.replace(/^\s+|\s+$/g, '')

};

 

 

// -----------------------------------------

//                  setfocus

// Delayed focus setting to get around IE bug

// -----------------------------------------

 

function setFocusDelayed(vfld)

{

  glb_vfld.focus()

}

 

function setfocus(vfld)

{

  glb_vfld = vfld;

  setTimeout( 'setFocusDelayed()', 100 );

}

 

 

// -----------------------------------------

//                  msg

// Display warn/error message in HTML element

// commonCheck routine must have previously been called

// -----------------------------------------

 

function msg(fld,     // id of element to display message in

             msgtype, // class to give element ("warn" or "error")

             message) // string to display

{

  // setting an empty string can give problems if later set to a

  // non-empty string, so ensure a space present. (For Mozilla and Opera one could

  // simply use a space, but IE demands something more, like a non-breaking space.)

  var dispmessage;

  if (emptyString.test(message))

    dispmessage = String.fromCharCode(nbsp);   

  else 

    dispmessage = message;

 

  var elem = document.getElementById(fld);

  elem.firstChild.nodeValue = dispmessage; 

 

  elem.className = msgtype;   // set the CSS class to adjust appearance of message

};

 

// -----------------------------------------

//            commonCheck

// Common code for all validation routines to:

// (a) check for older / less-equipped browsers

// (b) check if empty fields are required

// Returns true (validation passed),

//         false (validation failed) or

//         proceed (don't know yet)

// -----------------------------------------

 

var proceed = 2; 

 

function commonCheck    (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  if (!document.getElementById)

    return true;  // not available on this browser - leave validation to the server

  var elem = document.getElementById(ifld);

  if (!elem.firstChild)

    return true;  // not available on this browser

  if (elem.firstChild.nodeType != node_text)

    return true;  // ifld is wrong type of node 

 

  if (emptyString.test(vfld.value)) {

    if (reqd) {

      msg (ifld, "error", "ERROR: required"); 

      setfocus(vfld);

      return false;

    }

    else {

      msg (ifld, "warn", "");   // OK

      return true; 

    }

  }

  return proceed;

}

 

// -----------------------------------------

//            validatePresent

// Validate if something has been entered

// Returns true if so

// -----------------------------------------

 

function validatePresent(vfld,   // element to be validated

                         ifld )  // id of element to receive info/error msg

{

  var stat = commonCheck (vfld, ifld, true);

  if (stat != proceed) return stat;

 

  msg (ifld, "warn", ""); 

  return true;

};

 

// -----------------------------------------

//               validateEmail

// Validate if e-mail address

// Returns true if so (and also if could not be executed because of old browser)

// -----------------------------------------

 

function validateEmail  (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  var stat = commonCheck (vfld, ifld, reqd);

  if (stat != proceed) return stat;

 

  var tfld = trim(vfld.value);  // value of field with whitespace trimmed off

  var email = /^[^@]+@[^@.]+\.[^@]*\w\w$/

  if (!email.test(tfld)) {

    msg (ifld, "error", "ERROR: not a valid e-mail address");

    setfocus(vfld);

    return false;

  }

 

  var email2 = /^[A-Za-z][\w.-]+@\w[\w.-]+\.[\w.-]*[A-Za-z][A-Za-z]$/

  if (!email2.test(tfld))

    msg (ifld, "warn", "Unusual e-mail address - check if correct");

  else

    msg (ifld, "warn", "");

  return true;

};

 

//----------------------------------------------------------------

//                        validataname

//this function checks to validate name

//-----------------------------------------------------------------

 

function validatename   (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  var stat = commonCheck (vfld, ifld, reqd);

  if (stat != proceed) return stat;

 

  var tfld = trim(vfld.value);  // value of field with whitespace trimmed off

  var name = /^[A-Za-z]/

  if (!name.test(tfld))

  {

    msg (ifld, "error", "ERROR: not a valid name");

    setfocus(vfld);

    return false;

  }

 

  return true;

};

 

 

//-----------------------------------------

//                                  validate designation

//

//-------------------------------------------

function validatedesig   (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  var stat = commonCheck (vfld, ifld, reqd);

  if (stat != proceed) return stat;

 

  var tfld = trim(vfld.value);  // value of field with whitespace trimmed off

  var desig = /^[A-Za-z]/

  if (!desig.test(tfld))

  {

    msg (ifld, "error", "ERROR: not  valid ");

    setfocus(vfld);

    return false;

  }

 

  return true;

  };

 

 

// -----------------------------------------

//            validateTelnr

// Validate telephone number

// Returns true if so (and also if could not be executed because of old browser)

// Permits spaces, hyphens, brackets and leading +

// -----------------------------------------

 

function validateTelnr  (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  var stat = commonCheck (vfld, ifld, reqd);

  if (stat != proceed) return stat;

 

  var tfld = trim(vfld.value);  // value of field with whitespace trimmed off

  var telnr = /^\+?[0-9 ()-]+[0-9]$/

  if (!telnr.test(tfld)) {

    msg (ifld, "error", "ERROR: not a valid telephone number. Characters permitted are digits, space ()- and leading +");

    setfocus(vfld);

    return false;

  }

 

  var numdigits = 0;

  for (var j=0; j<tfld.length; j++)

    if (tfld.charAt(j)>='0' && tfld.charAt(j)<='9') numdigits++;

 

  if (numdigits<6) {

    msg (ifld, "error", "ERROR: " + numdigits + " digits - too short");

    setfocus(vfld);

    return false;

  }

 

  if (numdigits>14)

    msg (ifld, "warn", numdigits + " digits - check if correct");

  else {

    if (numdigits<10)

      msg (ifld, "warn", "Only " + numdigits + " digits - check if correct");

    else

      msg (ifld, "warn", "");

  }

  return true;

};

 

// -----------------------------------------

//             validateAge

// Validate person's age

// Returns true if OK

// -----------------------------------------

 

function validateAge    (vfld,   // element to be validated

                         ifld,   // id of element to receive info/error msg

                         reqd)   // true if required

{

  var stat = commonCheck (vfld, ifld, reqd);

  if (stat != proceed) return stat;

 

  var tfld = trim(vfld.value);

  var ageRE = /^[0-9]{1,3}$/

  if (!ageRE.test(tfld)) {

    msg (ifld, "error", "ERROR: not a valid age");

    setfocus(vfld);

    return false;

  }

 

  if (tfld>=200) {

    msg (ifld, "error", "ERROR: not a valid age");

    setfocus(vfld);

    return false;

  }

 

  if (tfld>110) msg (ifld, "warn", "Older than 110: check correct");

  else {

    if (tfld<7) msg (ifld, "warn", "Bit young for this, aren't you?");

    else        msg (ifld, "warn", "");

  }

  return true;

} 

 

3.3.3 server side validation The following is the code for server side validation on the server side program

  <%

Session("name")=request.Form("from")

Session("organization")=request.Form("organization")

Session("designation")=request.Form("designation")

Session("email")=request.Form("email")

Session("telephone")=request.Form("telnr")

%>

 

<%

function checkexp()

'Read in the username

            Dim strUserName,iStrPos, iLoop, strCurrentChar, bolValid,bolValidString

                                                           

            strUserName = Session("name")

            'response.Write(strUserName)

            strCurrentChar= Mid(strUserName, 2, 1)

 

if Len(strUsername)=0 then

response.Write("need to fill in the name field")

checkexp=1

exit function

end if

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if InStr("0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM",strCurrentChar)<=0 then

 response.Write("characters need to be a-z or A-Z or 0-9 please go back and refill")

 checkexp=1

 exit function

 end if

next

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if (strCurrentChar = " ") then

else

end if

                        next

                       

checkexp=0                 

                       

            end function

 

function checkexp1()

'Read in the username

            Dim strUserName,iStrPos, iLoop, strCurrentChar, bolValid,bolValidString

                                                           

            strUserName = Session("organization")

            'response.Write(strUserName)

            strCurrentChar= Mid(strUserName, 2, 1)

 

if Len(strUsername)=0 then

response.Write("<br><br>need to fill in the organization field")

checkexp1=1

exit function

end if

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if InStr("0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM",strCurrentChar)<=0 then

 response.Write("characters need to be a-z or A-Z or 0-9 please go back and refill")

 checkexp1=1

 exit function

 end if

next

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if (strCurrentChar = " ") then

else

end if

                        next

                       

checkexp1=0                

                       

            end function

 

 

function checkexp2()

'Read in the username

            Dim strUserName,iStrPos, iLoop, strCurrentChar, bolValid,bolValidString

                                                           

            strUserName = Session("designation")

            'response.Write(strUserName)

            strCurrentChar= Mid(strUserName, 2, 1)

 

if Len(strUsername)=0 then

response.Write("<br><br>need to fill in the designation field")

checkexp2=1

exit function

end if

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if InStr("0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM",strCurrentChar)<=0 then

 response.Write("characters need to be a-z or A-Z or 0-9 please go back and refill")

 checkexp2=1

 exit function

 end if

next

 

For iLoop = 1 to (Len(strUsername))

                                    strCurrentChar = Mid(strUserName, iLoop, 1)

if (strCurrentChar = " ") then

else

end if

                        next

                       

checkexp2=0                

                       

            end function

 

 

function isvalidphone()

dim phones,i,c

phones=Session("telephone")

 for i=1 to Len(phones)

 c=Mid(phones,i,1)

 if InStr("0123456789-+",c)<=0 then

 response.write(" <br><br><b>Invalid Entry !!!<br><hr><P><b>Invalid Telephone numnber. The allowed character set is 0123456789-+.<b><p><br>Go back and Reenter the No<br>")

 isvalidphone=1

 exit function

 end if

 next

 

 if len(phones)=0 then

 response.Write(" <br><br><b>Invalid Entry !!!<br><hr><P><b>Invalid Telephone numnber. The allowed character set is 0123456789-+.<b><p><br>Go back and Reenter the No<br>")

 isvalidphone=1

 exit function

 end if

 

 isvalidphone=0

 

 end function

 

 

 

%>

 

<%

dim iresult,iresult1,iresult2,iresult3

iresult=checkexp()

iresult1=checkexp1()

iresult2=checkexp2()

iresult3=isvalidphone()

if iresult=0  and iresult1=0 and iresult2=0 and iresult3=0 then

response.Redirect"add_to_guestbook11.asp"

else

response.Write("<br><br>something's wrong somewhere")

end if

%>

 

3.3.4 connection with the database Following is the code for connection with the database on the server side program.

<%

 

dim adoCon                               'Holds the Database Connection Object

Dim rsAddComments     'Holds the recordset for the new record to be added to the database

Dim strSQL                   'Holds the SQL query for the database

 

' Create an ADO connection odject

Set adoCon = Server.CreateObject("ADODB.Connection")

 

' Set an active connection to the Connection object using a DSN-less connection

adoCon.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("guestbook.mdb")

 

'Set an active connection to the Connection object using DSN connection

'adoCon.Open "DSN=guestbook"

 

'Create an ADO recordset object

Set rsAddComments = Server.CreateObject("ADODB.Recordset")

 

'Initialise the strSQL variable with an SQL statement to query the database

strSQL = "SELECT * FROM tblcomment"

 

 

'Set the cursor type we are using so we can navigate through the recordset

rsAddComments.CursorType = 2

 

'Set the lock type so that the record is locked by ADO when it is updated

rsAddComments.LockType = 3

 

'Open the tblComments table using the SQL query held in the strSQL varaiable

rsAddComments.Open strSQL, adoCon

 

'Tell the recordset we are adding a new record to it

rsAddComments.AddNew

 

'Add a new record to the recordset

rsAddComments.Fields("name") = session("name")

rsAddComments.Fields("organization") = session("organization")

rsAddComments.Fields("designation") = session("designation")

rsAddComments.Fields("emailid") = session("email")

rsAddComments.Fields("telephone") = session("telephone")

rsAddComments.Fields("comments")="kkkk"

 

'Write the updated recordset to the database

rsAddComments.Update

 

'Reset server objects

rsAddComments.Close

Set rsAddComments = Nothing

Set adoCon = Nothing

response.Redirect"guestbook.asp"

 

%>