PHP include file extensions? - php

For required/included files in PHP, is it better to use .inc extensions vs .inc.php vs .php extensions?

Sometimes people use the .inc extension and then do some server configuration to keep .inc files from being accessed via a web browser. This might be good, if done absolutely correctly by a knowledgeable sysadmin, but there's a better way: Any file that's not supposed to be accessed by web users should be kept outside your document root. Once these files are off the web, so to speak, you can use whatever extension you want. .php is definitely a sensible choice for syntax highlighting, general sanity, and so on.

Apache can sometimes (due to bugs or severe crashes) serve .php files as text (happend to me a few times on shared hosting).... I think you can use any extension you want as long as you don't store your files in a public folder.
Let's say your site is in /home/user/public_html/
create another folder /home/user/lib_php/
have the files:
(1) .../lib_php/one.class.php with
class one {
//...
}
(2) .../lib_php/two.function.php with
function two() {
//...
}
and you have the main index.php in /public_html
<?php
include_once('../lib_php/one.class.php');
include_once('../lib_php/two.function.php');
$x=a;
$b=two($x);
$c=new one;
//etc..
or
<?php
require_once('/home/user/lib_php/the.file.php');
This way you are taking every precaution the files are not reachable directly but can be used by your scripts...

My personal preference is that anything in the document root is a .php file, to indicate it's directly executable by the web server, and anything that's a library is a .inc file stored in a parallel directory, to indicate it's NOT directly executable.
My standard configuration is
/home/sites/example.com/html/ - anything here is 'safe' to expose if PHP fails and serves up raw code
/home/sites/example.com/inc/ - libraries, config files with passwords (e.g. the database connection class with DB credentials), etc.. Anything that shouldn't be exposed as there's no reason for it.
While you can certainly configure Apache to deny access to .inc files and keep them inside the webroot, then you're depending on Apache to keep you safe. If PHP can fail within Apache and expose your code, then the .inc blocks can ALSO fail and expose your code's innards as well.
Of course, if Apache's coughing blood all over the floor, there's no reason that the directory traversal protection can't fail as well and let someone do http://example.com/../inc/seekritpasswords.txt.
At some point you just have to accept that if something's stored anywhere on the web server, there's a possibility that a failure may allow access to the raw data and expose everything. How much time and effort you want to expend on protecting against that is up to you.

Related

Composer: where should I put the "vendor" folder?

I have concerns that are similar to what were addressed here. I'm using Composer to install Amazon AWS components to set up a SES (email) service.
According to the Amazon documentation, I need to include autoload.php in order to use the classes that I installed. This means that the autoload.php must be in my web directory (/var/www/html).
I didn't fully understand the answer provided to the SO question I previous mentioned, but it essentially says that the vendor directory should NOT be in the web directory. But if I do this, how will I require the autoload.php file, which is in the /vendor directory?
Overall I am very confused about how I should be properly setting this up. Any help would be appreciated.
Edit: This article also suggests putting the /vendor/ folder in the web directory. Is this the standard? What security risks should I be looking out for? Because there are no index.html files or anything in any of the folders, the directories of all the files that were installed can be seen and accessed freely. Surely this can't be a good thing?
The "web directory" is the directory directly served via HTTP to anyone asking with the right URL. So if anyone thinks there is a folder "/foo" hosted on your domain, and you didn't take precautions, and there is in fact that folder, and it does not contain a file that would be served as the directory index, anyone asking probably would get the directory listing of that folder, listing all files.
Now the difference between such a web hosted folder and the require statement in PHP is that PHP does not use a URL pointing at a publicly accessible HTTP hosted folder, but uses a filesystem path pointing to a file.
And most beginners mix this up: Because PHP at starter level is all about having a bunch of scripts spread around the web directory, which emit a lot of HTML containing links to other scripts, they get the idea that the links in HTML and the file paths in PHP are the same and have to be. This is wrong. They don't have to be the same, they are the same because no better approach has been selected.
So here's how a modern web application is constructed. If you deploy the whole project, the main directory on the server might be called /var/www/projectX. Inside this container are some files like /var/www/projectX/composer.json. Because of this there will also be a directory /var/www/projectX/vendor. Additionally, somewhere would be one PHP script that's being accessed (I delay the info HOW it's being accessed for now), and that location should either be A) /var/www/projectX/script.php or B) /var/www/projectX/public/script.php. Those two scripts want to use Composer provided classes and need to include the autoloading.
Because of the file location, the script in location A needs to run require 'vendor/autoload.php';, and the script in location B needs require '../vendor/autoload.php';. This is simply a matter of using the correct relative path from the script to the autoload file. You could even use an absolute path in both cases: require '/var/www/projectX/vendor/autoload.php'; will also work. The main point here is: It does not matter HOW you require that autoload.php file as long as it gets executed by the script. The path does not affect anything.
Now the HTTP hosting and accessing the scripts. The webserver has at least one directory configured that is being exposed to the outside world as the main directory of the domain. This is called DOCUMENT_ROOT, and it can be ANYWHERE. Now it depends on the configuration of your server which directory is preselected, and if you can change that setting (either by administrating your server on the command line, or by clicking some settings in a GUI).
If your server has the directory /var/www/projectX set as the document root, all the world can access the script in case A as http://example.com/script.php, as well as the script in case B as http://example.com/public/script.php, and also the vendor folder as http://example.com/vendor/.... This is not great, but could be avoided by placing .htaccess files inside or otherwise restrict access.
The better solution is to tell the server to only serve the directory /var/www/projectX/public as document root. This will prevent HTTP access to script A and the vendor folder, and access to script B is done via http://example.com/script.php.
In both cases, both scripts successfully include the autoloading of Composer because the restrictions of HTTP access do not apply to filesystem access.
Bad website hosting allows you only to use the first scenario, with the only accessible directory for you being directly the document root, without a method to change it.
More sophisticated website hosting ís using a fixed subdirectory like public or html or webroot as the document root, allowing you to hide sensitive files from ever being served via HTTP.
The best website hosting allows you to select which subdirectory should be hosted as document root.
In any case, the path pointing from a script to Composers autoload.php is not affected at all.

Protect file in web root but give access from php

I have a situation where I want to protect a file from public access, but enable read and write from php. The file contains sensitive information like passwords.
The problem is that
I cannot put the file outside the web root (server security restriction on access from php)
I would like to avoid mysql database.
Also I would try to avoid .htacess files.
So if I make a folder, say private, in the web root, and do
chmod 700 private
Then, if the file to protect is private/data, I do
chmod 700 private/file
will this be a safe setup? So now I can read and write to the file from php but it is not accessible for the public?
Is this a safe setup?
PHP runs as the same user as the webserver so if PHP can read it, so can your webserver (and vice versa).
If you don't want to use .htaccess there is another trick: save the file as a .php file. Even if someone accesses the file from the web they can't see the source, they might just get a white page or maybe an error depending on what exactly is in the file.
If you're running suPHP or fastCGI php, you can use a setup similar to what you've described to limit access to files. Otherwise, PHP will use the same user as the web server, and any file PHP can access is also accessible via url.
If want to keep the restrictions stipulated (which are rather strange), and as (i guess) you do not wish/have access to apache config directives, consider adding PHP to some group and give the group only rights to the file, ie. apache cannot read (if its not in root/wheel).
Or make it a valid .php file (so only php would be invoker when the file is requested) which returns nothing or redirects when invoked with php. or just cipher it.

folder to save files that are retrieved with require in document tree

I'm building a website based on php and i want to ask where to put files that are retrieved with a require statement, so that they can not be accessed from users with their browser.
(for example a php file that connects to my database)
EDIT actually i think the better way is to put them outside the public root because apache tutorial says htaccess will have a slowdown impact. it can be done with adding a ../
for example require("../myFile.php"); (At least this works in my server)
Best regards to all
That depends on the web server configuration. Usually (or at least in all cases I witnessed), you have a document root which cannot be accessed by users with their browser, with in there a folder containing all public material (often called htdocs, httpdocs, public_html or anything of the kind. Often, you can place your PHP include files in that root, and then require them using require("../include_file.php");
However, it depends on the configuration whether PHP can include files outside your public folder. If not, a .htaccess file is your best option.
If you place those files outside the document root of your webserver users cannot access these files with a browser.
If you use apache you can also place these files in a directory to which you do not allow access with a .htaccess file.
And as a last remark, if your files do not generate output, there is no way users can check the contents of the files.
If you mean source code then it is not visible for users, if you want hide folder contents use .htaccess directive Options -Indexes to hide files, if you can access php source your server configuration is wrong and it is not parsing php files.
You normally place them into a directory that is not accessible over the webserver (outside the document or web root). Sometimes called a "private" directory.
You then include/require the file from that path as PHP has still access to the files.
See also:
placing php script outside website root
disable access to included files - For a method if you're not able to place the files in a private directory.
Just make them secure with .htacces!
Here's a very clear tutorial for protecting files with a password. If you don't need direct access to the files per browser, or only your scripts need access, just block them completly by changing the code between
<Files xy>
change this bit here
</Files>
to
Order allow,deny
Deny from all
Then you won't need your htpassword file anymore either!
You need to put these files outside of public-facing folders on your web server. Most (all?) web hosts should have the capability to change the document root of the website.
For example, let's say that all of your files are served from the following directory on your host: /home/username/www/example.com/
This means that anything that resides inside that directory is visible to the internet. If you went to http://example.com/myfile.png it would serve the file at /home/username/www/example.com/myfile.png.
What you want to do is create a new directory called, for example, public which will serve your files, and point the document root there. After you've done that, the request for http://example.com/myfile.png will be served from /home/username/www/example.com/public/myfile.png (note the public directory here). Now, anything else that resides within the example.com directory won't be visible on your website. You can create a new directory called, for example, private where your sensitive include files will be stored.
So say you have two files: index.php, which serves your website, and sensitive.php which contains passwords and things of that nature. You would set those up like this:
/home/username/www/example.com/public/index.php
/home/username/www/example.com/private/sensitive.php
The index.php file is visible to the internet, but sensitive.php is not. To include sensitive.php, you just include the full file path:
require_once("/home/username/www/example/com/private/sensitive.php");
You can also set your application root (the root of your websites files, though not the root of the publicly accessible files) as a define, possibly in a config file somewhere, and use that, e.g.:
require_once(APP_ROOT . "sensitive.php");
If you can't change the document root, then what some frameworks do is use a define to note that the file shouldn't be executed directly. You create a define in any file you want as an entry point to your application, usually just index.php, like so:
if (!defined('SENSITIVE')) {
define('SENSITIVE', 'SENSITIVE');
}
Then, in any sensitive file, you check that it's been set, and exit if it hasn't, since that means the file is being executed directly, and not by your application:
if (!defined('SENSITIVE')) {
die("This file cannot be accessed directly.");
}
Also, make sure that your include files, when publicly accessible (and really, even if not), have a proper extension, such as .php, so that the web server knows to execute them as PHP files, rather than serving them as plain text. Some people use .inc to denote include files, but if the server doesn't recognize them as being handled by PHP, your code will be publicly visible to anyone who cares to look. That's not good! To prevent this, always name your files with a .php extension. If you want to use the .inc style to show your include files, consider using .inc.php instead.

Protect logfiles for php applications

I log sensitive information in a a log file lets call it "mylogfile.log". This file should in no circumstances be access from the outside/web.
I already protect it by using a .htaccess file but what i would like some extra safeguard like using a fileextension that is protected by the system. Is there any such?
The reason for the extra security is that this webapp is distrubuted to clients that could change or remove the .htaccess file. Also .htaccess override needs to be enabled in Apache.
You should put it outside of the document root.
If /var/www/your-site.com/public matches the URI your-site.com (public/index.html --> your-site.com/index.html etc), then log files will not be readable if you place them in /var/www/your-site.com/logs
When distributing an app like this, I would always make sure that you, given your limited and controlled space, do not use your "base folder" as the document root of the webserver, just to get some privacy around it.

Hiding PHP Files Outside WWW for Security

I've got a "globabVars.php" doc in my own little framework that contains database connection vars etc... I'm thinking would be neat to store outside of the web facing directories to keep it a little more secure. But, then I was thinking, is it really THAT much more secure? I mean, if someone were able to look at my .php files as a whole (without the server processing them) they would be INSIDE my server looking at all my files anyway...
Thoughts?
Moving a config file outside of the web root can prevent this file from getting leaked if you accidentally mis-configure apache. For instance if you remove Apache's mod_php then all .php files will be treated as text files. I have seen config files moved outside of the web root on production systems for this reason, and it did stop the file from getting leaked! (An admin iced the config during an update, doah!). Although this doesn't happen very often.
If an attacker can control the path of one of these functions: file_get_contents(), fopen(), readfile() or fgets() then he can read any file on your system. You also have to worry about sql injection. For instance this query under MySQL can be used to read files: select load_file("/etc/passwd").
To mitigate this issue, remove FILE privileges from your MySQL user account that PHP uses. Also do a chmod 500 -R /path/to/web/root, The last 2 zeros keeps any other account from accessing the files. You should also follow it up with a chown www-data -R /path/to/web/root where www-data is the user account that php is executed as, you can figure this out by doing a <?php system('whoami');?>.
It means noone can access it via a URL by default.
You can hide with .htaccess if it is in your docroot, but storing it above the docroot is just that bit safer.
You can have it read via PHP if your application is prone to directory traversal attacks.
Yeah, you are right. There is a very small difference.

Categories