soycharliente Posted March 14, 2008 Share Posted March 14, 2008 I'm trying to break my contact form. I'm trying to figure out what people could type in so that it creates a problem when processing the code. They only problem I've come across so far that breaks the form is when you type things in quotes. 1. When you type things in double quotes, it fails for the email address, though I've heard having double quotes in your address are valid, and none of the other fields except that message is reposted. 2. When you type things in single quotes, it fails for the email address, don't know if it's valid either way, and all of it is reposted. I know this is kind of weird/confusing. Can anyone offer any suggestions why it doesn't repost when using double quotes? I want it to still repost what they typed even if something fails the conditions. Relevant code (hopefully): <?php if (isset($_POST['Submit']) && $_POST['Submit'] == "Submit") { foreach ($_POST as $key => $val) { $_POST[$key] = stripslashes($val); } $to = "address@domain.tld"; // send the form here $name = $_POST['Name']; $email = $_POST['Email']; $subject = $_POST['Subject']; $message = $_POST['Message']; $message_length = strlen($message); $errors .= (empty($name)) ? "<br /><span class=\"error\">You have to type your name. Who are you?</span>" : FALSE; $errors .= (empty($email)||!preg_match("/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*(([,]|[,])\s*\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)*$/", $email)) ? "<br /><span class=\"error\">You have to type your email address so I can reply if I need to. Make sure you didn't try to cheat and make up one.</span>" : FALSE; $errors .= (empty($subject)) ? "<br /><span class=\"error\">You have to type a subject. What is your message about?</span>" : FALSE; $errors .= (empty($message)||$message_length>255) ? "<br /><span class=\"error\">You have to type your message. Make sure you use less than 255 characters. You are currently using $message_length.</span>" : FALSE; if (!$errors) { $msg = "Name: $name\nEmail: $email\nMessage: $message"; $headers .= "From: " . $name . "<" . $email . ">\r\n"; $subject = "CH[DOT]COM - ".$subject; ini_set(sendmail_from, $email); $bool = mail($to, $subject, $msg, $headers); ini_restore(sendmail_from); if ($bool) { header("Location: /contact/thankyou.php"); exit(); } else { die("Something happened that wasn't supposed to. Please send an email to address@domain.tld and tell me that you got this message."); } } } ?> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> <?php echo ($errors) ? "<p>All fields are required. Max length on all fields is 255 characters. $error</p>" : "<p>All fields are required. Max length on all fields is 255 characters.</p>"; ?> <label for="Name" id="Name">Name:</label> <input type="text" name="Name" value="<?php echo ($errors) ? $name : ""; ?>" maxlength="255" /> <label for="Email" id="Email">Email:</label> <input type="text" name="Email" value="<?php echo ($errors) ? $email : ""; ?>" maxlength="255" /> <label for="Subject" id="Subject">Subject:</label> <input type="text" name="Subject" value="<?php echo ($errors) ? $subject : ""; ?>" maxlength="255" /> <label for="Message" id="Message">Message:</label> <textarea name="Message" rows="20" cols="20"><?php echo ($errors) ? $message : ""; ?></textarea> <div class="clear"></div> <label for="Buttons" id="Buttons">Done?</label> <input class="submit-button" type="submit" name="Submit" value="Submit" /> <input class="reset-button" type="reset" name="Reset" value="Reset" /> </form> I printed the $_POST array. Here's a sample output: Array ( [Name] => "Charlie Holder" => 'me'@charlieholder.com [subject] => 'Hi!' [Message] => "Hello World!" [submit] => Submit ) Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/ Share on other sites More sharing options...
Psycho Posted March 14, 2008 Share Posted March 14, 2008 If you want to get VERY technical you can have just about ANY character in an email address. There is an extended standard that allows for many more characters than is in standard use. However, the extended standard is not fully supported by current email systems. Also, I have yet to see anyone using an email address using the extended format. After much research I created the following validation for email addresses (which does NOT include quote marks). It includes two parts: one to determine that the correct characters are inlcuded in each part of the email address and a second test to check for max lengths. <?php function validEmail($email) { $emailFormatTest = '/^[-\w+]+(?:\.[-\w+])*@[a-z\d]{2,}(?:[-.][a-z\d]{2,})*\.[a-z]{2,4}$/i'; $emailLengthTest = '/^(.{1,64})@(.{4,255})$/'; return (preg_match($formatTest, $email) && preg_match($lengthTest, $email)); } ?> Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492284 Share on other sites More sharing options...
soycharliente Posted March 14, 2008 Author Share Posted March 14, 2008 Thank you for the information, but I don't quite see how that applies to the problem I'm having. Maybe I didn't quite explain it correctly. The problem is that when people DO type double quotes, which fail, it's not reposting the form fields that they filled in. Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492291 Share on other sites More sharing options...
Psycho Posted March 14, 2008 Share Posted March 14, 2008 Check the HTML source - I bet the value is there. The problem, I think, is that if there is a double quote in the email input then that quote is being interpreted by the HTML as ending the value. Example: <?php $userinput = ' "myemail address" '; ?> <input type="text" name="Email" value="<?php echo ($errors) ? $email : ""; ?>" /> This is what would be output to the browser: <input type="text" name="Email" value=" "myemail address" " /> Either escape the quotes before populating the value field or strip them out. Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492316 Share on other sites More sharing options...
BlueSkyIS Posted March 14, 2008 Share Posted March 14, 2008 yes, watch for quotes in output to form fields. check out htmlspecialchars() for output to form fields. Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492319 Share on other sites More sharing options...
soycharliente Posted March 14, 2008 Author Share Posted March 14, 2008 Wow. I've told people about htmlspecialchars like a million times. Thanks everyone. I feel like I should link you to it so you can use it now that you've helped so much lol Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492335 Share on other sites More sharing options...
Psycho Posted March 14, 2008 Share Posted March 14, 2008 Correction to Reply#1. I unintentionally picked up a modified function that I was testing with and that RegEx is not correct. Here is the correct function: <?php function is_email($email) { $formatTest = '/^[-\w+]+(\.?[-\w+])*@[-a-z\d]{2,}(\.?[-a-z\d]{2,})*\.[a-z]{2,6}$/i'; $lengthTest = '/^(.{1,64})@(.{4,255})$/'; return (preg_match($formatTest, $email) && preg_match($lengthTest, $email)); } // NOTES: // // Format test // - Username accepts: 'a-z', 'A-Z', '0-9', '_' (underscore), '-' (dash), '+' (plus), & '.' (period) // Note: cannot start or end with a period (and connot be in succession) // - Domain accepts: 'a-z', 'A-Z', '0-9', '-' (dash), & '.' (period) // Note: cannot start or end with a period (and connot be in succession) // - TLD accepts: 'a-z', 'A-Z', & '0-9' // // Length test // - Username: 1 to 64 characters // - Domain: 4 to 255 character ?> Quote Link to comment https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/#findComment-492520 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.