I'm currently making two different, but pretty similar web-based applications. So I'm using PHP, and standard MySQL (MariaDB in my case because I use XAMPP but I guess two of them are similar to one another). FYAI, I'm building my apps on a local server which located just right in my PC.
So let's say my first project is Project1, and it is stored in localhost/project1. Meanwhile, the Project2 is in localhost/project2. Both of them have a login feature for different account/user.
So when they try to log in I do this. By the way, it's MVC.
class Auth extends Controller {
public function index()
{
// verification such as prevent raw attempt with no post data, etc.
// verify the username and password, header back if fail, blablabla, u know...
// and then the following is if succeeded
$_SESSION['login'] = true;
$_SESSION['id'] = // user id;
}
}
I used that similar system in both of my projects.
The Problem
So I was trying to figure out how session work, and I log myself into the localhost/project1. And then I open localhost/project2. Surprisingly for me, I didn't need to type in my username and password in localhost/project2. I logged in already. These things gave me some concern. So these are my questions:
Did that happened because I develop my site on a local server in my very own computer?
Don't you guys think that anybody can break in to my site just by creating some simple procedural php code in their server like this:
$_SESSION['login'] =true;
// and other sessions
and then just access that file, which make their session login value is
true, and other validation session index that i used, and then just
access my web site and logged in, like some man with big AK-47 in his
hand walks in right from the very front door of the white house with no
secret service notice and hold him down in custody?
Why is this really happening and how do you think I should fix it? I also have some timeout feature so I'm afraid any big changes would bother most of my construction but any suggestion is really welcome.
Sorry if my English is bad, or my php knowledge is pathetic. I'm new.
Sessions are normally driven by a cookie that contains your session ID. Since cookies are shared within the same domain by default, if you have two projects both located on the same host/domain (e.g. localhost), and both use sessions, then they will both share the same cookie and thus the same session data.
This means someone could NOT hack into your site by setting up a random session in their own site. Their session data would only be applicable to their own site.
On a side note, it's not usually a good idea to suggest analogies that involve storming the white house with a gun. Just a friendly piece of advice.
Related
If I may ask, I would like to ask about "sessions", "controllers" and "session controllers".
So let's start at the beginning: I have heard of MVC and tried it in C# (VS), but while I could grasp the concept, I didn't understand implementation. It all seemed so strange. Now in PHP the concept became even more clear.
Now I would like to ask whether or not a "session controller" is like a controller for the session. It seems straight forward, in wording, but maybe I have it wrong. Although I would preferably not implement MVC in the current project I am working on, yet I would like to perform some sort of "controller" that manages groupings of session content.
Although I would like to ask if it is possible to have the following script in your application:
//path: c:/xampp/htdocs/starvationproject/root/index.php
<?php
include '../session/controller.php';
?>
<!DOCTYPE..........
//path: c:/xampp/htdocs/starvationproject/session/controller.php
//I have not coded this script yet, but it will perform tasks like
//setting the user, session variables etc.
<?php
session_start();
?>
// An important question here. If I include this file in the previous, can
// I safely say that the session has been started in index because of the
// include, or do you have to manually type out session_start();
// in each page?
Lastly, I would like to ask if this file structure is correct or not, or rather if it is standard or nor, or whatever:
Folder Structure
, where "multi" (as you can see) has a page named after each folder in "partial", where what I did is, based on the get request of the page in "multi", I included a partial, i.e:
if ($_GET['q'] == 'Add') {
include '../partial/stockAct/add.php';
}
else if ($_GET['q'] == 'Update') {
include '../partial/stockAct/update.php';
}
And then those "partial" files only held like a section with a form or something like that. As in the tv stays where it is, I'm just switching channels.
I'll do my best to help.
First let's talk about sessions. Sessions are used by the server to 'store' temporary information throughout a single browser session (this can be modified slightly but we won't go down that rabbit hole). In your specific situation, having a session Controller is unnecessary because the server handles all of the session logic. For example, on the login page, when the login form is pushed to a login script, you can simple add the user id to the session at that point and then no matter which page you move to, the user id will still remain in the session. The benefit is of course that you only need to set the session once and only access it when you require. This is where an MVC shines though as you can easily define a routing where all pages of a specific authentication type first go through to ensure the user is logged in/ has access to the page content.
For folder structure, I'd recommend some immediate changes. Firstly, I'm sure you are familiar with the talk of "public / public_html' folders? These folders are specifically name to represent the location where you put ALL of the files a front-end user would "see". This includes, front-end js files, css/ styles and in your case php PAGES. This folder SHOULD NOT however contain any back-end logic like database connections or verification scripts as this would give the front-end access to potentially sensitive information (ie. database login information which I am sure is found in your DB_Conn.php file).
To fix this I propose the following (assuming you would like to avoid the "MVC" structure).
ROOT
->Public //this is your WEB ROOT/ DOCUMENT ROOT folder
->Pages
->Style
->Scripts
->Assets
->Images
->etc.
->DB
->Connections
->db1_conn.php
->db2_conn.php
->Models
->User.php
->Posts.php
->Verification
->login.php
->etc
I'd like to finish with some advice as I used to build sites this way some time ago. MVCs take some time to learn, but their biggest advantage is the organization and flow of information. As a bonus, their process covers common issues like verification, security and data sanitization. Don't let them scare you, for the time it takes to learn then, they are well worth the capability you will gain from them.
I'd highly recommend Laravel. Version 5.5 just came out and oh boy is it a thing of beauty. Hope I could help at least a little!
According to the documentation (http://ellislab.com/codeigniter/user-guide/libraries/sessions.html), the CodeIgniter session library has the following behavior:
"When a page is loaded, the session class will check to see if valid session data exists in the user's session cookie. If sessions data does not exist (or if it has expired) a new session will be created and saved in the cookie. If a session does exist, its information will be updated and the cookie will be updated. With each update, the session_id will be regenerated."
I think this behavior can be dangerous from a security point of view, because somebody could flood the site with requests and that way pollute the session store (which, in my case, is a mysql database). And my app is running on an ordinary web host..
Is there any easy solution to this which does not require too much additional coding? Maybe a library that could substitute for the one that ships with the core? I don't want to code it all myself because I think that would defend the purpose of using a framework.. and I actually don't want to use another PHP framework, since, for my specific requirements, CI is perfect as regards the freedom it gives you...
because somebody could flood the site with requests and that way pollute the session store
So? Then you just have a bunch of sessions in the db. This doesn't affect the validity of sessions. If there is a mechanism to delete old session based on space/time, then those sessions are gone and the former owners of those sessions will need to re-authenticate.
If you are worried about collisions, do a little research and you will find that any collision probability is a function of the underlying operating system and/or PHP itself, so CodeIgniter can't help you there.
Also, maybe disk space fills up but that is an operations/architecture problem, not a CodeIgniter problem and not a security issue in and of itself.
I'm currently building a web application that uses a combination of OpenID and uname/pw authentication to authenticate users. Users are supplied a PHP session when they login successfully, and some information about their account (email address, usergroup, blah blah) is written to that session.
However, there may be a need for me or someone else as an administrator to update a users details (or to ban them immediately if they're very naughty). I'm hesitant to use a killsession tag like this (pseudocode):
session_start();
mysql_start(connection_stuff);
if (mysql_query("SELECT FROM users WHERE uid = '$_SESSION['uid']' AND KillSession = true")) { Kill session, force reauthentication };
However, doing it like this has two flaws:
We have to query the database every time someone loads a page to see if something changed
We gotta log the user out which just annoys him (or reload all of his session variables, which doesn't seem efficient)
Is there some way I can modify a user's session while they're still in it without having to resort to forcing them to login again? Some people seem to suggest in this stackoverflow thread using session_id to change to the user and then fiddle with their variables, but that seems like a shoehorn way of doing it. Thanks in advance!
I think instead of storing that stuff along with the session, it should be kept (and cached) separately. That way you avoid data duplication and the issue you're running into right now.
If an admin needs to kill the session, just DELETE it from the table.
Even though you express concerns about having to query the database on every page load, my guess is that it most likely does not affect performance noticeably. If the website is database driven in the first place, them it's just a matter of a single more query. I'd actually say that moving the entire session handling to the database (store session variables in a table) can make your system better in terms on flexibility. It will be much easier to deploy your system on multiple servers and do proper load balancing if that is someting you think will become necessary at son point. That is how the bigger CMS systems handle their sessions. My advise is, in other words, to stick with the extra query and actually consider to move session state to the database.
Firstly, please don't dismiss this question - I'm aware it's an ugly situation but hey, real life isn't pretty.
I'm developing an extra section to a web app that's written in asp.net, but in php - it's mostly done (the two parts don't really communicate with each other outside of a database - the integration is mostly just cosmetic.)
The only issue I have is detecting from the php part when the .net session has expired so that it logs the user out and redirects to the login page.
I believe the asp.net application is compiled, but either way I'm not allowed to alter it so I was thinking maybe the best thing to do would be to make a very small/simple aspx page that outputs true or false which I could call using curl from php (and passing the browser's cookies along.)
Would this even be possible? I'm not sure how session security works on asp.net eg whether one .net application can read another's session variables, but if it's anything like php then it'll be possible.
mypage.php --curl--> checksession.aspx --|
| |
<----------- true / false <---------------
So mypage issues a GET (with cookies from browser) to checksession using curl, checksession simply returns a true or false (or something like that) and mypage redirects to the site's login page if that's false.
The authentication for the php side is already sorted out and is separate to this issue.
So really, what I need to know is can I have just a simple .aspx file that does this check, and if so where would I go to to find out how to program such a simple page? If it's just a line or three, please could you let me know what those lines would be (I'm sorry I've never done any .net stuff..)
If this isn't possible, then if you don't mind, could you provide some alternative solutions? Thanks!
-- EDIT --
After spending most of the day with this problem, I'm now thinking that using php at all to get around this is a bad idea. There's actually two levels of authentication involved (one is normal HTTP request/response login type thing, then there's the .net session) - on top of that I totally missed the point that obviously these sessions are almost certainly going to be backed up by the IP of the users browser which I'd have to spoof or something coming from curl as that'll be running on the server.
So I think I'm going to use jQuery somewhere in the header of my page to check and redirect as required...somehow :/
-- EDIT 2 --
Ok, so the javascript way has suited my needs pretty well - obviously it's not a secure way of doing things, but fortunately in this case it's ok as this is just an app used on the intranet (and the shoddy way they authenticate users is terrible anyway.)
There are multiple ways here. First of all, the cookies alone won't do much, because the session can be expired in ASP.net even though the Cookie is still alive.
ASP.net supports multiple SessionStates, of which two are common:
In Process - here, the Web Server (Usually IIS) holds all Sessions in memory. If the IIS Service is restarted (Happens by default every 24 hours, not just when the system restarts!), All Sessions are wiped (that's why the cookie alone does not help). This scenario is default I believe and thus very common in single-server environments
SQL Server - here, the session data is stored in a SQL Server database. This isn't used that often though.
State Server. This seems really uncommon, so I'm omitting it.
Scenario 2 is your best bet, because you can just read the session id from the cookie and query the SQL Server database for the session info.
in Scenario 1, your approach is the correct one: You need help from the ASP.net Application, which can be a .aspx page. Make a request from PHP passing in the session cookie and check Session.SessionID and Session.IsNewSession to make sure the ID Matches and IsNewSession should be false - otherwise, ASP.net just recreated a new Session.
You may have to interact with the Session from the ASP.net page to activate it (Session["PingFromPHP"] = true) which may interfere with the ASP.net Application if your key (the name in the []-brackets) has the same name.
If the ASP.net Application is compiled, put the .aspx.cs file that serves as the code behind into a folder named App_Code, this should allow you to run it.
Hope that gets you started.
I don't know php but If both app are on same domain you should be able to read the ASP.Net session cookies and determine if it has expired or not., because cookies are bount to domain instead of web app using it and so browser will surely give the cookie with the request.
This maybe isn't the right answer to this question.. but I found a fairly easy (slightly ugly) fix which was a bit of luck really..
I created a page called checksession.aspx and asp.net (or the iis app) automatically redirected that page to the login page if the session had expired. Using this with curl I can now just check whether I get a 302 redirect and if so I know that the session has expired.
Woot :)
I have found what looks like a good, secure PHP login script, however i am having trouble figuring out how to implement it. (It is located here http://www.adesdesign.net/php/tutorials/php/php_login1.php)
I am new to PHP so don't know much yet. I can't figure out how you actually authenticate a user and return a message to them if it fails and where to stick all the functions and classes mentioned throughout.
I know it may be very obvious to some but i just don't get it!
Thanks.
Not the easiest script/way to do it, but quite complete. You say you're new to php, what about OOP ?
IMO, this one seems easier : tutoriel.
Principle always stays the same : you have in your database a table with your user.
The visitor come and try to log.
If his login/password are good, you redirect him to his profil/any page you want and you store in $_SESSION['verifiedUser'] = true ,
if his login/pass are wrong, he's redirected to the login page, with an error message.
And in every page restricted to logged user, you add
if (!isset[$_SESSION['verifiedUser']) )
header('Location:loggingForm.php');
Clement answer is perfect.
May be the pear Auth class can be usefull
Just a note because you siad your are new to php: the authetication process is not the only important thing. You should also think about the ACL (access control list), a mechanism which allows an authenticated user to do some things but not others on one or more pages
--
Dam