Jump to content

Recommended Posts

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 )

 

Link to comment
https://forums.phpfreaks.com/topic/96163-solved-contact-form-injections/
Share on other sites

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));
}

?>

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.

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.

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

?>

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.