I know that $_SERVER["HTTP_REFERER"] can be easily faked through setting your host file on your computer. What is a better alternative?

I want a form to be submitted to itself, e.g.
formProcess.php

<?php
 if(isset($_POST["formButton"]))
 {
  doThis($_POST["formField1"], $_POST["formField2"]);
 }
?>
<html>
 <body>
  <form action="" method="POST">
   <input name="formField1">
   <input name="formField2">
  </form>
 </body>
</html>

I read somewhere that setting a session can be used as an alternative. Is this the right way to go?

<?php
 session_start();
 if(!isset($_POST["submit"]))
 {
  $_SESSION["on_the_right_page"] = TRUE;
 }
 if(isset($_POST["submit"]))
 {
  if($_SESSION["on_the_right_page"] == TRUE)
  {
   doThis($_POST["formField1"], $_POST["formField2"]);
  }
 }
?>
<html>
 <body>
  <form action="" method="POST">
   <input name="formField1">
   <input name="formField2">
  </form>
 </body>
</html>

Is that the best way to make sure that's right? Or can a user fake a $_SESSION too?

    lupus6x9 wrote:

    Or can a user fake a $_SESSION too?

    Nope.

      A session can be used if the user stays on one website. Sessions cannot be transferred from different domains since they are based on your browser passing a cookie to the server for each request. That also means shutting off cookies will prevent sessions from being able to track. Even with session ids appended to links (as PHP does when it detects cookies are turned off) are easy to manipulate.

      As you already pointed out, the browser sends the referrer so that is also in the end users control if they choose to mess with it. Easy to temper with all these things where http is a stateless protocol.

      I suppose I would suggest doing what they do for obscuring passwords when you don't have SSL. That is, you make javascript render some random salt and hash that with a server side random value (pass it to the javascript on page load.) You only post the hash and salt to the form handler (same page in this instance) and then you take the salt from the form and the server side random value (that you stored in a database perhaps) and hash those. Now you can compare the hash with the hash you got from the form. This will go along way to almost ensure that the form was submitted by a real user.

      Cheers!

        lupus6x9 wrote:

        If sessions cannot be faked, then why do some professional scripts make session ID's (I assume they do: on most admin CP pages, there's something like "http://site.com/admin/?sid=abc123def456").

        Because they don't know better.

        You can hijack a session, but you can't fake one (i.e. insert your own data). It's even easier to hijack a session when the session ID is in the URL.

          Isn't the session ID passed in the HTTP headers anyway?

            Kudose wrote:

            Because they don't know better.

            You can hijack a session, but you can't fake one (i.e. insert your own data). It's even easier to hijack a session when the session ID is in the URL.

            Sorry, I hope this isn't spam, but I just want to be sure I fully understand this.

            if($_SESSION["is_logged_in"] == TRUE) {

            The above statement is completely secure? There is NO possible way someone fake that at all?

            I also was unfamiliar with session hijacking, so I read off of this site about how to sort of prevent that. It sounds like a good idea to me.

              dougal85 wrote:

              Isn't the session ID passed in the HTTP headers anyway?

              Yes.

              lupus6x9 wrote:

              The above statement is completely secure? There is NO possible way someone fake that at all?

              No. I can take a session ID from one computer and paste it into the address bar of another and get the same content ... session hijacking.

                But sessions shouldn't be read from the browser URL.... If I go to script.php?s=123

                and the script.php source code is:

                <?php session_start(); if($_SESSION["s"] == "123") { echo "yay!"; } else { echo "nay"; } ?>

                I don't get "yay." The session isn't a GET variable unless you set it. ...Right?

                  lupus6x9 wrote:

                  But sessions shouldn't be read from the browser URL.... If I go to script.php?s=123

                  and the script.php source code is:

                  <?php session_start(); if($_SESSION["s"] == "123") { echo "yay!"; } else { echo "nay"; } ?>

                  I don't get "yay." The session isn't a GET variable unless you set it. ...Right?

                  You're thinking of $GET. $SESSION variables can only (and should only) be set in your code.

                  Passing sessions explained.

                  OK, here's the deal, a PHP session (same for other languages/web servers too) is basically a random number that the server stores with server-side information and then sends a cookie to your browser. When your browser request additonal pages/images from your servers domain, it sends the cookie with the ID. I like to think of it as a safe combination. All the data iis stored in the "safe" (server) but you send the "combination" (session id) in your cookie with every subsequent request. Since the cookie is a temp cookie, when you close your browser the cookie is destroyed and the next time you request anything on the server, you get a new session.

                  And yes, you could initialize a session and set a variable when the form page loads and then check for that session variable when handling the form post. However, it's still very easy for a bot to hit your form and get a session cookie (just headers remember) and then just send that cookie in it's header when it does a post.

                  Okay, this is all based on my assumption that you want to make sure that a real human is using your form and that he or she is the same person and not a "man-in-the-middle." So what are your intentions with this script?

                    Write a Reply...