0

I'm developing a php emailer that uses a form which needs to redirect to a "thank you" page that I don't have access to for the purpose of adding code. User input is sent through some simple preg_match functions to make sure it matches the necessary format. If it fails one of these functions, a javascript popup is echoed letting the user know what they need to change. If it makes it through, the data is stored in SESSION variables, and passed to a page where the data is added to the necessary html, and sent as a simple html email. The process.php page then redirects to results.php which clears out the session, and takes the user to the "thank you" page.

My problem is that when the user enters bad data then corrects it and submits, pressing the 'back' button after arriving at the "thank you" page gets me one of these "confirm form resubmit" pages before it goes back to the form. Once it actually gets back to the form after hitting 'back' a second time, the old, bad data is in the form in place of the good stuff. I would like to fix it so the "confirm form resubmit" page never appears, and the user is returned to a blank form if they hit the back button only once. My html:

            <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
            <table id="form_table" style="280px; border:0px; padding: 0 0 5px 0; border-spacing: 0px;">
                <tr>
                    <td>
                        <span style="font-size: 12px;">*First name</span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <input style="padding: 5px; font-size: 12px;" name="firstName" type="text" size="50" value="<?php if(isset($_POST['firstName'])) { echo htmlentities($_POST['firstName']); }?>" />
                    </td>
                </tr>
                <tr>
                    <td style="padding-top: 7px;">
                        <span style="font-size: 12px;">*Last name</span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <input style="padding: 5px; font-size: 12px;" name="lastName" type="text" size="50" value="<?php if(isset($_POST['lastName'])) { echo htmlentities($_POST['lastName']); }?>" />
                    </td>
                </tr>
                <tr>
                    <td style="padding-top: 7px;">
                        <span style="font-size: 12px;">*Email</span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <input style="padding: 5px; font-size: 12px;" name="emailAddy" type="text" size="50" value="<?php if(isset($_POST['emailAddy'])) { echo htmlentities($_POST['emailAddy']); }?>" />
                    </td>
                </tr>
                <tr>
                    <td style="padding-top: 7px;">
                        <span style="font-size: 12px;">Phone number</span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <input style="padding: 5px; font-size: 12px;" name="phoneNumber" type="text" size="50" value="<?php if(isset($_POST['phoneNumber'])) { echo htmlentities($_POST['phoneNumber']); }?>" />
                    </td>
                </tr>
                <tr>
                    <td style="padding-top: 15px;">
                        <span style="font-size: 12px;">Tell us how we can help</span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <input style="padding: 5px 5px 15px 5px; font-size: 12px;" name="howHelp" type="text" size="50" value="<?php if(isset($_POST['howHelp'])) { echo htmlentities($_POST['howHelp']); } ?>" />
                    </td>
                </tr>
            </table>
            <div style="width: inherit;">
                <input type="image"  id="saveform" src="http://www.fivemm.com/client/tristar/images/consult-btn.jpg" alt="Submit Question!" style="width: 100%; height: 96px; border: none;" />
            </div>
            <?php echo $msg_to_user ?>
        </form>

The processing code, located on the bottom of the same page:

<?php

if(isset($_POST['firstName'])) {

function died($error) {
    $error = 'So sorry, but it looks like there are some issues with your form.\\n\\n'.$error;
    echo '<script type="text/javascript"> alert("'.$error.'")</script>';
    die();
}

$error_message = "";
$email_exp = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
$string_exp = "/^[A-Za-z .'-]+$/";
$msg_exp = "/^$|^[A-Za-z ?!.'-:]+$/";

if(!preg_match($string_exp,$_POST['firstName'])) {
    $error_message .= 'The first name you entered contains invalid characters or is blank.\\n\\n';
}

if(!preg_match($string_exp,$_POST['lastName']) && strlen($_POST['lastName']) > 0) {
    $error_message .= 'The last name you entered contains invalid characters.\\n\\n';
}

if(!preg_match($email_exp,$_POST['emailAddy'])) {
    $error_message .= 'The email address you entered does not appear to be valid or is blank.\\n\\n';
}

if(strlen($error_message) > 0) {
    died($error_message);
}

function clean_string($string) {
    $bad = array("content-type","bcc:","to:","cc:","href");
    return str_replace($bad,"",$string);
}

$_SESSION['firstName'] = $_POST['firstName']; // required
$_SESSION['lastName'] = $_POST['lastName']; // required
$_SESSION['emailAddy'] = $_POST['emailAddy']; // required
$_SESSION['phoneNumber'] = htmlspecialchars(clean_string($_POST['phoneNumber'])); //  required
$_SESSION['howHelp'] = clean_string($_POST['howHelp']);

echo ("<SCRIPT LANGUAGE='JavaScript'>window.location.href='process.php';</SCRIPT>");
}
?>

The process.php page:

<?php
session_start();
if(isset($_SESSION['firstName']) && isset($_SESSION['page1'])) {
    $_SESSION['page2']="2";
    $first_name = $_SESSION['firstName'];
    $last_name = $_SESSION['lastName'];
    $email_addy = $_SESSION['emailAddy'];
    $phone_number = $_SESSION['phoneNumber'];
    $how_help = $_SESSION['howHelp'];

    // EDIT THESE 2 LINES BELOW AS REQUIRED
    $email_to = 'someguy@domainname.com'; // use for testing
    $email_subject = "This Guy Wants To Contact You!"; // Enter intended message here

    $email_message = '<html>';
    $email_message .= '<head>';
    $email_message .= '</head>';
    $email_message .= '<body>';
    $email_message .= '<h3>You have a new email message!</h3>';
    $email_message .= '<table>';
    $email_message .= '<tr><td>Name</td><td>'.$first_name.' '.$last_name.'</td></tr>';
    $email_message .= '<tr><td>Email Address</td><td>'.$email_addy.'</td></tr>';
    $email_message .= '<tr><td>Phone Number</td><td>'.$phone_number.'</td></tr>';
    $email_message .= '<tr><td>How can we help?</td><td>'.$how_help.'</td></tr>';
    $email_message .= '</table>';
    $email_message .= '</body>';
    $email_message .= '</html>';

    // create email headers

    $headers = "From: ".$first_name." \r\n";
    $headers .= "Bcc: otherguy@otherdomain.com, otherdude@yetanotherdomain.com\r\n";
    $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
    $headers .= "\r\n";

//      $headers .= 'X-Mailer: PHP/' . phpversion();
    @mail($email_to, $email_subject, $email_message, $headers);
    header('Location: results.php');
}
?>

And finally, the results.php page:

<?php 
session_start();
    if (isset($_SESSION['page2']))
    {
        session_destroy();
        header('Location: http://www.domainname.com/thank-you/');
    }
    else
    {
        header('Location: index.php');
    }
?>
MarvinLazer
  • 198
  • 2
  • 5
  • 16
  • You could try: if ( window.history.replaceState ) { window.history.replaceState( null, null, window.location.href ); } at top of the page you're getting the popup on – James Osguthorpe Mar 24 '21 at 00:58

2 Answers2

0

Well, I must admit, the code is a bit strange. As I can see, you have a PHP part in the form page, which test the value from the form. That's it? I suggest to perform the Rexp in Javascript. Using this you will have a cleaner code: one form with JS for test, submit to process page. In process page, if you want, you can perform another test, and in case of faillure, fill the session and go back to the form (in that case you will have to read the session).

Maybe the confirm before resubmit came from the fact the page is self-called.

Regards Peter

Peter
  • 1,247
  • 19
  • 33
  • I use php to test values from forms because someone told me it's easy for malicious users to screw with javascript-tested form inputs by just turning javascript off in their browsers. Are there any other disadvantages to the way my code is structured? – MarvinLazer Oct 03 '14 at 20:44
  • I think there are two points of view. The first is the one from the "basic and cool guys" so the one who just want to use your site. The second one is the "bad guys". The main problem is that struggling against the hypotetical "bad guys" must not create problem for the "cool one". In fact, you must have JS test in order to help the "cool guy" immediatly (so alert box before submiting) so avoiding him submitting bad data. If, in that case, someone is submitting bad datas, this mean he is probably one of the "bad guys". So just refuse the data, go back to the previous empty page and that's all. – Peter Oct 06 '14 at 16:34
0

Short: you can't turn it off.

Long: You should move the processing of form to the beginning.

At first you check if form was submitted and if so you process the data. On the other hand, when form was not submitted, you just show the form.

The idea here is that when you find errors on processing the data, you can display the error message and also show the form again. The good part here is that now you can fill the parts of form that are correct with the $_POST values you got.

Something like this:

    ...
    <input type="text" name="username" value="<?php echo $_POST["username"]?>" />
    ... 

Now the user just fills the ones that had errors and resubmits. If it passes you proceed with your email part.

Note that you should sanitize the $_POST array before you use it. ( look: stripslashes, trim, htmlspecialchars )

Hope I made myself clear :)


Sorry, it's late, so I made an example of what i meant: sample php code

Paperclip
  • 615
  • 5
  • 14