BackSlash
BackSlash

Reputation: 22243

How to prevent custom post request to the "action" page of a form

i'm making a form and i would like to make the submitting PHP page accessible only if the form was submitted, preventing custom requests to my PHP page.

This is my form.html:

<html>
    <head>
        <title>Name/Surname form</title>
    </head>
    <body>
        <form id="form1" method="POST" action="processData.php">
            Name: <input type="text" id="name" name="name"><br>
            Surname: <input type="text" id="surname" name="surname"><br>
            <input type="submit" value="Submit form">
        </form>
    </body>
</html>

and then my processData.php:

<?php
    if(!isset($_POST['name'],$_POST['surname'])) die;

    include ("config.php");

    //connect
    $mysqli = new mysqli($dbhost, $dbuser, $dbpassword, $dbname); //variables from config.php

    //check connection
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }


    if ($stmt = $mysqli->prepare("INSERT INTO name_surname_table (name, surname) values (?, ?)")) {

        //bind
        $stmt->bind_param('ss', $name, $surname);

        //set
        $name=$_POST['name'];
        $surname=$_POST['surname'];

        //execute
        $stmt->execute();

        //close
        $stmt->close();
        }
    else {
        //error
        printf("Prepared Statement Error: %s\n", $mysqli->error);
    }
?>

The problem is that if i do a custom post request without submitting the form in my previous page, the data is submitted to the db, that means that an automated program could just put whatever it wants in my db... How can i prevent this?

Thanks!

Upvotes: 3

Views: 1693

Answers (4)

IMSoP
IMSoP

Reputation: 97908

Fundamentally you cannot prevent a malicious client sending "incorrect" data to your server. It is up to you to detect that situation and handle error cases appropriately.

If only certain users should be able to submit data, then obviously you need some form of login system. Then you can trust any data from a logged in user, and reject everything else.

If you just want to know that the client loaded the form on the previous page, you can add a hidden field containing a "nonce" - a random string whose value you store somewhere on the server such as in the PHP session. If the nonce submitted doesn't match the expected value, reject the input. Note that this does not guarantee that the user interacted with the form in their browser, only that they downloaded it (since a program can still extract the nonce and stimulate submitting the form)

Upvotes: 1

soyuka
soyuka

Reputation: 9105

You have many options to prevent the robots from submitting your forms automatically :

  1. Use a Captcha or some easy calculation field (for example What gives 3 + 2 ?)

  2. With a token

  3. Make some check with $_REQUEST variables

A token can be done like this :

session_start();
//generate a unique string
$token = uniqid(rand(), true);
//Store the token
$_SESSION['token'] = $token;
//Store the token_time
$_SESSION['token_time'] = time();

Add an hidden input to your form :

<input type="hidden" name="token" id="token" value="<?php echo $token;?>"/>

And than before submitting the form to the database :

session_start();
//If token exists
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) && isset($_POST['token']))
{
    //If it's the same as the posted one
    if($_SESSION['token'] == $_POST['token'])
    {
        //For example 15 mins ago
        $old_time = time() - (15*60);
        //If token hasn't expired
        if($_SESSION['token_time'] >= $old_time)
        {
           //Do your queries here
        }
    }
}

Upvotes: 4

kavin
kavin

Reputation: 1684

You should make a token based authentication for your forms.

In the page where you display form, first set a session variable with a random code.

//generate this using whatever random code generation method you prefer.
$_SESSION["token"] = "your-random-code";

In your forum have a hidden field as below.

<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>">

In the submit handler php file, do a check like below.

if(isset($_POST['token']) && $_POST['token'] == $_SESSION['token'])

Upvotes: 0

Rob Cozzens
Rob Cozzens

Reputation: 136

You could have a hidden field in the form that contains a secret code that expires...

When you generate the form, you calculate the code by running a hash on the time or even just picking a random number. Then store that in your session and insert it in the form you send.

When you process the form submission, check to make sure the secret code is the same as what is stored in the session.

Upvotes: 0

Related Questions