PHP—"Defined or Exit" at the beginning of many files? - php

I have been inspecting some PHP source codes and I more often than not find files starting with
defined('__someconstant__') or exit();
I know that this prevents the file to be accessed directly if a previous file defining __someconstant__, but then I wonder if this is really necessary... Isn't there (even non-PHP based) a cleaner way of doing it without introducing this extra code in every file?

Isn't there (even non-PHP based) a cleaner way of doing it without introducing this extra code in every file?
Presence of such snippets indicate bad code structuring, namely code automatically executing in global scope. You shouldn't have this or exit(); code in pure function/class includes. It would be redundant there.
Code that does perform potentially dangerous actions shoult not be web-accessible in the first place. The or exit; approach is a workaround. It should always be accompanied by a FilesMatch and Deny from All in a .htaccess file however. Best set the whole include directory inaccessible.

To avoid those (useless) lines at the top of (nearly) each file, your could:
Store a public "controller" file (like index.php in a directory called web or public on which your web server's alias or virtual host points to
Store in other directories like lib, config, apps... all the files that should not be directly accessed through the webserver by simply typing an URL.
This is typically the structure of existing frameworks such as Symfony 1.x
Additionally you can (and certainly will, for URL rewrites) put a .htaccess file, but a server misconfiguration can incidentally disable it, so keeping source files in distinct directories is IMO better.

Adding to #NullUserException's answer...
Yes there are other ways of preventing a file from being accessed directly (.htaccess being one), but for software that is shared with a wide audience, you can't really rely on those technologies being there. You can rely on a simple condition at the top of the files though.

Related

How to invoke a php file that is located outside public_html

Im creating a website and i am very OCD when it comes to security so i heard that if you store all of your .php files outside of your public_html folder and invoke them with another .php file that is inside your public_html folder then your risk of an attack is lower. Is this true, if so how would i do this. I read something about using .htaccess but I'm not sure if that was the correct way to do it. I though i could maybe use include but im not sure how include works with parameters.
There isn't a huge amount of extra protection offered by this strategy. Mainly, it ensures that if your server is misconfigured and fails to send PHP scripts to the PHP interpreter, it doesn't allow PHP code to be sent directly down to the browser.
You don't store all your PHP scripts outside document root. You typically store only files which are not intended to be accessed publicly outisde the doc root. Store your include files outside the doc root and include them as you would any file. Store files which are are public views inside the document root, as they need to be web-accessible.
There is a design pattern known as the Front Controller pattern whereby a single index page (index.php) accepts routes and includes other files as appropriate. Numerous PHP frameworks support this out of the box.
See PHP include function: http://www.php.net/manual/en/function.include.php
However, I doubt what you're trying to do will increase security. Where did you hear that it increases security?

What is an .inc and why use it?

I often see examples in PHP that include.inc files. What is the meaning of .inc? What it is used for? What are the disadvantages and advantages of using it?
It has no meaning, it is just a file extension. It is some people's convention to name files with a .inc extension if that file is designed to be included by other PHP files, but it is only convention.
It does have a possible disadvantage which is that servers normally are not configured to parse .inc files as php, so if the file sits in your web root and your server is configured in the default way, a user could view your php source code in the .inc file by visiting the URL directly.
Its only possible advantage is that it is easy to identify which files are used as includes. Although simply giving them a .php extension and placing them in an includes folder has the same effect without the disadvantage mentioned above.
If you are concerned about the file's content being served rather than its output. You can use a double extension like: file.inc.php. It then serves the same purpose of helpfulness and maintainability.
I normally have 2 php files for each page on my site:
One named welcome.php in the root folder, containing all of the HTML markup.
And another named welcome.inc.php in the inc folder, containing all PHP functions specific to the welcome.php page.
EDIT: Another benefit of using the double extention .inc.php would be that any IDE can still recognise the file as PHP code.
Generally means that its a file that needs to be included and does not make standalone script in itself.
This is a convention not a programming technique.
Although if your web server is not configured properly it could expose files with extensions like .inc.
It's just a way for the developer to be able to easily identify files which are meant to be used as includes. It's a popular convention. It does not have any special meaning to PHP, and won't change the behaviour of PHP or the script itself.
This is a convention that programmer usually use to identify different file names for include files. So that if the other developers is working on their code, he can easily identify why this file is there and what is purpose of this file by just seeing the name of the file.
Just to add. Another disadvantage would be, .inc files are not recognized by IDE thus, you could not take advantage of auto-complete or code prediction features.
In my opinion, these were used as a way to quickly find include files when developing. Really these have been made obsolete with conventions and framework designs.
Note that
You can configure Apache so that all files With .inc extension are forbidden to be retrieved by visiting URL directly.
see link:https://serverfault.com/questions/22577/how-to-deny-the-web-access-to-some-files

PHP core code directory structure

I'm looking to centralize a lot of my web applications code, so that multiple components have access to the same core functionality. This is how I have the website set up:
/var/www/website - domain.com
/var/www/subdomain1 - subdomain1.domain.com
/var/www/subdomain2 - subdomain2.domain.com
Naturally I've had a lot of trouble when it comes to the duplication of common functionality, as any changes made to one area would also need to be applied to other areas. My proposed solution is to create a new directory in /var/www which will contain all of the core scripts:
/var/www/code - core code
I would then set the PHP include directory to /var/www/code, so scripts can include these files without having to specify the absolute path.
Can you think of any more efficient ways of centralizing the code code?
Many thanks!
Your approach is good enough for this purpose.
Little suggestion:
store your front-end scripts in directory like /var/www/website/www instead of /var/www/website. There will be index file and ajax processors and scripts like that. But your project-based inclusions (as well as other miscellaneous stuff) would be stored in directory like /var/www/website/includes. It is simple yet efficient defense from hacker attacks on your inclusion files
so, your document roots will be in /var/www/website/www (domain) and /var/www/website/subdomain/www/ (subdomain)
It seems that you are thinking correctly :
Share Code between multiple PHP sites
It's only a suggestion, but you should put the public content in the /var/www/* which may end being publicly accessible—either because of your http server or because of some misconfiguration—and create some other directories for your shared code/libs like /usr/local/lib/php/*.
For more security you should frame it with open_basedir adding the private and public dirs—as well as upload and session dirs.
And don't forget to version your libs, e.g.:
/usr/local/lib/php/myLib-1.0
/usr/local/lib/php/myLib-1.2
etc.
Thus, you'll be able to make changes without breaking everything.

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).

Is "do not load this page directly" really necessary in PHP?

I was going to ask what the best way to do this is, but then decided I should ask whether or not it is even necessary. I have never seen it done in JSP development, but it appears to be common practice in PHP. What is the reasoning behind this, and if I do not protect against this, what else should I be taking into consideration?
The reason this is more common in PHP than other similar languages has to do with PHP's history. Early versions of PHP had the "register_globals" setting on as a default (in fact, it may not have even been a setting in really early versions). Register_globals tells PHP to define global variables according to the query string. So if you queried such a script thusly:
http://site.com/script.php?hello=world&foo=bar
... the script would automatically define a variable $hello with value "world" and $foo with value "bar."
For such a script, if you knew the names of key variables, it was possible to exploit the script by specifying those variables on the query string. The solution? Define some magic string in the core script and then make all the ancilliary scripts check for the magic string and bail out if it's not there.
Thankfully, almost nobody uses register_variables anymore, but many scripts are still very poorly written and make stupid assumptions that cause them to do damage if they are called out of context.
Personally, I avoid the whole thing by using the Symfony framework, which (at least in its default setup) keeps the controllers and templates out of the web root altogether. The only entry point is the front controller.
If you include everything from outside web root then it's not an issue as nothing can be loaded directly.
Well, This is to prevent sensitive includes from being sent to the web-server directly. It's certainly not an all-inclusive security measure, but it could help with your particular setup.
If however, your user was in a position to include the file from their own script, it won't help at all
I emit a 404 page, not as a serious security measure but only because I don't like leaking information about the internals of a site, even the names of internal files.
But if the file just contains functions then there's no real harm in omitting the check.
It also isn't just a security feature in php but more of how many MVC based PHP sites function. If for example in SugarCRM you were to call a module file directly the page load would fail because the controller, view and model were not previously loaded and you'd have no db config/connection information either, so to make sure all dependencies are loaded the users is forced through a known entry point - i.e. index.php
I just found an approach in the .Net MVC system that you could replicate for PHP using Apache Rewrites, .htaccess files or if you are using IIS, a web.config file.
As the MVC pattern doens't need the user to directly access aspx files these are not served and a 404 is sent instead. If you have a naming convention for included files "inc.php" for example you could redirect *.inc.php requests to a 404 for specific folders - in Apache Rewrite supply R=404 at the end of the rule will return that HTTP status to your client.
Some of these examples may help: Apache Rewrite Examples
As already mentioned in some of the other answers, you shouldn't need to do this. If a file isn't supposed to be served up by the web server, you shouldn't leave it within the web folder. Includes should be placed in a directory outside the web root.
Apart from that, the proper way to tell the user that a page doesn't exist, is by emitting a status 404, using:
header("HTTP/1.0 404 Not Found");
exit;
If you don't do this, it is hard for non-humans (Eg. search-engines) to distinguish between a regular page and a non-page.
This is very important because if you are editing your site running Google Toolbar, it will find your inner php files and then put them into search results. At best this will create an awkward experience for users but if you are a sloppy programmer, could reveal database connection information.

Categories