secure php session handling that uses mysql storage - php

I’m trying to find a lightweight PHP session handling library, i’ve googled and fallen into confusion.
I want a library that stores sessions using MySQL
allows kicking out of logged in user
does ip matching
browser matching
secure to session hacking etc.
Any ideas?

If you're familiar with MySQL and PHP it's rather trivial to write your own session handler.
http://php.net/manual/en/function.session-set-save-handler.php
It may be faster to write a personalized one than searching for exactly what you want.

You could have a look at this article by Chris Shiflett, which describes making changes to session_set_save_handler().

You may want to check out this class that I made a while ago... it does everything that you say expect for kick a user out, but you can mae a function that does that in 5 minutes (just call the delete method with the user id that you want to kick out).
It still needs documentation and some tweeks here and there, but you can give yourself an idea of how is done.
I wouldn't relay on user's IP for security, if they're using rotating IP (some cellphones companies) or they're behind thor or something you're going to have issues, use user_agent instead.

Related

Share login between PHP and ASP Classic (VBScript)

I'm trying to update/maintain an older web site that was initially written in Classic ASP/VBScript, and later had PHP pages added. I'd like to set it up so that PHP handles the login, but then that logged in state can be shared between PHP and ASP/VBScript. Note that the pages and languages are fairly intermingled -- somebody spending time on the site might come across several different pages in each language, in no particular order.
(Eventually I expect it to be completely rewritten in PHP, but I have to eat this elephant one bite at a time; and for now I'm simple trying to improve security.)
Let's assume I've successfully logged in and validated the user in PHP using something like phpPass. How do I tell the ASP/VBScript page they just pulled up that they're logged in? How can I best do this securely?
(And thank you for any help!)
You cannot share sessions across Classic ASP/VBScript and PHP as they create/use them differently. My solution isn't that secure but would work:
Log the user in via 1 of the languages (say PHP)
Pass the initial session variable to a URL and get ASP to look at the querystring and then create another session for ASP there.
That would deal with it...although not that secure!
The best answer I've been able to find for this issue was the following. Specific to sharing a login between Classic ASP and ASP.net, but the methodology is exactly the same:
As you probably already know, classic asp and asp.net cannot share the
same session state, so you do need to have a mechanism to log from one
into the other.
What I would do is: when someone logs in, create a unique GUID that
you save in the database for that user. When you jump from one site to
the other, pass that GUID into the query string. When you try to
auto-log them into the other site, look up that GUID and see if it's
attached to anyone. If it is, log them in.
This way you aren't passing anything that a user could guess or
decrypt.
Additionally, it's smart to add a timestamp to the database as well; and the GUID should only be valid for a second or two. Log in on the PHP end, then flip over to ASP and check the GUID.
Not totally secure, but appears to be about as secure as I'm going to find.
source: https://stackoverflow.com/a/921575/339440
Edit to add: per comments, also record the user's IP address to the database and compare it on the ASP side. No teleporting allowed!
CORRECTION: In this case "GUID" is a misnomer. What you need here is a random string of characters, not a GUID. A GUID is a semi-random construct with one of a handful of specific formats, and is not applicable here.

Security through different programming language

There is any way to check the login status through different programming language?
Right now I'm using three session (same name) that starts at the same time after the login process, using ajax.
Right now, the login.html form is processed on three files: login.aspx, login.asp and login.php but it's seems too slow and weird. I'm combining three different services from the same company into one, after re-building the users and others common tables in mysql, everything seems to work fine, but I'm really scared about security bugs.
Just to let you you know, I have to check the login session status before any ajax callback, so if the user is working on an ASP page calling PHP through Ajax, may be that the session is still active on the ASP, but expired on the php file.
Any valid method to check all in one time? I can also accept a cookie solution but how to make it readable between php, asp and .net?
This sounds like single sign-on to me. Let's try to split the problem.
There is any way to check the login status through different programming language?
You're not really interested in the language used. Any language, given the same info and algorithm, would decode with success the same encrypted data. I guess you're instead having problems because PHP's application logic regarding this point is different from the ASP's one.
So for the first point, you can
Implement / normalize the same session checking logic among all of your apps. This is probably unfeasible, because you might be using Laravel here, and ASP.Net on the other, and the two are probably slightly different in this regard. If you can, do this, or...
Look into JSON Web Tokens. I won't go into detail, but these were more or less designed to solve this class of problems. They are also easy to handle, but be aware, there are aspects you have to take care of when using them for user authentication.
[...] Just to let you you know, I have to check the login session status before any ajax callback, so if the user is working on an ASP page calling PHP through Ajax, may be that the session is still active on the ASP, but expired on the php file.
Not to be that guy, but some concepts are somewhat deformed here. Sessions don't expire on files; they normally are setup with a given expiration time and a given domain. So generally speaking, a session opened from a PHP app, and stored on a cookie, then read from an ASP one shouldn't change, given that no difference exists between the two app's session handling logic.
Any valid method to check all in one time? I can also accept a cookie solution but how to make it readable between php, asp and .net?
For both of the solutions i suggested above is, especially for the cookie one, it's important you make the apps absolutely identical in respect to session handling. While this is trivial with JWT (as there's barely any logic on the app's side), this may prove to be harder with cookies if the authentication logic comes from some one else's code (as in a framework).
I haven't asked about single sign-out, and at this point i'm afraid to ask :). But these are some guidelines:
If going the cookie route, be aware of cookie's domain. A cookie is normally valid for every request coming from the website domain (name.com), but you may have some of your apps under a subdomain (like, phpapp.name.com). In this case, be sure the cookie created from the given app is valid for the whole domain, and not just the subdomain. And make the apps available at subdomains / pages under the same domain. Cookies don't work cross-domain, and you have to deal with that, since cookie domain policy is enforced at browser level.
Launching three AJAX calls means triggering three login procedures. I suppose all of these would terminate, at some point in the future, and all of those would be storing / rewriting the cookie. If the apps understand the same cookie, it's mandatory you open the login process on just one of them. This would store the cookie, which would then be automatically picked app from, say, a page in the second app, giving you a seamless transition into a logged-state in the second app.
JWT would normally require some JS work, which you may like since the same script can easily be loaded in all of your apps. On the other side, you can be sure that different server libraries handling JWT would all work the same for you, thus ensuring compatibility.
Personally, i would look into JSON Web Tokens.
You can develop your own session provider which stores data in a separate place (for ex. in database or files). Then everything you need to do is write some code in every environment to handle your session information from that provider. Because you use only one source to store session information there will be no problem with synchronization between any of yours environment.
If you need then you can use a webservice for exchange session information between every environment and session provider. Every application can use security connection to get and set information about session from that session webservice.
I think you can do this!You can create provider which stores data into database. Then Write some cool code to manage your provider.You can also use webapp or sevice.Every service use security to get and put information.

How to recognize 2 PCs with same IP and browser(version)

I want to give a "like" option on my page for non-logged users.
The simpliest thing would be to detect user IP ( e.g. by $_SERVER['REMOTE_ADDR']).
More sophisticated would be detecting user's agent (e.g. by $_SERVER['HTTP_USER_AGENT']).
But I want to give like-posibility for "each PC in family" (real-life family) - this could also mean they all have not only the same IP, not only the same browser but also the same browser-version...
So how would I determinate whether it is a different PC? (without using cookies/session)
I want to store one "like" per PC and since cookies can be cleared I didn't want to use them :)
I wanted to abstract my particular interest from the whole problematics - so I did.
However you should never trust user input (as David pointed out) - so do not base your final like-count on just that ! At least put a likes/per IP limit and combine it with cookies/session.
Your only option to do this outside the simple methods of using cookies, logins, etc. is to do browser fingerprinting. This technique involves gather a variety of information that the browser outputs to the server/webpage and making a hash of it to create a unique ID for that client. It has a remarkably high accuracy and would work fairly well under the circumstances you are describing.
It is based on the idea that "no two browsers are exactly the same". In other words, you look at screen resolution, user agent strings, active plugins, etc. and create a "fingerprint" of those settings. There is almost always going to be a variance in some way.
There are available libraries that can help get you started. Here is one that is very easy to implement and understand... https://github.com/Valve/fingerprintjs
You can use sessions without using cookies. When the user logs in, they get a token, and this token is appended to every URL they visit. (In PHP you can see this if you disable cookies in the browser, you will get "PHPSESSIONID" in the URL). So, if you make users log in before voting / liking / whatever, then you can achieve this using sessions but not cookies.
If you are talking about public users without a login mechanism, then there really isn't any way to achieve this, unless you set a cookie recording the fact that this browser has voted.
Note however that not only can cookies be deleted, but it won't actually achieve what you want unless everyone in the family uses a different browser or has a separate login on their operating system. Otherwise they are effectively all the same user as far as you can tell. Also people can use multiple browsers so one person could vote / like more than once anyway.
Detecting the User Agent can easily be spoofed; so it isnt a reliable way. The best way to do this is sessions or cookies. Why do you not wish to use them?
Short answer: you can't.
Remember, each request to a web server is a new event. Cookies are the only way to persist data between calls. So if you rule them out you really can't differentiate them. This is a major reason why Google puts long life cookies on their site.
Can cookies be deleted? Sure. But they're really the only option you have.
You cannot give a single identity to a PC.
Cookies can be cleared.
User logins can be done from different computers.
$ip.$http_user_agent will not work.
User may restart the modem and ISP might assign a new IP.
Or use a different browser to change $http_user_agent.
Or another system on a LAN might have the same $http_user_agent.
What is the significance of giving one "like" per PC (provided you are able to even identify a PC correctly)?
What if two different users with different tastes use the same PC?

Secure voting system with php without login

Is there a way to make a reasonably secure system to vote without having to login. I now use cookies to set if the person has voted yet and also insert the users ip in the database.
If that user removes his cookies, he will be able to vote again. That's why I do a check if the user's ip exists in the database and if that IP has voted in the last 30 seconds. That way he'll have to remove his cookies and change his IP address to vote again.
I know there's no 100% failproof solution to this, but
is there a more secure way to do this?
There are two ways that could improve your results, but read and judge for yourself, if you need them:
More persistent cookies
There is the Evercookie project, which stores cookie-like information in a lot of places. It is much harder to delete than just normal cookies.
I personally think that this project should be considered a proof of concept and actually using it would be unethical
Better user recognition
Instead of just looking at the IP address in order to identify a returning visitor, you could use Browser fingerprinting. The EFF has shown with their Panopticlick project, that the combination of Browser version, OS version, installed add-ons etc. is often unique. The Piwik web analytics tool also uses this kind of user heuristics to tell visitors apart. I don't know the implementation, but it's FOSS and in PHP, so you should be able to find that part.
You can run with both of those solutions in unison - but it's still not very secure. You could go as far as blocking a subnet from voting (192.168.1.xxx) to prevent against dynamic IP changes, but then you're also blocking up to 254 people from voting - and it won't prevent against a proxy.
One method I've seen used quite a bit is making it look like you allow duplicate votes; i.e: show it on the end user's end that their duplicate vote has been counted, but don't actually count it in your own database.
But realistically, a login system is about the only relatively "secure" way of doing this - but if someone is determined enough, that can obviously be gamed too.
Hope this helps.
Eoghan
You could ad the
User agent (on short periods there's often little chance that 2 surfers have exactly the same : https://panopticlick.eff.org/index.php?action=log&js=yes)
But again ' if someone is determined enough, that can obviously be gamed too.'

Session management in propiearatory webserver

I have been tasked with attempting to fix a problem with session management in a webserver. The code is written in c and is pretty old. Sessions are limited to creating a folder for a new session and a little php script runs on top and checks the SID is valid for a logged in user.
However the way the program works the SID is stored in the URL! so any copy pastes result in session hijacking. Now I've been told its not possible to change the fact that the SID is stored in the URL. It is not possible to use cookies as some customers have high security settings in their browsers and this also cannot be changed. The only things I can think of are URL rewriting storing the SID in a hidden field but I am still waiting for information from my manager, I don't think it will be possible as the HTML files are pre written and I don't think it is possible to add hidden fields to them, maybe this can be done on the fly by the server program, I'm not sure. And my last idea was to use tokens, or just to start a new session if a different IP address or User-Agent string is found even if it has a valid SID.
I don't really know much about web security I am on a placement year from University and mainly C programming but have been given this task as a little side project which I would like to try and accomplish something with.
Do any of you have any pointers?
I know I've been vague and I'm not allowed to post any code :( sorry
Thanks for you help in advance though.
Even with already existing session managers, the only way to avoid session hijacking is to also validate against the client's IP address and optionally the user agent string as well. Any of the other suggestions can be done just for obscurity, but won't have any effect if somebody decides to try hacking into your app.

Categories