can Session be used to store secure info? - php

I have a php program, which has the login page and logout page. When user successfully logged in to the page it will be redirected to index.php
when index.php is loaded, it will fetch the data from the database (mySQL. ie. Select * from users) and populated some of the user data and display them in nice table format
Name Phone DOB ... Option
John Doe xxx-xxx-xxxx mm-dd-yy ... [Edit] [Details]...
etc
Not all fields from the query results will be displayed in the above table, only some of them will.
Under the Option column, there is an option called "Details", when clicked, user will be able to see some secure info.
I can think of two ways of doing it:
when index.php is loaded, instead of calling Select * from users (which * will contains some security info) I'll just call "Select id fullname, phone, dob from users". (don't select something unless it's necessary). Then when "Details" is clicked, I'll pass the id and retrieve the secure info from db by using that id. (IMO this is the most secure way but I'll have to make extra query call)
when index.php is loaded, I'll just do a Select * from users. Save the query results (arrays) into Session, then when "Details" is clicked, I'll just retrieve the array from the Session. This way I don't have to make extra query call, however I'm not sure if Session is secure or not.
Which way is better, in terms of security? (if none of them are, please advise how should I do this)

Storing data in the session is safe. Storing data in cookies is not safe.
Sessions are stored on the server, cookies are stored by the client (hence they are unsafe).
As far as performance goes .. it depends. There is no single answer, do what works for you but by all means keep it simple.

Related

Which is best method storing and retrieving data for registration in php?

Any one please help me,
I am have doing one registration form, which have 50 fields and 3 steps for complete registration, i have confused,
1) can i store all the fields in session or
2) each value store in database when steps complete and maintain one id that stored in database id in session, and retrieve values from database through that id
which is best one..
It depends.
Storing intermediate data in a session, not in your database, will save precious server resources. This is important.
You also will not end up with a lot of half completed registrations because 3 pages, or 50 fields, will be too much for a majority of people, so they won't finish it.
On the other hand, you will never know how many people didn't finish your form if you don't store the intermediate data in your database.
If you use a database, your form could work even if you weren't allowed to store a cookie on the visitors computer.
So my idea is that storing the data in a database, is the way to go.
50 fields for registration is bit too much. I would consult my superior to divide it as:
Registration Basics:
- Username
- Password
- Email
Registration Others (Picture, Passport# or similar): User will update his profile i.e. Part of this registration process at his ease or prompted to do so whenever one logins.
Yes you can store all fields in Session, I would prefer cookies as you
can always read user cookies at a later time(set cookie expire time to
couple of days). Plus it'll ease burden from server.
You can use following SQL to return ID of the registration:
select last_insert_id()
Would recommend store as you go forward with your registration i.e. Insert Username, Password, Email initially, then use UPDATE statement to add information to the same person (or row in terms of database).
Hope this helps.

Consistency of user data between all his sessions

I'm developing a site in PHP. When the user session starts I load all his db row in the $_SESSION var. When the user changes a db value I update the $_SESSION var too.
The problem starts when more than one session is active for the same user. Is there a way to update the data for all the sessions of the same user without overloading the database? Or, alternatively, is there a way to force php to use the same session file for all the session that belongs to the same user? Or I must simply query the db every time a session continues?
And another dilemma is: is it worth it? I mean, I do not know how much this mechanism could alleviate the server load, and I do not know if this mechanism is applicable to file-based sessions or I must use another session storing type.
This question is somewhat related to this other question on mine (even if the workaround for this is simply to delete all session files).
It really reaches the question why would you need to many data in a $_SESSION. And you should really take a time to decide which data is so often needed to be displayed.
In most of the cases you only need session identifier that keeps the user logged in, containing user_id, to take the needed data directly from the database.
Assuming the user can change its avatar, and you haven't go so many places to display this avatar, you don't need to store it in session, nor to SELECT it at the very same time. For instance, you can have a trigger page, which SELECTS the avatar by $_SESSION['user_id'] when he tries to send personal message to another user. Otherwise, you can put a cache (i.e. using memcached) where a query, which selects the user avatars should not be made more often than once an hour.
If user changes an email, it's the same. If somebody else tries to send him message, you trigger the SELECT query. Otherwise a cache is set.
So, let's say the user has changed his avatar, email, some other trivial info, then accessed your index page. In his session you load only the identifier. In the db the records are present, but they are not selected yet. So you have neither server load, because the session is light, nor database load, because no SELECT queries were sent.
No matter how many times the user tries to set his session (in this case logs second time), you have a present data in the db, and a session only with identifier. You can identify all his instances, but never use a data, which is not needed.
1 Well, I (don't, but) could do this with my session handler. I use databased SESSIONS with some extra information/columns like username and userid. That way I can exactly determine which session belongs to which user without fiddeling around with the serialized data.
http://php.net/manual/de/function.session-set-save-handler.php
2 But in your case it might be simpler to update your user table and then SELECT the user again to put the (new) data to $_SESSION['user']. (You will need some "user data was updated" info, to reload new data for all sessions).
3 Or you just avoid that a user can login more than once.

PHP Recently Viewed Products

How could I write a code for recently viewed products? I use a database to create dynamic pages and thought I could store the ID number in a session or cookie and pull the image and title from the database. Although I dodn't know if this would work. I would only want it to display the last 5 items viewed and not show any duplicates. Any Ideas?
If the user is logged in, you can create a table called 'userViews' providing the userID and the viewed productID.
Then, you can select a query using 'SELECT DISTINCT' on the productID. This will select unique values. (Check http://www.w3schools.com/sql/sql_distinct.asp)
If the user is not logged in, I suggest you do the same but instead of using a userID, try to find something unique from the user. You could try setting a cookie or session with a random (unique) number and link that to the database.
The conventional way would be to store within a cookie. If you can encrypt the cookie, do so.
Remember, a cookie can be modified by the user. The #1 rule is to never trust user input. All in all, be sure to validate the information before displaying or you'll open yourself up to the world of attacks.
Store the IDs in an array? Seperate by ',' or '.' -- do NOT create 100 different cookies for storing IDs.
You COULD also use SQL to store the views... but why use un-needed sql queries? SQL is for storage, long term. Session and cookies are for current actions.
There are 3 ways you can show recently viewed products. (Maybe some other way but these 3 are mostly used).
Based On IP
Store recently viewed in Cookies
Session ID
Based on IP
This isn't a good idea, it's because there is chance two people are using same router and the person who did not see the product would see the other person recent view. (You may use IP based to show other people like in your area. etc..).
Based on Cookies
By using cookies you are 100% sure that your are display recent product to the person who is visiting your sites, but not all users/visitors have enabled the cookies also cookies can easily edit and a security risk if you did not encrypt properly.
Session ID
You can generate a random user_id for a visitors and store this information in database like this:
start_session();
if(!$_SESSION['user_id']){
$_SESSION['user_id'] = rand(1, 1000000);
mysql_query('INSERT INTO products_recent (user_id) VALUES ('.$_SESSION['userid'].')');
}
Also, you can select/update the user product views and display to that users.
And you can easily clean database every 24 hours if you want, or you can use this data for analysis purpose.
Finally - Registered Users
If register users view your product I high recommend save in database and show these recent view product every time he/she visit your store.

To use sessions or db queries when doing check-up on every page?

I have application that has to check multiple data from user table, in order to create page.
Not just id and password, but other data as well, about 7 parts of information at this moment.
This check-up is done on every page.
Do I load all this data in session, and check it from there, or do I fire query on every page request? Needless to say, there are also other queries going on.
What's better practice, regarding optimization?
You should call the data once from the database and store it in a Session Variable. I generally put my user_id, username, email, user firstname & access_levels in a session when the user first logs in, Then I can call them anywhere in my application whilst the user is logged in.
Do not store the password in the session as it would not be required.
You an also create a variable called logged_in and set it to true or false to test against, (i.e: Show the "Account menu if the user is logged in, else show "Register" Menu).
[Update]
Here is a link to the Pro's/Con's of MySQL caching.
Scroll down to the bottom before the comments.
It kinda depends on your site, for a small site query caching would be fine, but if you wanted to develop more scalable applications, You have to keep speed in mind.
How to tell is mysql query cache is enabled: [LINK]
MySQL will cache the query if it's exactly the same as last time, so getting the user information via MySQL is fine. And especially so if you are getting everything via the primary key which is very fast.
Trips to database are slower than accessing sessions. You should definitely use sessions. Just don't forget that if this data changed in a database, it should also be changed in the current session.
If the data doesn't change too much you could cache it to a file ... or cache it to memory using something like memcache.
Then you can include it via this file and set some theshholds on when to fetch from db or just include.
Your question uses "check" - do you mean that you have to validate data on every page request? If so, you probably can't avoid going to the database.
If all you need to do is store data that doesn't change between pages for the same user, you should use sessions. Be sure to read the white paper "PHP is Not Java" on the zend.com website first!

Check permissions?

How do people usually verify that the information being fetched from a database is indeed related to the active user?
For example: let's say we list a group of PMs inside user x's inbox - how do I make sure that only user x can fetch something from the inbox, and not someone else (this would be done by "hacking" the address ofcourse).
Obviously I could just compare the active username with what is in the database table, but is there no easy way I can control this globally somehow, without having to compare the active username with hundreds of different tables for different actions?
Supposedly you're fetching the messages of the logged in user to begin with, no? Something like:
"SELECT * FROM `messages` WHERE `recipient` = '$loggedInUserId'"
If so, I don't understand the question. If that's not what you're doing, you're doing something wrong.
Well your application tracks users sessions, and ensures security. I.e. when user logins server sets cookie with session id, and by session variable your server upon request of page will know what user is really requesting something(or maybe no logged in user at all if there is no cookie), thus your application may use user id from session and request url to figure out if it should show what is requested, or show error message or redirect because user is trying to access what is not his. Of course this is a bit more involving but thats a start. I suggest reading on php sessions and cookies.
That is what database query conditionals are for... only selecting the relative data.
Generally once the person is logged in you would get their username and password from $_SESSION variables, query the database to make sure they are a valid user, then grab whatever you need using a WHERE username = '$username'

Categories