2

I have a website that has 2 .php files in it. One is user.php & two is success.php.

In the user.php, I have an HTML form with textarea and an input submit button. The action of the form is success.php (Demo of the user.php: jsfiddle.net/SS33s)

And here is the success.php code: jsfiddle.net/bL2u5/

What I need is a PHP code to put inside the success.php page to NOT allow forms that were submitted from any other website EXCEPT my website (Mywebsite.com) and to show something like: "There was an error completing your request, please go to mywebsite.com." for the people who submitted the form on OTHER websites than mine.

The thing is that Google Analytics has tracked some people that have an HTML form that has the action="http://mywebsite.com/success.php", which I don't want that, I want MY users to only access the success.php page.

Please excuse my English. English is not my first language and I am trying to explain my problem as clear as possible. Thank you :)

user3213765
  • 87
  • 1
  • 1
  • 8

3 Answers3

1

Read about Cross-site request forgery CSRF

Try this: https://www.owasp.org/index.php/PHP_CSRF_Guard

smg628
  • 179
  • 1
  • 5
1

add this code in the top of your php page:

if ($_SERVER['HTTP_REFERER']!="http://localhost/user.php"){ //replace with the past url
    die();
}
else{
//the code to execute
}

if you want check this out CSRF (Cross-site request forgery) attack example and prevention in PHP

Community
  • 1
  • 1
MAXIMIX
  • 42
  • 4
  • Hey @MAXIMIX, I have added the code to the top of the page of success.php and then I went to one of the websites (NOT MY WEBSITE) that uses their action for http://mywebsite.com/success.php and when I click the 'Submit' button, it shows a blank page. The problem is when I visit MY website page (mywebsite.com/user.php) and click the 'Submit' button it shows a blank page as well :( Any idea what should I do? Thanks – user3213765 Feb 12 '14 at 00:20
  • Hey @user3213765 to impove the code we sould replace our code with this one: ` ` so we can define correctly the url the isset function is added to prevent an error comming from an empty hhtp request header – MAXIMIX Feb 12 '14 at 00:29
1

Well, a good server should prevent _POST attacks automatically, at least mine does. However, server cannot detect userscript attacks.

So there is a little trick for that. This trick also makes spiderbots life a little harder, because form data is different and has to be manually copied from the source.

This solution works with $_SESSION (read more).

This is the class.form_session.php example:

<?

// First we have to start the sessions all together
session_start();

// This wraps the functions neetly into a class
class FormSession {
    // This function creates the form session
    function create_form_session () {
        $hash = md5('SomeRandomStringToMakeTheHashImpossible' . time());
        return $_SESSION['form_session'] = $hash;
    }

    // This form simply returns the current form session
    function current_form_session () {
        return $_SESSION['form_session'];
    }

    // This function kills/deletes/unsets the form session
    function destroy_form_session () {
        unset($_SESSION['form_session']);
    }
}

// Lets start the class and make it usable
$fs = new FormSession;

This is the user.php example:

<?

// Include START - If you are gonna use this trick cross-server, include this part to the top of each file (that use this method ofc)
require('class.form_session.php');
// Include END


// Lets create a new form session
$form_session = $fs->create_form_session();

// Lets generate a very simple form
print '<form method="post" action="test2.php">
    <input type="text" name="' . $form_session . '_username" value="" placeholder="Username" /><br />
    <input type="password" name="' . $form_session . '_password" value="" placeholder="Password" /><br />
    <input type="submit" name="' . $form_session . '_submittrigger" value="Submit this!" />
</form>';

This is the success.php example:

<?

// Include START - If you are gonna use this trick cross-server, include this part to the top of each file (that use this method ofc)
require('class.form_session.php');
// Include END


// This catches the submit, this could also be in another file
if ($_POST[$fs->current_form_session() . '_submittrigger']) {
    // Success!
    echo '<pre>'; print_r($_POST); echo '</pre>';
    // Now lets delete the session
    $fs->destroy_form_session();
}

As you can see, this works in one file. Which is the way I personally like the submits to be, however if you include the top session related part to your success.php, then it should work fine.

Kalle H. Väravas
  • 3,579
  • 4
  • 30
  • 47
  • Do I have to put it in success.php or user.php? Thanks – user3213765 Feb 11 '14 at 23:25
  • 1
    I edited it, so you can see the files separately. Tested it, works good. I will do some security tests later too. But its highly unlikely that nobody will hack into your _POST action with this method in use. Also this helps a little with automatic spambots. – Kalle H. Väravas Feb 11 '14 at 23:29
  • Hey @Kalle H. Väravas, I have tried to add the code that "MAXIMIX" gave me in his answer and it worked just like I wanted to :) Do you think people can STILL hack into the _POST of success.php with the code that MAXIMIX gave me in his answer? And thanks a lot for your time :) – user3213765 Feb 11 '14 at 23:39
  • 1
    So I added a class around it, so you can save some space in your code :) So basically, add `require('class.form_session.php');` to your files, where you are going to use the form-related-activities. And you can see the usage in the others files examples. However, this will make a conflict between multiple usages. So if you have 2 forms, with the same class, then the hash should be different. Let me know, if you are going to use it for multiple forms. – Kalle H. Väravas Feb 11 '14 at 23:39
  • Yes I do use it on 2 forms in 1 page (user.php) but the input is ALWAYS different, users always submit a different ID every time they use the form :) – user3213765 Feb 11 '14 at 23:43
  • 1
    Well, his answer has a point of course. That will basically disallow outside sents from other servers. However, in practice with normal virtual hosting services, this is not that easy anyways. But of course that depends on the servers configuration. However, as this is PHP, then you can still send requests via userscript, meaning javascript. Mozilla has all the tools built in, that I could send AJAX _POST calls to your server. With my solution, you have to always go and manually copy the SESSION. If you want to prevent these, use both solutions at the same time :) – Kalle H. Väravas Feb 11 '14 at 23:44
  • If you have two forms on the same page, then it doesn't matter, but since the session is generated always, when you open that page.. then multiple pages on your site will always overwrite the current session-hash. Check @smg628 answer as well, that's basically same trick, but with much more details. – Kalle H. Väravas Feb 11 '14 at 23:48
  • Thank you very much for your answer and comments. I really appreciate the answers on my question. Thanks everyone :) – user3213765 Feb 11 '14 at 23:51
  • Hey Kalle, I have added the code (that MAXIMIX gave me) to the top of the page of success.php and then I went to one of the websites (NOT MY WEBSITE) that uses their action for mywebsite.com/success.php and when I click the 'Submit' button, it shows a blank page. The problem is when I visit MY website page (mywebsite.com/user.php) and click the 'Submit' button it shows a blank page as well :( Any idea what should I do? Thanks – user3213765 Feb 12 '14 at 00:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47276/discussion-between-kalle-h-varavas-and-user3213765) – Kalle H. Väravas Feb 12 '14 at 00:27