In light of my recent issue (PHP - Session lost/emptied on form post), the session ID almost by random regenerates itself upon a form being posted (login -> add item to basket OR add item to basket -> login), resulting in the session data being lost. A work around was brought to light that I could pass the session ID as a hidden input to force the session ID to maintain itself. Is this a practical fix? And would this open me up to any vulnerabilities?
Please note that my website is run on a shared server.
It doesn't affect the level of your security. The session ID is stored as a cookie on the user's browser and you propose saving it in the HTML source. Either way, the end user or a malicious entity using a network sniffer will be able to access this data. So you can use it if it makes your job easier.
I'll take a stab in the dark and guess that when you're submitting the form to a different subdomain, i.e. you're on http://www.example.com, and you're submitting to https://secure.example.com or the like.
If so, you need to make sure that the session cookie domain is set to use all subdomains of your website, not just your current one. You can check that with:
ini_get('session.cookie_domain');
// if this outputs something like "www.example.com" and you're submitting to
// "somethingelse.example.com", here's your problem.
If it's not set properly, you can set it either in php.ini or in your scripts:
ini_set('session.cookie_domain', '.example.com'); // or...
session_set_cookie_params(ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), '.example.com');
session_start();
... alternatively, you can just make sure that you're using the same subdomain when you submit the form as there's rarely a good reason to use a different one in this context.
Or your problem could be completely unrelated. Worth checking out in any case.
But, as #Kaustubh Karkare said, the security of passing session variables through your form is identical to passing them through cookies. And as for practicality, it's a perfectly reasonable, if not often used, way to pass session ids around.
Instead of posting it, go to your action page from your form and use this
<?php
//let's start the session
session_start();
$_SESSION['whateveryouwanttocallit'] = session_id()
?>
So basically don't post it at all....
You can check it by the following:
<?php print_r($_SESSION)?>
And can confirm it to: <?php echo session_id()?>
In answer to your question however, this is not a good work around.
By posting a session id to your session, you're just creating a duplicate of the information and naming it whatever you want, the session ID is already in your session.
Also, if you're intending to use your session ID in a hidden input as a form of cookie to ensure they information on that user isn't lost, the problems will be:
The session with this newly created session id will also get wiped.
Even if it stayed, the session id will have been regenerated and so be a different string.
Related
I am trying to create a website where a user logs in or creates a new account if they are not already a user. I have that working, but what I cannot seem to figure out is how to have PHP or HTML save the username through different pages. A user logs in, and then based on the specific user, my website will show different exercises the user has completed in the past, as well as allow the user to add more exercises in the future. My website uses PHP, HTML, and MySQL to search different tables in my database and output the results.
I have tried many different possible solutions, such as sessions in PHP like this, but it did not work. Each PHP page has this at the beginning:
session_start();
and then further down, I have:
$_SESSION["Username"] = $_POST['Username'];
I have also tried hidden input values in HTML, but that did not seem to work quite right either. Each HTML page has this:
<input type="hidden" name="Username" value="Cbartowski">
I have tried a lot of ways to try to have my web page save the username and use that data throughout my pages, but I haven't had any luck. Would sessions in PHP be the way to go? Or hidden input in HTML? Or something else entirely?
Any help would be greatly appreciated!
First of all, using hidden input to store the username is a critical threat to your website.
One can easily check out the username of the person by viewing the source code.
Using PHP sessions is the way to go here.
What i have understood is that you are initializing
$_SESSION["Username"] = $_POST["Username"];
on every page. Now, consider you have two php pages.
One is form-request-handler.php and other is display-user-preferences.php
Now, when user submits the form the username gets set into session variable using the above code snippet on form-request-handler.php page.
Now, when user hits the display-user-preferences.php page, you again set the value of session variable. But since, no post request has been made to this page so Null is get saved into session variable and you are not able to retrieve the required information from the database.
So, whichever php page is handling the post request just initialize your session variable there and use it on other pages.
Sessions variables will be available to you unless you call
session_destroy();
Hope, this helps :)
html hidden input is not a good way because users can see it with the browser show source action.
are u shure session file are saved and the session ID is include in your links ?
if not sessions start a new session each time the user click a link.
have a look in your temp folder each time your clicking a link; if a new session file is created it's because you forget the session ID.
maybe it's the problem.
Check your form method : Should be POST
Check your variable using:
var_dump($_POST['Username']);
So from experience, its better to use post methods when doing user authentication. Purely for security reasons. In addition to this, using PHP's session variables is also the recommended way of passing user information from one page to another.
if you want to store the user name in the session variable, here are some steps you can follow
start the session using session_start();
name the session variable and store the information you want
$_SESSION['what-ever-you-want-to-call-it']=$what-you want to store
eg.$_SESSION['Username']=$_POST['Username']. Note the use of single quotes
You can now call $_SESSION['Username'] anywhere in a php script provide the session has been started before calling it. That is session_start();.
Note break apart the code your working on and ensure each individual piece works. eg,is the post providing you with the username??
I am beginning to learn php. I have a question regarding sessions.
Right now, I know that session_start() creates a session variable.
What I don't know is, when I access the session I created, do I need to use session_start() again?
If yes...
Why is this? Because I already created a session and I wonder why it wouldn't last the entire browsing session.
because what i understand from it is, that it is going to create a new session.
No:
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
http://php.net/session_start
Each new page you visit is an entirely new context for PHP. session_start allows you to reestablish a previous context/session/data.
The session_start function tells PHP to enable session tracking. It doesn't wipe out the session created by a previous page. You must call session_start() before you'll have access to any variables in $_SESSION.
Because of the manual session_start()
session_start — Start new or resume existing session
the same way you would connect to database every time you want to use it. it will connect to however you're storing your sessions. The session variables are no wiped out.
Also read more here but this should help to understand how sessions work:
When you are working with an application, you open it, do some changes
and then you close it. This is much like a Session. The computer knows
who you are. It knows when you start the application and when you end.
But on the internet there is one problem: the web server does not know
who you are and what you do because the HTTP address doesn't maintain
state.
A PHP session solves this problem by allowing you to store user
information on the server for later use (i.e. username, shopping
items, etc). However, session information is temporary and will be
deleted after the user has left the website. If you need a permanent
storage you may want to store the data in a database.
Sessions work by creating a unique id (UID) for each visitor and store
variables based on this UID. The UID is either stored in a cookie or
is propagated in the URL.
Session data is stored at the Server side but the reference or id to the session is stored on the client's browser cookie. For the server to know your session id we make a call to session_start() on each page it is required (at the top) so that the first thing done is to get the id from the user and retrieve the session data. It is required on every page whenever you want to access session data.
Here is a video tutorial also. http://blip.tv/step4wd/php-sessions_en-5983086
The answer is yes. You have to do that on every page. If you don't do that you get a undefined index error.
This will work because we include the file
Index.php
<?php
session_start();
//file doesn't have session_start
include "file.php";
?>
No: it is NOT always going to create a new session. It only tells the script that this page wants to start OR maintain an existing session.
A session is nothing more that a STATE AT THE SERVER that you carry from from page to page.
It is NOT accessible from the client (browser).
The only thing the browser must do to keep the session is passing an ID (called default PHPSESSID in PHP).
This ID can be stored in a cookie, GET or POST, as long as you get it transfered to the server with each request you make.
Youve to use session_start(), everywhere you need to work with session like, creating, accessing, destroying.
Unlike cookies, you can't access or work with session unless you initiate the session.
I've a site where people login and a SESSION is created.
I have noticed that if you leave the site for long enough (not sure exact time frame) the session ends but the members is still in the site. They can still click and navigate around and I believe this has resulted in some meaningless data in the DB as SESSION variables like userID don't exist.
I was looking for advice around logging users out when the SESSION ends.
I have looked at code like this - any better ideas?
<?php if(!isset($_SESSION[]) {header(loginpage.php);}?>
Is there a better way to write the above code?
Where should this code be placed? Just on the navigation menu or really on any place a user can click?
Finally is there a way to understand when the SESSION naturally expires - is there a SESSION variable I can print to screen to see the timeleft etc?
thanks
You need to validate the session, you already headed into that direction with your code, but it's not enough:
<?php if(!isset($_SESSION[]) {header(loginpage.php);}?>
It's not enough because $_SESSION[] exists automatically after the session is started (the session mechanism in PHP, see session_start).
Instead, if you have saved the userID inside the session, check that one:
isset($_SESSION['userID'])
If the session really expired, it should not be set.
I agree with the above answer. I would say it depends on how your application is architected to say where this belongs. before there is any output to the screen I am assuming your calling session_start, then immediately check for a session variable such as userID that gets set after a user logs in. if it's not set redirect setting a header for location to your login page. you could also write some js that checks the session cookie for a value at a specified interval(I believe, it's been a while so test it out), then when the variable isn't present you can redirect to the login page. a third way would be for the js code to make an XHR call to a php script to check out the session for you.
Sorry for the newbie question! I'm making a small website that allows users to create their own accounts. It's not a banking system, and it's unlikely that someone would want to hack it. That said, I am trying to make it reasonably secure, as there are plenty of bored script kiddies out there.
Could someone describe a basic workflow for a user logging in and having a cookie set that will keep them logged in for 30 days?
At the moment I have the following:
Validate and sanitize inputted data.
Check supplied credentials against bcrypt hashed password in DB.
If correct then call "Login" function.
Login function:
a. Delete any session data from DB with userID (table with two columns: SessionString and UserID).
b. Add new session data to DB (newy random generated string and UserID).
c. Write random generated string and UserID to cookie.
d. Set $_SESSION("UserID") with $userID.
But although the two cookies are being created and written to, the $_SESSION("UserID") remains blank... I'm guessing because I can't write to $_SESSION any time I like?
And even once that's fixed, how do I use the data stored in the cookie to log a user in? I'm guessing I don't want to go to the DB on every page load. And it will still require me to create a database object to see if the credentials in the cookie are ok. Is this the right way to this?
Once again, apologies for the newbie question!
UPDATE:
Yes, I do understand the difference between $_SESSION variables and a cookies. I also have session_start() at the top of every page (right after <php with no blank lines). $_SESSION("UserID") just remains blank.
Here's the code from the top of the page:
<?php
session_start();
if(!isset($_SESSION['initiated'])) {
session_regenerate_id();
$_SESSION['initiated'] = true;
}
Thanks for the help.
First off, there is an important difference between a session and a cookie. When you use the $_SESSION[".."] you are creating a session (which lives on the server, compared to a cookie which lives on the client), even though the browser uses a cookie to keep track of the session id. To create a cookie you would use the setcookie() method.
That said, I would recommend you to read through this article which is a step-by-step guide on how to create a secure login script, with persistence using a cookie for a "Remember me"-feature. Describe how to do it in detail would be to extensive for an SO answer im afraid.
Side note:
To be able to write to the session, you might have to call session_start(); prior to getting or setting a session variable using $_SESSION[".."].
Did you write a custom session handler that has your session-files stored in the db? I guess you don't.
If you want to use $_SESSION you have to also do session_start(). When using PHP sessions the cookie to identify the user will be set for you. You will also get session files created in your /tmp directory. That's the location your variables and anything you assign to $_SESSION will be stored.
Unless you define a custom session handler, that will manage the location of the session files, you won't need to query your database. Just save the users credentials in $_SESSION.
See this Tutorial on how to use PHP sessions.
PS: You access arrays like this: $_SESSION["UserID"], not with ().
you might want want to look at this article in which i have already discussed about various types of session hijacking and how you could avoid it.
session security in php
I am having a really unsual problem I have never had before, I have a signup page/form and a processing page that for submits to, on the processing page I set any errors that are in the user data like empty fields and set them to a session var array
$_SESSION['signup_errors'] = $signup_errors;
$signup_errors is an array that I set to the session, I can then access that session data on the same page but I just changed my site around to use mod-rewrite to change the URL's and the only thing that I can seem to think of is on my signup form I cannot access these session variables anymore and now that I use mod-rewrite the url is like this domain.com/account/new and it used to be domian.com/?p=account.new so now it appears that it is in a differnt folder, could that have something to do with it?
I have tried debugging it a lot and that is the only thing I can come up with is maybe because it appears to be a different directory now because of the mod-rewrite maybe that makes the session unaccessible?
Are you sure you're starting sessions on every page you're accessing? I would check to make sure there's
session_start();
Wherever necessary.
Also, what does
print_r( $_SESSION );
return? Anything at all? If not it would probably indicate what I was saying.
I would check that you're not changing domains. E.G. domain.com -> www.domain.com
Normally a cookie is used to track the session id, and by default, the cookie is tied to a single domain. I.E. If the session was created at www.domain.com, when you visited login.domain.com the cookie wouldn't be sent resulting in no session information.
It happened to me once, maybe you have a similar scenario. The session variable was temporary and I would destroy it once it was outputted to the screen.
With mod rewrite if you are routing everything, if there is a broken image, that might be redirected to your php script as well, it would in the back ground print out the error and destroy that session var.
Just a thought!