...

View Full Version : FUNCTION: Validate Form Submissions



Element
12-28-2005, 03:32 AM
This function will allow you to validate whether the submission is coming from your site, and if it has code in the $_POST fields (optional)



<?php

// By Jordan S. C. Thompson
// Some help by Velox Letum

// This script will check to make sure the submission
// is coming from your site, and that no code is
// found in the post fields.


function validateFormSubmission($noCodeCheck = FALSE) {
if(isset($_POST)) {
$runningScriptOn = "http://".$_SERVER['HTTP_HOST']."/";
$referParts = parse_url($_SERVER['HTTP_REFERER']);
if(empty($referParts['scheme'])) {
$scheme = "http://";
} else {
$scheme = $referParts['scheme'];
}
$host = $referParts['host'];
$referRunningOn = $scheme . $host;
if($referRunningOn !== $runningScriptOn) {
$die = 1;
}
if($noCodeCheck == FALSE) {
foreach($_POST as $key => $val) {
if(strlen($val) != strlen(strip_tags($val)){
$die++;
}
}
}
if($die == 1) {
die("There was a problem with the form submission.");
} elseif($die == 2) {
die("There was more the one problem with the form submission.");
} else {
return true;
}
} else {
return true;
}
}

?>


Here is an example of using it:



<?php
// This is at the top of my doument, under where you would include or place the function.

// Example one, check refer and for code
validateFormSubmission();

// Example two, check refer, but don't check for code
validateFormSubmission(TRUE);

?>


If you want to use this else where in the file, and don't want it to die and kill your template then replace:



// Original Code
if($die == 1) {
die("There was a problem with the form submission.");
} elseif($die == 2) {
die("There was more the one problem with the form submission.");
} else {


With:



// Replacement Code
if(isset($die)) {
return false;
} else {


I hope this is usefull. :)

matthijs
02-09-2006, 07:55 AM
If I understand your code you compare $_SERVER['HTTP_HOST'] with $_SERVER['HTTP_REFERER']. But since both data can not be trusted (1,2,3), how can you be sure the function is doing what it is supposed to be doing? In other words, if both can be spoofed, you never know if the form did come from your site?

(1) shiflett.org (http://shiflett.org/archive/98)
(2) Php architects guide to php security, Ilia Alshanetsky
(3) http://www-128.ibm.com/developerworks/blogs/dw_blog_comments.jspa?blog=481&entry=75480

marek_mar
02-09-2006, 09:52 AM
You can't. I have a little program which can fake the referer so it'll always be the address I'm accessing a page from...
BTW the if(isset($_POST)) is not needed as $_POST is always set.

matthijs
02-09-2006, 10:27 AM
So I'm correct in saying the script doesn't work as intended.
Probably a good point to consider is the question why you would want to make sure the form submission is coming from your site. I remember reading in Shiflett's book that in his opinion it really doesn't matter were the form submission is coming from: one needs a good input filtering anyway.

marek_mar
02-09-2006, 12:30 PM
You can check if a request came form your site with sessions

Element
02-09-2006, 10:43 PM
*Shrugs* Its just code, if you need to shoot someone, shoot yourself. ;) Because I don't care.

The method has been around for a long time and is a basic way. If someone can foool referers, an such they can do much more that you can't stop anyway without getting complicating and blogging down scripts.

matthijs
02-10-2006, 08:04 AM
*Shrugs* Its just code, if you need to shoot someone, shoot yourself. Because I don't care.
I'm not sure I understand what you mean here (ah, how difficult is it to communicate in a few lines of text..) but I hope you understand I'm not attacking you in any way. I just try to learn myself. When I saw the code and remembered reading about the faking of the SERVER variables I posted my question to invoke a little discussion.

What other ways would you suggest to use if one really wants to be sure the request came from your site? Sessions as marek_mar suggests?

(as I said before the best strategy is to never trust any input, wether it's coming from your site or somewere else. But I can imagine that in some cases checking if the form came from the same site can be used as a defense in depth measure. And in that case you could/might want to try to do that the best you can)

raf
03-08-2006, 11:35 AM
What other ways would you suggest to use if one really wants to be sure the request came from your site? Sessions as marek_mar suggests?
the request never comes from your site. the request always comes from the browser.
a form is actually nothing more then a way to allow the browser to compose the POST or GET collection and then include it inside the request. in fact, it doesn't even need to be a browser. any server can parse your response that contains the form, and build a POST-collection and send that back to your server.
Or a server can parse the form, build another form from it, send that form to a user who displays it in his browser and posts it to your server. or who first posts it to the go-between server which builds the POST-collection that is sent to your server.

basicaly, there is no way on earth that you can verify if the POST-collection was generated with the form you sent in your response.

but the good news is that it doesn't matter how the client composed the POST-collection. the only thing that matters is if the client included valid values or not, and it's quite easy to check that.

matthijs
03-08-2006, 12:24 PM
You are absolutely correct.
but the good news is that it doesn't matter how the client composed the POST-collection. the only thing that matters is if the client included valid values or not, and it's quite easy to check that.
Indeed, never trusting any input and validating the input well is the best (and only) thing you should do. Whether it's easy? I don't know. For beginners those regexes can look pretty scary.

But about the purpose of the original script in this thread: I did read a method in the security guide of http://phpsec.org with which it should/supposedly be possible to make sure the form was posted from the site itself. That method uses random tokens and sessions to store them. But anyone interested should read the guide, as I can't explain the details.Cross site request forgeries (http://phpsec.org/projects/guide/2.html#2.4)

GJay
03-08-2006, 04:19 PM
The Zend framework includes an input filter:
http://framework.zend.com/manual/zend.inputfilter.html

matthijs
03-08-2006, 04:59 PM
Yes, the zend framework and the way it can be used to foolproof and validate input looks promising. Just finished coding a couple of forms, not even that complicated. But even though I use a standard validation class, typing it all out is still too much work. Hopefully a framework like Zend's will make it all a lot easier (also easier to make less mistakes!)

marek_mar
03-08-2006, 05:40 PM
the request never comes from your site.
It can come from your site. It is useless in most cases though. :)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum