Since the default /tmp is usually open to all accounts in a shared host it's generally advised to use session.save_path and set a different location.
Is it assumed that a better location is in /home/username/example_session_tmp/ as long as it's not in /home/username/public_html/?
If so, wouldn't that still be vulnerable in case a hacker were able to inject a script in public_html and read ../example_session_tmp/? Or is it the only way and it's generally assumed your site is secured from script injections?
Note: Database session handler is an alternative option but let's assume it's not possible.
If a hacker gets a script into your site, there isn't a lot you can do to stop him from snagging sessions. If your webserver has access to the sessions then that user will. No matter where you stick it the hacker can find with with a simple call to session_save_path.
To sum up:
Prevent hackers from getting access. Who cares about sessions if your server is wide open? Secure this first.
Setting the save_path to ~/sessions should prevent other shared hosting users tampering with your sessions. This does not prevent someone who gains access to your webserver from seeing and tampering with sessions.
I agree with you for putting in /home/username/example_session_tmp/.
But,
If you have only one site per server, you don't need to change the path
If you want to make shared hosting your solution, moving to a new path is a good idea (you can check for apache-mpm-itk or php5-fpm)
If you want to have multiple servers, the easiest way is to put the session in the database, or create a shared folder (nfs, samba) for the sessions files.
Related
Have a questions, looking for an expert opinion
If a website is registered with a hosting company over a shared platform, then could that website's session variables be hacked by others working on the same shared platform?
Thank You.
I'd say shared hosts are less secure in that regard, as I've personally seen several shared hosts where everybody could view the temp folder where session files are stored. As php default dictates, file names equal session ID, meaning I could from there easily go to the corresponding site, put in the file name into a cookie, and thus hijack the session.
As mentioned in other answers and comments, competent hosts may avoid this through proper administration and sandboxing. Investigate yours.
There's also alternative session storage methods, such as through database. One could also regenerate the session ID often, to decrease the window for any potential hijack. Take a look at http://php.net/manual/en/session.security.php and http://php.net/manual/en/class.sessionhandler.php for some more details.
All that said, you're still better off avoiding sensitive data in session variables altogether.
At first you should ask yourself: Who do you trust? Sessions exist (besides sharing data between requests) to enable the developer to store and controll data outside the users reach. This was the problem and this is solved by sessions.
If you are in a shared environment it is possible for other processes and users to access your stored information and change it, but - and that's a big one - it is also possible for them to access your database and your code. So there is nothing to really help you in the case of evil attackers from within your system.
The only thing that will help is competent administration. In shared environments it is crucial to sandbox each application running on the server. They have to set session_save_path on a per user base, just as they should do with everything else.
I am currently building a simple CMS, and I would like to isolate it as much as possible. The application itself will have php login function, however I was thinking to add one more layer of security utilising Apache built-in security.
How secure is to isolate a PHP directory on a server using integrated apache password check? The general logics is that Apache security should be pretty tough to crack.
Thanks!
I understand your concerns about your code in progress. It is better to work on localhost till you reach a point when you are certain in your code, but what you can do:
Password protect your folder (can be sniffed).
Limit your folder access by IP (can be faked)
Make this php script run as a separate user with access rights only for this folder, so even if you have security breach it won`t impact your server or other scripts running on it.
Make sure you are using database user that have permissions only for your test database.
Create a fake domain, put a record in your hosts file and make your script accessible only from this domain (for example: app.staging.lo)
All this combined will be secure enough to keeps you away from troubles.
I read this post where the author advices to store session files in a different location on our application since sessions in /tmp/ are not safe. Is this a best practice that everyone follows? How safe does putting session files into other location will make any difference?
Need your valuable advice on this.
Thank You.
The problem is only that if you're on a shared host, the /tmp directory is typically shared by everybody, so other users will at least be able to list all files in the /tmp directory. They don't typically have access to those files, but just being able to see them may already be quite a security risk. Therefore it's better to store your temporary data elsewhere where only you have access.
This is not really of any concern if you are the master of your own server.
Just to make sure everyone is on the same page these are the credentials I'm talking about...
$user = 'user';// not actual user, not root either
$pass = 'pass';// not actual password
$server = 'localhost';
$database = mysqli_connect($server,$user,$pass,true|false);
So I'm talking about the passwords used to connect to the database, not the passwords in the database (which for clarification I have hashed with salt and pepper).
I have not read anything that I think remotely suggests you can have 100% foolproof security since obviously the server needs to connect to the database and get the content for visitors 24/7; if I am mistaken I would love to hear how this would be possible.
So let's presume a hacker has root access (or if that does not imply access to the PHP code let's just say then have access to all the PHP source code) and they (in this circumstance) desire to access/modify/etc databases. If we can not prevent them should they have access to the PHP source then we want to slow them down as much as possible. I can keep each site/database connection password in separate files (can as in I'm a few weeks from finishing multi-domain support) for each site and not inside of public_html (obviously). I use serialize and unserialize to store certain variables to ensure certain level of fault tolerance for when the database becomes unavailable on shared hosting (preventing site A from looking and acting like site B and vice-versa) as the database can sometimes become unavailable numerous times a day (my database error logs are written to when the SQL service becomes available again and catches these "away" errors). One thought that has crossed my mind is determining a way to store the passwords in one hash and un-hashing them to be used to connect to the database by PHP though I'd like some opinions about this as well please.
If someone has a suggestion from the database perspective (e.g. having the ability to restrict users to SELECT, INSERT, DELETE, UPDATE, etc and not allowing DROP and TRUNCATE as examples) my primary concern is making sure I am SQL neutral as I plan to eventually migrate from MySQL to PostgreSQL (this may or may not be relevant though if it is better to mention it). I currently use phpMyAdmin and cPanel and phpMyAdmin shows the connected user is not the same as the site's database user names so in that regard I can still use certain commands (DROP and TRUNCATE as examples again) with that user and restrict the SITE user permissions unless I am mistaken for some reason?
Is there a way to configure the context of where the connection credentials are accepted? For clarification a hacker with access to the source code would not be accessing the site the same way legitimate users would.
Another idea that crossed my mind is system based encryption, is there a near-universal (as in on every or almost every LAMP web host setup) web-hosting technique where the system can read/write the file through Apache that would introduce a new layer that a hacker would have to determine a way to circumvent?
I am using different passwords for each user of course.
I currently am on shared hosting though hopefully my setup will scale upwards to dedicated hosting eventually.
So what are the thoughts on my security concepts and what other concepts could I try out to make my database connection credentials more secure?
Clarification: I am looking for ideas that I can pursue. If there is disagreement with any of the suggestions please ask for clarification and explain your concern in place of debating a given approach as I may or may not have even considered let alone begun to pursue a given concept. Thanks!
There is little to be gained from trying to slow down an intruder that already has root access to your system. Even if you manage to hide the credentials well enough to discourage them, they already have access to your system and can wreak havoc in a million ways including modifying the code to do whatever they wish.
Your best bet is to focus on preventing the baddies from ever penetrating your outer defenses, worry about the rest only after you've made sure you did everything you can to keep them at the gates.
Having said that, restricting database user accounts to only a certain subset of privileges is definitely not a bad thing to do if your architecture allows it.
As code_burgar says, once your box gives root, it's too late. That being said, I have had to implement additional security mesures on a project I was involved with a while back. The solution to store config files in an encrypted partition so that people with direct access to the machine can't pull the passwords off by connecting the drive to another PC. Of course this was in addition to file system permissions so people can't read the file from inside the OS itself.
Another detail worth bringing up, if you are really paranoid on security:
$user = 'user';// not actual user, not root either
$pass = 'pass';// not actual password
$server = 'localhost';
$database = mysql_connect($server,$user,$pass,true|false);
unset($user, $pass, $server); // Flush from memory.
You can unset the critical variables after use, ensuring they cannot be var_dumped or retrieved from memory.
Good-luck, hope that helps.
You want to approach security in layers. Yes, if an attacker has root access, you're in a very bad place - but that doesn't mean you shouldn't protect yourself against lower levels of penetration. Most of these recommendations may be hard to do on shared hosting...
Assuming you're using a decent hosting provider, and recent versions of LAMP, the effort required to gain root access is substantial - unless you're a very lucrative target, it's not your biggest worry.
I'll assume you harden your server and infrastructure appropriately, and check they're configured correctly. You also need to switch off services you don't need - e.g. if you have an FTP server running, an attacker who can brute force a password doesn't need root to get in.
The first thing you should probably do is make sure that the application code has no vulnerabilities, and that you have a strong password policy. Most "hacks" are not the result of evil geniuses worrying away at your server for months until they have "root" - they are the result of silly mistakes (e.g. SQL injection), or weak password ("admin/admin" anyone?).
Next, you want to make sure that if your webserver is compromised - but not at "root" level - you can prevent the attacker from executing arbitrary SQL scripts. This means restricting the permissions of your web server to "read and execute" if at all possible so they can't upload new PHP files. It also means removing things like CPanel and phpMyAdmin - an attacker who can compromise your production server could compromise those apps, and steal passwords from you (run them on a different server if you need them).
It's definitely worth looking at the way your database permissions are set up - though this can be hard, and may not yield much additional security. At the very least, create a "web user" for each client, and grant that user only "insert, update and delete" on their own database.
I have found a solution for PHP(Linux) On the root create a directory say db and create a class and define all the database connection variables and access methods in a class say DBConnection.php now your website is example.com you are storing your files in public_html directory create a php file under this directory to connect and do all database operations and include DBConnection.php file using following statement
require('../db/DBConnection.php');
this file cannot be accessed using 'www.example.com/db/DBConnection.php'
you can try this on your web site.
I wrote a PHP web-application using SQLite and sessions stored on filesystem.
This is functionally fine and attractively low maintenance. But, now it needs to run on a shared host.
All web-applications on the shared host run as the same user, so my users' session data is vulnerable, as is the database, code, etc.
Many recommend storing sessions in DBMS such as MySQL in this situation. So at first I thought I will just do that, and move the SQLite data into MySQL too. But then I realized the MySQL credentials need to be readable by the web application user, so I'm back to square one.
I think the best solution is to use PHP as a CGI so it runs as different user for each web-application. This sounds great, but my host does not do this it uses mod_php. Are there any drawbacks from an admin's point-of-view for enabling this? (performance, backward compatibility, etc)? If not then I will ask them to enable this.
Otherwise, is there anything I can do to secure my database and session data in this situation?
As long as your code is running as the shared web user, anything stored on the server is going to be vulnerable. Any other user could write a PHP script to examine any readable file on the server, including your data and PHP code.
If your hosting provider will allow it, running as PHP as a CGI under a different user will help, but I expect there will be a significant performance hit, as each request will require a new process to be created. (You could look at FCGI as a better-performing alternative.)
The other approach would be to set a cookie based on something the user provides, and use that to encrypt session data. For instance, when the user logs in, take a hash of their username, password (as just supplied by them) and the current time, encrypt the session data with the hash, set a cookie containing the hash. On the next request, you'll get the cookie back, which you can then use to decrypt the session data. Note however that this will only protect the current session data; your user table, other data, and code will still be vulnerable.
In this situation, you need to decide whether the tradeoff of the low cost of shared hosting is acceptable considering the reduced security it provides. This will depend on your application, and it may be that rather than trying to come up with a complex (and possibly not even very effective) way to add security, you're better off just accepting the risk.
I don't view security as all or nothing. There are steps you can take. Give the web db user only the permissions it needs. Store passwords as hashes. Use openid login so users provide their credentials over SSL.
PHP on cgi can be slower and some hosts may simply not want to support more than one environment.
You may need to stick with your host for some reason, but generally there are so many available that it is a good reminder for people to compare functionality and security as well as cost. I have noticed many companies starting to offer virtual machine hosting -- nearly dedicated server level security in terms of isolating your code from other users -- at what is to me reasonable cost.
A shared host is no way to run a web site if you are conscious about privacy and security of your data from the sites that you share the server with. Anything accessible to your web application is fair game for the others; it'll only be a matter of time before they can access it (assuming they do have incentive to do that to you).
"you can place your DB connection variables in a file below the web root. this will at least protect it from web access. if you're going to use file based sessions as well, you can set the session path in your user's directory and again outside the web root."
I don't have an account so I can't downvote that.. but seriously it is not even relevant to the question.
Duh you store stuff outside the webroot. That goes for any hosting scenario and is not specific to shared hosting. We're not talking about protecting from outsiders here. We're talking about protecting from other applications on the same machine.
To the OP I think PHP as CGI is the most secure solution, as you already suggested yourself. But as someone else said there is a performance hit with this.
Something you might look at is moving your sessions and db to MySQL and using safe_mode and/or open_basedir.
I would solve the problem with a infrasturcture change instead of a code one.
Consider upgrading to a VPS server. Nowdays you can get them very inexpensive. I've seen VPS's starting # 10$/mo.