Forum Moderators: coopster

Message Too Old, No Replies

Form Data > Validation and Cleaning

         

kkonline

5:28 am on Aug 21, 2007 (gmt 0)

10+ Year Member



I am using the following algorithm/flow/pseudocode for
validation and cleaning of data entered by the users
in the form( consisting of fields like name,
main article(text type in db),
mood for election(should ONLY be 1,2,3... 6).

Question >It seems everywhere i have to use if and else statements,
giving me around 8-10 if else statements in this check.
Please look at the approach and tell me if there is a better solution
or i am missing anything or tell if any check can be performed on a
particular field which is important and i have missed.

Basically i just want you to go through the algorithm and discuss it's weakpoints
and suggest some solution to it.

Initially faultflag=0;

A> Cross-Site Request Forgeries check
A1> Token checking -> if incorrect print "invalid source!" and exit;
A2> Timeout detection -> if timeout print "Timeout!" and exit;
A3> If the source is correct (correct domain) Goto B>

B> Check Captcha (prevents spambots)
B1> If wrong print "wrong captcha" $faultflag++;
B2> If correct, Goto C> (till now data from correct source and not a spambot)

C> C1> If( isset[$_POST['name']])
C2> If yes (some name was posted) THEN validate the maxlength<=30 and check D>
else print "too long" faultflag++;
C3> else print "you forgot to write name" faultflag++;

D> Similar to C, check for title and it's length
If valid goto E>

E> E1> If( isset[$_POST['maintext']])
E2> If yes (some article was posted) THEN validate ; if valid goto F>
E3> else print "you forgot to write article" faultflag++;

Ques 1> In point E2> if the article is posted then how should i validate
it. Because in the db I am using text type to store the value as
the article could be very long? Or should i use some other type
for articles in the db? Or should i use text(varchar(2500)) for example?

F> F1> If( isset[$_POST['mood']])
F2> If yes (some mood was posted) THEN validate it to be no. 1 to 6.
else print "wrong mood" faultflag++;
If valid goto G>
F3> else print "you forgot to write mood" faultflag++;

G> G1> If( faultflag>0) print "there are $faultflag errors, fill
the form again. link to the form;
G2> else (when no errors) connect to db

H> [Assuming the "clean" data is in name,mood,maintext]
mysql_real_escape() the name,mood,maintext
trim the name,mood,maintext

Store to db

For displaying the data after extracting it from db I am
converting it into XML format in use following protection
htmlentities($row_rsAll[$column], ENT_NOQUOTES, 'UTF-8');
on the data which is to be printed.

Ques 2> Should i ALSO use the class written by Christian Stocker
for prevention of xss before displaying the data in XML
<snip>
(and use htmlentities alone?)

[edited by: dreamcatcher at 6:47 am (utc) on Aug. 21, 2007]
[edit reason] no urls as per T.O.S [webmasterworld.com].Thanks [/edit]

venelin13

6:13 am on Aug 21, 2007 (gmt 0)

10+ Year Member



Just one notice - it is not a good idea to check directly the value of $_POST['name'], rather you should make some filtering/casting and after that, to check the result data:

//Step 1: you may consider stripping the HTML tags, or some special tags as <script>
$name = strip_tags($_POST['name']);
$age = strip_tags($_POST['age']);

//Step 2: casting is allways a good practice
$name = (string) $name;
$age = (integer) $age;

//Step 3: finally, strip the "white spaces"
$name = trim($name);
$age = trim($age);

All these 3 steps can be combined into one:
$name = (string) trim(strip_tags($_POST['name']));
$age = (int) trim(strip_tags($_POST['age']));

Instead of typing so many code, I have my own function to do all these operations:

/**
* Sanitize data, comming from the forms.
*
* @param $data mixed Anykind of data, posted from a particualr form field.
* @param $type string Data type name - "string", "integer", etc...
* @param $allowed_tags string List of allowed HTML tags, if any. Example: "<p><b><font>"
*/
function sanitize($data, $type, $allowed_tags){

$result = "";

if($type == "string"){
$result = (string) trim(strip_tags($data, $allowed_tags));
}elseif($type == "int"){
$result = (int) trim(strip_tags($data, $allowed_tags));
}

return $result;

}

You may extend it in any way to fit your needs.

After the data is been sanitized, than you may continue with your code:

if(isset($name))
...

kkonline

6:35 am on Aug 21, 2007 (gmt 0)

10+ Year Member



One doubt.
should i use strip_tags() before storing it to db or after it is stored. and when i am displaying the details then(for xss prevention)

Any other changes/suggestions to make the form secure are welcome

venelin13

10:15 am on Aug 21, 2007 (gmt 0)

10+ Year Member



You should use strip_tags() function before store the data into the database.

kkonline

12:32 pm on Aug 21, 2007 (gmt 0)

10+ Year Member



I think if i use Filters then it would reduce the task to nothing
[in2.php.net...]