phphtmlforms

Web form repeatedly resubmits itself after submission by Apple users


I have a .php file on the web which contains an html form. That form (in case it's relevant) calls the original .php file when a user presses "Submit". That is, the file is called newform.php and the form within that file looks like this:

<form method=POST action="newform.php" id="trythis">

...

<input type="submit" value="Submit"></p>

</form>

Mostly, this works fine. Occasionally, though, a user will leave the browser window open after submitting the form, which then re-submits itself anywhere from a few times a day to a few times a week until that window gets closed (so I get several duplicate submissions from the same user).

I have enough data to be sure of these things:

  1. This is not caused by users repeatedly hitting the submit button. It is also not caused by users refreshing the page. In many cases, the users are not even aware that they've left this window open until I contact them and ask them to close it.

  2. This happens **only** when the user is submitting from an Apple product (and leaving the window open).

  3. This only became a problem a few years ago (I can't remember exactly when), after many years in which the problem never occurred. The onset of the problem might or might not have coincided with my tweaking the code; this is another thing I can't remember.

  4. (Adding this because it's come up in comments and answers): After you hit submit, the php code checks to see if the form variables have been set, and if they have it displays a thank-you page instead of re-displaying the form. So the open browser windows that are re-submitting the form don't actually have the form displayed; they have the thank-you page displayed.

Question: What's causing this and how do I stop it?


Solution

  • Some web browsers (e.g. Apple's Safari) will keep the recently visited pages and will "re-open" them when the user re-runs the browser, so it may cause what you encounter: (form data re-submitted when user restarts his/her machine and runs the browser)

    Note: Safari generally reopens previous windows and tabs automatically after a restart, functioning as a convenience feature for users. This behavior helps users quickly resume their browsing session

    Usually this can be fixed in three ways:

    (A) Add a captcha (e.g. google recaptcha or conventional captcha)

    On the form data input page, adding the captcha will help to avoid robotic submission, and also on the target page it will not process the form submission unless it is handled by a human being, and also re-submission (say due to auto-reload of browser windows) will not be processed because the captcha data is no longer valid

    For google recaptcha setting up and example code, you may refer to:

    https://developers.google.com/recaptcha/intro

    (B) Adding a token (to avoid actions similar to Cross-Site Request Forgery (CSRF) attack), so change your form by adding:

    <?php $_SESSION['token'] = md5(uniqid(mt_rand(), true)); ?>
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?? '' ?>">
    

    (Make sure session_start(); is placed at the top of the page)

    So change your form to:

    <?php session_start(); ?>
    
    <form method=POST action="newform.php" id="trythis">
    
    <?php $_SESSION['token'] = md5(uniqid(mt_rand(), true)); ?>
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?? '' ?>">
    ...
    
    <input type="submit" value="Submit"></p>
    
    </form>
    
    

    and on the target page, add the following to the top:

    <?php session_start(); 
    $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);
    
    if (!$token || $token !== $_SESSION['token']) {
        // CSRF token mismatch, reject the request
                die('CSRF token validation failed.');
    } 
    

    By applying the above security token check, it effectively prevents CSRF attacks and also avoid the issues of form data resubmission because the token will not be the same next time the user restarts his/her machine / browser windows

    (C) Help the users to change the Safari's settings by disabling "Frequently Visited" Sites: Prevents sites from showing on the New Tab/Start Page.

    Mac: Safari > Settings > General (set "New windows/tabs open with" to "Empty Page" or Start Page with settings adjusted).

    iPhone/iPad: Settings > Safari > turn off "Frequently Visited Sites".