www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20

Thread: Question about XSS attacks for php contact form security

  1. #1
    Join Date
    Feb 2014
    Posts
    23

    Question about XSS attacks for php contact form security

    Okay, so I have a simple contact form where a user is asked to input his name(required), email(required, checked to see if it is a real email address), telephone number(optional), and a brief message(required, minimum 20 characters). This is then submitted to an email address.

    Although nothing the user inputs is posted back by the browser, it does get sent to an email address. From what I have read and come to understand Output escaping by way of the htmlspecialchars function wouldn't be required in my situation since none of the user input is displayed back by the browser. Am I correct? Basically, should I do any kind of data sanitation in my situation? like striping unnecessary characters from anything the user decides to input? What else can I do to provide some extra security? I see a lot of sites don't bother using captchas, this is mostly to prevent bots from spamming emails right?

    This form is submitted in ajax, with a PHP fallback in case js is disabled in the users browser.

  2. #2
    Join Date
    Feb 2014
    Location
    England
    Posts
    52
    You can use filter_var which is great for sanitizing user input:

    http://net.tutsplus.com/tutorials/ph...h-php-filters/

    Good luck!

  3. #3
    Join Date
    Feb 2014
    Posts
    23
    I love the fact that I'm learning something useful at such a rate, thanks that looks perfect!

  4. #4
    Join Date
    Feb 2014
    Posts
    23
    hmm for some reason this is not working for me,
    in my php file I have: if ( isset(_$POST) ) {

    and then:

    Code:
    $name = filter_var($_POST['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    	$email = $_POST['email'];
    	$telephone = filter_var($_POST['telephone'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    	$enquiry = $_POST['enquiry'];
    	$message = filter_var($_POST['message'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    for all of the submitted form fields, but for some reason when i test it out and i receive an email with the submitted form data i still have characters like / etc in it.

  5. #5
    Join Date
    Feb 2014
    Posts
    23
    Do I need to define a new variable when using filter_var? meaning $name = $_POST['name'] and then do $nameclean = filter_var($name, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

  6. #6
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,622
    If the email is being sent as plain text (not HTML), then XSS shouldn't really be a worry, would it? If you are sending it as as HTML, then htmlentities() or htmlspecialchars() or even strip_tags() would take care of a user trying to sneak malicious links or JavaScript code into the message body.

    Main thing I'd look for is them trying to hijack your mailer by injecting mail headers. Simplest way I've found to stop that from working is to reject anything that has newlines and/or carriage returns for anything other than the message body (i.e. subject, email addresses, additional headers). A simple way to do that:
    PHP Code:
    if(preg_match('/[\r\n]/'$someField)) {
        
    // do not accept this input

    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  7. #7
    Join Date
    Feb 2014
    Location
    England
    Posts
    52
    It's good practice to filter sanitize and validate user input, you may want to add the contact form to a db in the future or display a list of contacts you have had from a website.

    With filter_var it doesn't take long so might aswell.

    If you are doing a name then a good one to use is $nameclean = filter_var($_POST['name'], FILTER_SANITIZE_STRING);

  8. #8
    Join Date
    Feb 2014
    Posts
    23
    For some reason when i define a new variable and give it the value of the filter_var function it does nothing when I test out the contact form. I am sending myself emails with all kinds of characters in the 'name' input field and they are still there in the email i receive with the form data. this is my php code for the contact form I am using,

    Code:
    <?php
    if( isset($_POST) ){
    	
    	//form validation vars
    	$formok = true;
    	$errors = array();
    	
    	//sumbission data
    	$ipaddress = $_SERVER['REMOTE_ADDR'];
    	$date = date('d/m/Y');
    	$time = date('H:i:s');
    	
    	//form data
    	$name = $_POST['name'];
    	$email = $_POST['email'];
    	$telephone = $_POST['telephone'];
    	$enquiry = $_POST['enquiry'];
    	$message = $_POST['message'];
    	
      //sanitize form data
    
    $nameclean = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
       
    	//validate form data
    
    	//validate name is not empty
    	if(empty($name)){
    		$formok = false;
    		$errors[] = "You have not entered a name";
        
    
    	//validate email address is not empty
    	if(empty($email)){
    		$formok = false;
    		$errors[] = "You have not entered an email address";
        }
    	//validate email address is valid
    	}elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    		$formok = false;
    		$errors[] = "You have not entered a valid email address";
    	}
    	
    	//validate message is not empty
    	if(empty($message)){
    		$formok = false;
    		$errors[] = "You have not entered a message";
    	}
    	//validate message is greater than 20 characters
    	elseif(strlen($message) < 20){
    		$formok = false;
    		$errors[] = "Your message must be greater than 20 characters";
    	}
    	
    	//send email if all is ok
    	if($formok){
    
            ini_set("sendmail_from","http://localhost:36923/");
            
    
    
    		$headers = "From: http://localhost:36923/" . "\r\n";
    		$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    		
    		$emailbody = "<p>You have recieved a new message from the enquiries form on your website.</p>
    					  <p><strong>Name: </strong> {$name} </p>
    					  <p><strong>Email Address: </strong> {$email} </p>
    					  <p><strong>Telephone: </strong> {$telephone} </p>
    					  <p><strong>Enquiry: </strong> {$enquiry} </p>
    					  <p><strong>Message: </strong> {$message} </p>
    					  <p>This message was sent from the IP Address: {$ipaddress} on {$date} at {$time}</p>";
    		
    		mail("kid5er@yahoo.com","New Enquiry",$emailbody,$headers);
    		
    	}
    	
    	//what we need to return back to our form
    	$returndata = array(
    		'posted_form_data' => array(
    			'name' => $name,
    			'email' => $email,
    			'telephone' => $telephone,
    			'enquiry' => $enquiry,
    			'message' => $message
    		),
    		'form_ok' => $formok,
    		'errors' => $errors
    	);
    		
    	
    	//if this is not an ajax request
    	if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest'){
    		//set session variables
    		session_start();
    		$_SESSION['cf_returndata'] = $returndata;
    		
    		//redirect back to form
    		header('location: ' . $_SERVER['HTTP_REFERER']);
    	}
    }

  9. #9
    Join Date
    Feb 2014
    Location
    England
    Posts
    52
    You set the new variable to $nameclean but then you carry on using $name. After you have done the filter_var you need to use the new variable.

    You could just do $name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);

  10. #10
    Join Date
    Feb 2014
    Location
    England
    Posts
    52
    PHP Code:
        //form data
        
    $name=  filter_var($_POST['name'], FILTER_SANITIZE_STRING);
        
    $email=  filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
        
    $telephone=  filter_var($_POST['telephone'], FILTER_SANITIZE_NUMBER_INT);
        
    $enquiry=  filter_var($_POST['enquiry'], FILTER_SANITIZE_STRING);
        
    $message =  filter_var($_POST['message'], FILTER_SANITIZE_STRING); 
    Note that the telephone number will only keep digits, plus and minus signs.

  11. #11
    Join Date
    Feb 2014
    Posts
    23
    I'm doing this to the T but for some reason its still not working for me, at first I changed all of the name variables to nameclean and then I reverted them back to just name and used the code you posted

    I even tried an if else statement that read that if the user submits anything in the name input field then the string gets sanitized, but also it was a no go.

  12. #12
    Join Date
    Feb 2014
    Posts
    23
    an if function not if else

  13. #13
    Join Date
    Feb 2014
    Location
    England
    Posts
    52
    var_dump($name) to see what is happening when you submit the data.

  14. #14
    Join Date
    Feb 2014
    Posts
    23
    okay, I var_dump($name) then echo it, and remove the php that redirects me back to my form so that i can see the result. and the output for the var_dump is exactly what i enter into input for the name part of my contact form, naturally. it says something like string(7) mike$*%& for example. its like the filter_var FILTER_SANITIZE_STRING doesn't even exist

  15. #15
    Join Date
    Feb 2014
    Posts
    23
    lol this is getting frustrating, its not likes complicated! it should be working

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles