Why placing framework folder outside public root is safer? - php

Why it is always recommended to place framework files outside of the public root ?
Given that sometimes a framework doesn't have .ini or .inc files that can be opened by a browser.

Well, there is definitely nothing to be gained from placing framework sources inside the web root. Since the choice of where to place the file is therefore free, it's only logical to go with the principle of least privilege: you don't need web access to these files, so you won't get it.
A more concrete reason is that framework sources can easily disclose the brand and version of a framework being used on a website (although this information can also usually be gained by examining the generated content); this in turn can make it easier for malicious users to exploit known or newly discovered vulnerabilities.

This is safer because if there is any misconfiguration in web server, then it is possible that script files (be it .php, .asp or whatever) can be spit out in plain text and potential attacker sees all your source code and defined passwords. So the best practice is to put only index.php file in webroot which in turn includes bootstrap script from outside webroot.
I remember one real world example - in Latvia, where I live, we have large social network "draugiem.lv" (in our country more popular than Facebook) and few years ago all their PHP source code leaked by misconfigured server, as I described earlier.

In addition to the standard reasons cited by the other answers - server mis-configuration, principle of least privilege, etc - it is worth noting that many frameworks, including Zend Framework, can use config files that are in formats other than PHP, e.g., .ini, .yml, etc.
If these were in the public-accessible web root, then - depending upon server config - they would be served directly to anyone who requests them. Since these config files typically contain sensitive information like db passwords, API-keys, etc, it is certainly desirable to make them as inaccessible as possible.
As an example, consider application/configs/application.ini. If the doc root were at the project-folder level, then a request for:
http://example.com/application/configs/application.ini
would deliver the keys to the castle.

Related

Confused On Higher Web Root Access For Secure Login

Going to try and mess around with forms of secure login now, and the php files that connect to the database are going to be stored above the web root, public_html, so they cannot be publicly accessed.
My first question is that people are saying you cannot invoke this php file with Javascript.
That makes sense because Javascript runs client-side and could expose information, but this leaves me a bit confused on how to invoke this php file securely.
Should I have another php file below the web root that invokes the content-sensitive one above the web root?
Would this be achieved with "../../some-folder-above-web-root/some-php-above-web-root.php", and if so isn't that revealing to the location of the php file in the web root? Or doesn't it's location matter since people cannot access it (.. hackers).
All in all I really just want to know how to communicate to a script above the web root, properly and securely.
Yes, you are correct. There should be a PHP file below the web root that will access the secured PHP files above the web root. In Zend Framework, there is a single index.php file, called the bootstraper, which does many things including:
set the error display level
set the include paths
define global constants
read the configuration files
load the library classes
get the front controller
configure the database connection
determine the route, per RESTful url's, and MVC
set Exception handling
call the requested controller
I would highly suggest using an MVC framework, they are industry standard, and have pre-built functionality for many common problems including secure logins. Zend Framework implements Access Control Lists style security, though you can easily role your own. Other notable frameworks are Drupal, Yii, Codeigniter, Symphony, CakePHP, and Joomla.
Other best practices for security are:
filter all file uploads based on mimetype, NOT file extension or filetype
filter all POST and GET data, based on the database table column type and length
sanitize all SQL strings before running them
change all the default login passwords on your servers, ex: Apache, MySQL, FTP, SSH, SVN, etc.
learn how to configure php.ini, httpd.conf, etc.
disable any services, modules, and plugins, not being used in your framework, PHP, Apache, and MySQL
fuzz your code
use unit tests
learn a bit about penetration testing
you can give those files READ ONLY permission for other, something like 754 (all permissions for root, read and execute for group, read only for other) for example, then you can read its contents using for example file_get_contents and a absolute path.
A common way to do this is have a config file (with the sensible info inside) outside the public web dir, read it using a absolute path, and then use it as variables.
If you want to EXECUTE a script outside the public web path you have to give EXECUTE permission to 'other' which isn't much secure.
Also regarding your question about javascript, it ins't about security: javascript code won't be executed in the server, where the file with sensible info is, it will be executed on the client browser, so there's nothing to read there.

Preventing directory scanning from Acunetix

I have a PHP enabled site, with directory-listing turned off.
But, when I used Acunetix: (web vulnerability scanning software) to scan my site, and other high-profile websites, it was able to list all directories & files.
I don't know what this is happening, but I have this theory: maybe the software is using English words, trying to see if a folder exists by trying names like "include/", "css/", "/images", etc. Then, maybe it is able to list files that way.
Because, if directory listing is off, I don't know what more there is to do.
So, I devised this plan, that if I give my folders/files difficult names like I3Nc_lude, 11css11, etc., maybe it would be difficult for the software to find the names. What do you think?
I know, I could be dead-wrong about this, and the idea might be laughable but, that is why I am asking for help.
How do you Completely! Forbid directory listing??
Ensure all directories from the root of your site have directory
listings disabled. It is typically on by default when you setup a
new server.
Assuming that directory listing in your webserver is not your issue,
keep in mind that any resources you have in your site: CSS files, JS
sources, and of course HREFs can be traversed with little or no
effort (typically a few lines of javascript). There is no way to
hide anything that you've referenced. This is most likely what you
are seeing reflected in the scan.
Alternatively, if you use SVN or other version control systems to
deploy your site, often these can be used to determine the path of
every file in your codebase.
Probably the most common mistake people make when first creating sites is that they keep all their files in the webroot, and it becomes somewhat trivial to figure out where things are.
IMHO the best approach is have your code in a separate directory outside the webroot, and then load it as needed (this is how most MVC frameworks work). You can control entirely then what can and can not be accessed via the web. You can have 100s of classes in a directory and as long as they are not in the webroot, no one will ever be able to see them, even if directory listing were to become enabled.
The checkers aren't using some kind of language-based brute force attack, that would be far too costly and invasive even for the most inept hacker. Your internet file sharing service (Apache, IIS, whatever) is serving up the structure to anyone who asks.
I found this solution at - it should apply to you, I hope.
http://www.velvetblues.com/web-development-blog/dont-get-hacked-6-ways-to-secure-your-wordpress-blog/
Hide Your Directory Structure
It is also good practice to hide your directory structure. By default, many WordPress installations enable any visitors to snoop and see all files in folders lacking an index file. And while this might not seem dangerous, it really is. By enabling visitors to see what files are in each directory, they can better plot their attack.
To fix this problem, you can do one of two things:
Option 1: Use An Index File
For each directory that you want to protect, simply add an index file. A simple index.html file will suffice.
Option 2: Use An .htaccess File
The preferred way of hiding the directory structure is to use the following code in an .htaccess file.
Options -indexes
That just sounds like a nightmare to manage. Focus on securing the files the best you can with all preventative measures. Don't rely on security through obscurity. If someone wants in, some random directory names will just slow them down slightly

Prevent scripts from stealing password in open source PHP project?

I'm currently developing a PHP framework. Other developers may create modules for the framework. Source code of these modules should reside in the framework directory.
Since the project is open-source, modules know location of the config file which has database password in it. How to protect passwords from malicious modules? Please check that modules may just require_once the config file and do harmful things!
Currently I'm storing Database passwords in a directory named config, and protecting it by a .htaccess file:
<Directory config>
order allow,deny
deny from all
<Directory>
But that is not sufficient to prevent scripts steal the password, is it?
I've read the thread How to secure database passwords in PHP? but it did not help me finding the answer.
In PHP, you can't. It's not a sandboxed language; any code you run gets all the permissions of the user it's running under. It can read and write files, execute commands, make network connections, and so on, You must absolutely trust any code you're bringing in to your project to behave well.
If you need security boundaries, you would have to implement them yourself through privilege separation. Have each module run in its own process, as a user with very low privileges. Then you need some sort of inter-process communication. That could be using OS-level pipes, or by having separate .php files run as different users running as web services accessed by the user-facing scripts. Either way, it doesn't fit neatly into the usual way PHP applications work.
Or use another language such as Java, which can offer restricted code with stronger guarantees about what it is allowed to do (see SecurityManager et al).
Unfortunately, PHP is not a very secure language or runtime. However, the best way to secure this sort of information is to provide a configuration setting that has your username/password in it, outside of your document root. In addition, the modules should just use your API to get a database connection, not create one of their own based on this file. The config setting should not be global. You should design something like this in a very OOP style and provide the necessary level of encapsulation to block unwarranted access.
I've got an idea that may work for you, but it all really depends on what abilities your framework scripts have. For my idea to be plausible security wise you need to essentially create a sandbox for your framework files.
One idea:
What you could do (but probably more resource intensive) is read each module like you would a text file.
Then you need to identify everywhere that reads a file within their script. You've got things like fopen for file_get_contents to consider. One thing I'd probably do is tell the users they may only read and write files using file_get_contents and file_put_contents, then use a tool to strip out any other file write/read functions from their script (like fopen).
Then write your own function to replace file_get_contents and file_put_contents, make their script use your function rather than PHP's file_get_contents and file_put_contents. In your file_get_contents function you're essentially going to be checking permissions; are they accessing your config file, yes or no, then return a string saying "access denied" if they are or you use the real file_get_contents to read and return the file if not.
As for your file_put_contents, you just need to make sure they're not writing files to your server (they shouldn't be allowed, imagine what they could do!), alternatively, you could probably use a CHMOD to stop that happening.
Once you've essentially rewritten the module in memory, to be secure, you then use the "exec" function to execute it.
This would take a considerable amount of work - but it's the only pure PHP way I can think of.
I am not sure if it is possible, however you could maybe make a system which checks the files in the module for any php code which tries to include the config file, and then warn the user about it before installing.
However it really shouldn't be your responsibility in the end.
A very good question with no good answer that I know of, however...
Have you seen runkit? It allows for sandboxing in PHP.
The official version apparently isn't well maintained any more, however there is a version on GitHub that is quite popular: zenovich/runkit on GitHub
Although the best solution is perhaps a community repository where every submission is checked for security issues before being given the OK to use.
Good Luck with your project
Well, I see no problem here.
If it's a module, it can do harmful things by definition, with or without database access. It can delete files, read cookies, etc etc.
So, you have to either trust to these modules (may be after reviewing them) or refuse to use modules at all.
Don't include your actual config file in your open source project.
The way I do it is a create just the template config file config.ini.dist
When a user downloads your project they have to rename it to config.ini and enter their own configuration information.
This way every user will have their own database connection info like username and password. Also when you update your project and users download your newest version, their own config files will not be overwritten by the one from your program.
This a a very common way to store configuration in open source projects - you distribute a template config file and tell users that they have to rename it and enter their own configuration details.
I don't think there is a way to prevent a module to capture sensible data from the actual framework configuration and send it to some stranger out there. On the other end, I don't think that should be your responsability to protect the user from that to happen.
After all, it's the user that will decide to install any module, right? In theory it should be him that would have to verify the module intents.
Drupal, for example, does nothing in this direction.
There is a worst problem, anyway: what'd prevent a nasty module to wipe out your entire database, once it is installed?
And, by the way, what could the malicious stranger do with your database password? At the very least you anyway need to secure the connection of the database, so that only trusted hosts can connect to the database server (IP/host based check, for example).

Securely storing database connection details. Why use .inc at all?

I am always reading that you should always store your database credentials outside of your document root because normally you would have them set to db.inc or something similar.
I can understand this and naturally it makes perfect sense.
What I don't understand is why you are making the file into one that you either need to set apache to hide or you need to put it into a secure location in the first place.
What is the issue with making it, say db.php - Then apache knows to execute the script first and return the output (which would presumably be blank in most cases).
Maybe I am being dumb and missing an inherent security flaw but is there any issues with just storing your details in a .php file? I mean Wordpress and other major open source PHP applications manage to get away with it, but is this because they can't make their script talk to folders outside of www or because it is just as secure as any other method?
Maybe I am being dumb and missing an inherent security flaw but is there any issues with just storing your details in a .php file?
A tiny slip up in the configuration of Apache, and the file starts being served raw instead of being processed by the PHP engine.
I mean Wordpress and other major open source PHP applications manage to get away with it, but is this because they can't make their script talk to folders outside of www or because it is just as secure as any other method?
They accept increased risk for increased convenience.
Storing files containing (database) credentials outside the document root is always a good idea.
Say, you upgrade Apache, but forget updating the configuration with PHP. Any file in the document root can possibly be downloaded without getting parsed.
Wordpress, Joomla, phpBB and others are made to be portable. That is, reside in one folder.

Why is it a good practice to remove PHP files from the htdocs directory?

Why is it a good practice to remove PHP files from the htdocs/public directory?
They are being parsed anyway, right?
if PHP files are at some point not parsed due to a configuration error or, say, a failing interpreter, there is no danger of the source code (and possibly passwords) being revealed to the world as clear text.
Also, human mistakes like renaming a .php file to .php.bak are less dangerous that way.
I had this once, years ago, when a colleague, from the Perl world and totally ignorant about PHP, decided to set "short_open_tags" to "off" on a server we shared, because short_open_tags messed with some XML experiment he had going (<?xml version="1.0"?>). That was fun! :)
and a second thing:
Calling includes out of context
Having includes (i.e. pieces of PHP code that is included elsewhere) under the web root makes you potentially vulnerable to people calling those includes directly, out of context, possibly bypassing security checks and initializations.
If you can't/won't avoid PHP code to reside in the web root, at least be sure to start each file checking whether it is running in the correct context.
Set this in your main script(s):
define ("RUNNING_IN_SCRIPT", true);
and add this to the 1st line of each include:
if (!defined("RUNNING_IN_SCRIPT")) die ("This file cannot be called directly.");
Yes, they are parsed. However, that is completely dependent on you or the server admin not screwing up the config files.
All it takes is a quick typo in the Apache config before Apache forgets to parse the PHP (I've had this happen). Since Apache won't know what to do with a PHP file after that, your source code just gets output as plain text, and can be immediately copied. Heck, it's even cached in the user's browser, so a malicious user can quickly copy all your code and browse it later at their convenience, looking for security holes.
You don't want your source to be visible even for a second. If you have no code files in the htdocs directory, this can't happen. They can easily be included into your code from outside the directory however.
Many MVC frameworks use this method of sandboxing for just this purpose.
The more executable PHP files you have, the more security risks you also have :
What if there is a problem in your configuration (it happens !), and the source code of your PHP file containing your database credentials is sent to the browser ?
what if there is some "bad" thing left in one of those files, you didn't think about, and no-one ever tested ?
The less PHP executable files you have... well, that's a couple of potential problems you don't have to care about.
That's why it's often considered as best to :
put under the document root only the PHP files that have to be called via Apache (like index.php, for instance),
and put outside of the document root the PHP files that are not accessed directly, but only included by the first ones (ie, libraries / frameworks, for instance).

Categories