5

Being a novice with PHP, I may not be taking the correct route with forms but this way works for me, up to a point. Below is an example of my setup/

I have a form at www.foo.com/add.php, which needs an admin to be logged in to the session. The form inserts data into a database. Once it is submitted, the actions is set to action="scripts/add.php" and then that is redirected using a PHP header function to www.foo.com/done.php.

What I want to know is, can you deny access to the script file directly, e.g. if you go to the script file in a web browser it could enter an empty row into the database or possibly cause some other security issues?

Blease
  • 1,380
  • 4
  • 38
  • 64
  • Personally, I authenticate at the start of every PHP script and treat all input as suspicious, validating as necessary before performing any actions. I tend to do this using an include that deals with my security - session vars etc. I also make sure my database connection script lives outside of web root level. – Darren Crabb Oct 18 '13 at 11:53
  • @DarrenCrabb Thank you for your advice, I now have added Guillaumes code into my include file for each form script, I also escape all inputs too. I do however have have `$db=mysqli_connect('localhost','user','pass','db');` in my included file, is this a big issue in your opinion? – Blease Oct 18 '13 at 11:58

4 Answers4

7

If the form is submitted using POST method (with attribute method="post" in <form>), you can still execute your script only on POST requests, by adding this at the top:

 if ($_SERVER['REQUEST_METHOD'] != 'POST') {
   exit;
 }
Guillaume Poussel
  • 9,572
  • 2
  • 33
  • 42
  • I presume this would also work if the script was accessed with AJAX using the POST method? – Blease Oct 18 '13 at 11:53
  • Yes, it will only allow POST requests, using AJAX or not. – Guillaume Poussel Oct 18 '13 at 11:55
  • 1
    I think this answer is not correct. Just validating for the request being a POST request only prevents an accidental visit by directly adressing the script in the browser adress bar. But if somebody requests your script with the appropiate tool (e.g. curl) he can still add empty entries to your DB. The correct answer is the one from @Patrick Shafer and the suggestion from Darren Crabb: Careful input validation and authorisation. – korius Oct 18 '13 at 14:27
4

There are a few options available to you:

  1. Validate the form post data before inserting into the database
  2. Include a nonce or other generated value that is only present in the form prior to submission

The problem you're trying to solve really sounds like you want to prohibit blank records from being inserted into the database- not necessarily that you want to prevent access to add.php. This is where option #1 comes into play.

In your current add.php, it sounds like there needs to be some input validation. Basically, you'd check the values that are received by the script to make sure they exist. For example, if add.php accepts a first name, as part of a phonebook app, you'd have code similar to the below:

$firstName = '';
if(isset($_GET['firstName']))
    $firstName = $isset($_GET['firstName']);
// ...
if(trim($firstName) == '')
    //do something to handle an error, either set an error flag or die() with an appropriate message

This is a basic example of input validation, PHP has a validation library you may want to become familiar with: http://www.php.net/manual/en/intro.filter.php

With this input validation in place, someone can navigate to add.php and should receive an error. It will also detect if someone submits a blank form as well.

#2 requires that your form receive a unique value when it's generated called a nonce. The nonce is a unique value that's specific to that instance of the form. The subsequent call to add.php will only accept the request if the nonce is valid. An approach might be to store the nonce in the user's session.

Another note outside the scope of the question, since you're inserting data into a database, you should make sure you have proper escaping of inserted data. If you're using MySQL, see here: http://www.php.net/manual/en/mysqli.real-escape-string.php. If using another database engine, you'll want to lookup the specific library to see how to escape the string.

Patrick Shafer
  • 996
  • 1
  • 6
  • 9
  • 1
    U think you missed the point of the original question completely. – crafter Oct 18 '13 at 12:09
  • Thank you for your advice, I have added the isset condition now (I usually do include it?). Any how, I just wanted a way to prevent access to the files directly which I have figure out! I did appreciate the extras you included like the escaping (Which I do use also). +1 for the helpful advice to novices like myself – Blease Oct 18 '13 at 12:11
0

Yuu can try this to check whether request send by post or not

if(isset($_POST)){
continue.......
}
Praveen D
  • 2,337
  • 2
  • 31
  • 43
0

in order to secure such pages i have applied the code below.

Except request method, it also checks that the request comes only from specific domain.

$live_site_regex = '/http:\/\/(w{3}|w*).?yourdomain.ext/';
if($_POST && preg_match($live_site_regex,$_SERVER['HTTP_REFERER']) == 1){
//everything is ok
}
fatsouls32
  • 109
  • 1
  • 4