0

I have entered the following code to prevent CSRF but issuing and checking tokens. The top section goes on the login.php, the second part goes on the landing page. The issuing of the token works, and when I print $_SESSION['token']on the landing page they match up. However, when i substitute the other code in, its says that they don't match and shows 'expired'.

<?php session_start(); $_SESSION['token'] = $token; $_SESSION['token'] = uniqid(md5(microtime()), true); print $_SESSION['token']; ?> <html> <head> <title>My first PHP website</title> </head> <body> <h2>Please login here to see your tour</h2> <form action= "checklogin.php" method="post"> Enter Username: <input type="text" name="username" required="required"/> <br/> Enter Password: <input type="password" name="password" required="required" /> <br/> <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" /> <input type="submit" value= "login" /> </form> </body> 

<?php session_start(); print $_SESSION['token']; session_start(); if ($_POST['token'] !== $_SESSION['token']) { die('expired'); } ?> 
15
  • 2
    You're using $_GET['token'] but your form uses the POST method so you should use $_POST['token'] instead, i.e. if ($_POST['token'] !== $_SESSION['token']) Commented Apr 30, 2015 at 11:34
  • @mrun Thanks for that suggestion, i tried that but it didn't work. I have therefore altered my post. Commented Apr 30, 2015 at 11:46
  • Why two session_start(); lines in your second (validating) file? Commented Apr 30, 2015 at 11:54
  • @MarkBaker They are on two different php files, the top one is on login.php and the bottom one is my destination file. Commented Apr 30, 2015 at 12:06
  • 1
    @Rus84 I just tested your code and it's working for me. I don't see a submit button in your form. Are you sure you're submitting it? Try to print $_POST['token'] in login.php. Commented Apr 30, 2015 at 12:12

2 Answers 2

1

Following our discussion in the comments of your question I'm posting this answer so the information is summarized.

Your code is basically correct but the issue you're having is because after the redirect to the user's unique landing page you no longer can access the data in $_POST you originally have in your checklogin.php, i.e. after submitting the login form.

So in your checklogin.php script you have among others these options:

  1. Include the token in the URL you're redirecting to and then check the $_SESSION['token'] against $_GET['token'].

  2. Set a flag in the $_SESSION indicating that the use has been allowed access to the system. Something like $_SESSION['loggedIn'] = true; (that's what I would recommend)

NOTE: Here you are facing another issue: you have to think about restricting access of each user to only their own page. Imagine that if a user somehow knows the URL of another user's home page they could easily edit the URL and reach it. My recommendation is to save the user's id in the $_SESSION and then at the top of each user's home page to check whether the currently logged in user is allowed to open the said page.

I hope that makes it more clear!

Sign up to request clarification or add additional context in comments.

4 Comments

yes that summary is correct. The note section is exactly right and that is one of my main concerns regarding security. I am new to php, and learning on the job through trial and error (so to speak). The username, password, page_ID, is all saved in a MYSQL database. will the Id sessions be stored in the checklogin.php? Then on the top of file1.php file2.php etc you will check to make sure that the right user has accessed the file? Thanks
Yes, exactly. You would save the user id in $_SESSION inside checklogin.php and then check in each file whether the user is allowed to access the file. Btw there are a lot more better ways of doing this but since that's the way you have chosen to build your app than that's one of the ways to go. Imagine for a second how many checks you will have to write... in every single file. And then if you decide to add another criteria whether or not the user can access the file? Right! You'll have to change all the files! So you should probably think of a way to improve this part of your app :-)
I was wondering if you could help me with the point number two that you recommended above, setting a flag. How would you set something up in the final php file to show that they are able to view the page? Any bits of code that you can suggest is much appreciated. Thanks.
Sorry but I was away a couple of days, I'll try to suggest some help later today or tomorrow
1

The form action is login.php so when a user logs in the POST data is submitted to the login.php page. Your question does not explain how the user then gets directed to their landing page.

One option would be to try the following.

Replace:

<form action="login.php" method="post"> 

With:

<form action="landingpage.php" method="post"> 

That way on your landing page you will be able to get the value of

$_POST['token'] 

4 Comments

yes you are right. The difficulties are arising as I'm using a redirect on the checklogin. So once they login they go to the checklogin.php, their username and password is compared against what is stored in the database. They are then sent to their own unique page depending on their userID. I am therefore assuming that i need to check that the tokens match up on that page as well as the final php file?
If I understand correctly you would just need to make sure the tokens match on logincheck.php only.
I want to check that the tokens match firstly on checklogin.php and then to their redirected location file1.php.
Why check the token again? It is really only necessary to check the token on form submit I think. Look at this for more info on how CSRF tokens work: stackoverflow.com/questions/5207160/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.