separate php file as template - security hazard? - php

I was looking at templating systems for php, and I've come to believe that pure php code seems to be the solution I want to use.
I'm the lone developer, so there's no designers who need a nerfed arena to work in. Template engines like smarty seem to suffer from the "Inner-platform effect". If I stick with good practices ( pre-computed values, use only foreach ), I think this will work.
My goal is to have a single source for the string of the html shared by each page. My thought is that a separate php file, accessed via include, is a good way to meet this goal.
However, I'm concerned that that might pose a security hazard for the site -- I can't think of anything specific at the moment, but someone could guess the name of the template and request it directly, perhaps exposing something they needn't see. (I suppose I could put in a check to see if it itself is the request.) I have a hunch this could be bad, so I don't want to go ahead and do it, create what I feared would happen, and then throw that work away.
If a separate file is not the best idea, what else should I use to basically store a string for the whole site? A string constant in an include, that I could use in sprintf()? A function that returns the html string from arguments of the page-specific html parts?

Files that should not be served via HTTP should be stored in a directory from which your webserver will not allow anything (not PHP, at least) to be served to the users.
Two possibilities :
put those files outside of the DocumentRoot
or put those files in a sub-directory, from which Apache will not be able to serve any file.
Such "not served" files generally include stuff like :
configuration files
libraries / frameworks
data files (like an SQLite database, for instance ; or i18n files)
The first solution : your directories could look like this :
data/
i18n/
i18n/your-file-here.php
library/
www/ <- this is Apache's DocumentRoot
index.php
another-php-file.php
And for the second solution, just disable access to the directory containing your "data" or "libraries" files, putting in it a .htaccess (If your webserver is Apache) file containing something like
Deny From All
With that, Apache will not allow anyone to directly access via HTTP the files in that directory, but your executable PHP script (in another directory) will still be able to include them.

Simple, really; Name the file whatever you want, but use ".inc.php" as the extension, then include this line at the top of the file:
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
die;
}
this will kill the script if the file is accessed directly.
EDIT: Pascal Martin's solution is probably more in keeping with BCP, whereas mine is more quick-and-dirty. I've used both, and either seems to be fine.

I like using a separate template file as well. Generally I'll define a constant in my config file and then put a check for that constant at the top of the included file like such:
Set constant in config:
define('_VALIDPAGE', true);
Check constant in included file:
defined('_VALIDPAGE') or die('Not allowed');
This makes it so that the included file can only be loaded from within your application.

you're right in that php is a fine templating system in itself, as long as you stick to a certain subset of it in the "template" files. but insistance on a single template per web page is impractical: more often than not you'll find that you have fragments duplicated over several templates.
anyway, separate files are fine. putting templates into a directory (tree) separate from the source directory (tree) is in my experience bad idea: the conceptual distance grows, you loose sight of what's really used and what's not, and as a result, you have quite a few templates that are dead but not buried, since their state is not so obvious.
my suggestion: keep the "templates" together with "program" files, protected with appropriate web server configuration
DocumentRoot /www
AddType application/x-httpd-php .php
<Files ~ \.tpl$>
deny from all
</Files>
/www/
dir1/
file.php
file.tpl
another-file.tpl
dir2/
other-file.php
other-file.tpl
yet-another-file.tpl
...
common/
shared-file.tpl
another.tpl

Related

How to secure a PHPMailer file

Just finished doing a simple mail transfer at my site using PhpMailer
I got 3 question about it -
I have read that's needed to store your credentials on a different file, read that there's 2 options - ini/php, which one would be better and how exactly this file should look like.
Regarding the directory of the credentials file, read it should be located outside the web root (just one level above its fine?), in that case how do I call it from inside the web root?
On the same matter, should the Mail.php itself be located on the site directory? or should I take it out as well?
It's generally safest to put values like these in .php files because they will render to nothing, unlike a .ini file which will usually render as plain text.
Yes, one level above is fine - it means that the file does not have a public URL of its own. From a script running inside the web root, you'd just load it with require '../settings.php';
You don't say what Mail.php is, but generally any other PHP scripts can stay put. Things like class definitions are safe because they have no effect when run directly (or at least should have no effect, if you've written them safely!). That said, it's common to put your composer vendor folder outside the web root since you don't necessarily have control over what ends up in there.

Accessing outside of public_html or httpdocs

In a way to secure my files from outside access, I am considering placing all the included files outside the public_html folder or the httpdocs folder.
However, this comment is saying that nothing should be kept outside of the public folder that handles user input data.
What is the best and most ideal practice for this? My thinking would be to have a .htaccess point route EVERYTHING to an index.php, and the index.php includes all the neccessary files such as database connections and whatever else, and also includes the .php file which would have the HTML and PHP inside it for the main body content of the page.
Can anyone tell me if there is anything wrong with that, and why?
However, this comment is saying that nothing should be kept outside of the public folder that handles user input data.
The comment uses the word direct. Includes are handling the data indirectly.
My thinking would be to have a .htaccess
Configuration is better handled in the main configuration file if possible. .htaccess marginally is less efficient (and scatters configuration across your webroot).
point route EVERYTHING to an index.php, and the index.php includes all the neccessary files such as database connections and whatever else, and also
The front controller pattern is a perfectly reasonable approach.
includes the .php file which would have the HTML and PHP inside it for the main body content of the page.
Simply including that can start to create a bit of a mess. I suggest investigating the MVC pattern.
The comment you are referring to says that nothing that handles input or output directly should be outside the document root.
On the other hand, it's perfectly fine to place library code outside the root. If you use index.php as a single entry point to your application, pretty much the only things that should be web-accessible in addition to that script would be your assets (css, js, images, etc).

Easy and efficient way of breaking up html code into several files and using php's include()

Currently, for things like a header, footer or common sidebar object, I create a custom .php file and do something along these lines:
echo '
<some><html><here>
';
and then include it on the pages that I want it to appear:
include('path/to/file');
The only problem with this is that someone can point their browser to my .php file and view part of html on its own. It isn't a huge deal, but it seems unprofessional and a little careless. Is there a better way of doing this?
The simplest way is to move all those files outside the DocumentRoot / public directory and include them from there. Something like:
include '../pages/header.php';
// rest of the script
include '../pages/bottom.php';
Anyway that's the purpose of that directory - to only hold things that are meant to be accessed directly.
Of course, the first step after this would be to look into having only one index.php file which filters all the requests (permissions, filtering, rewrites, etc) and includes whatever is necessary based on the request (this is called a Front Controller and there are also a few lightweight frameworks which already implement it). Here's a starting point: https://github.com/adrian-gheorghe/basic-website/blob/master/public/index.php
Put the included php files in a separate directory, and make this directory inaccessible from the outside (using .htaccess with Apache, for example).
You must restrain the access to other files in the server configuration.
WordPress pretty much does what you are currently doing: it stores all of the theme files in /wp-content/themes/THEMENAMEHERE/, and you can access the files to there directly. It's not that big of a concern, as users can't exactly do anything harmful, but if you care, you can store your files in a separate directory (as other answers have mentioned), or configure httpd.conf or .htaccess to block access to the particular scripts.

PHP: Is it secure to use index.php as the bootstrap?

I ask because it seems like the only thing ever called in a proper app index.php file is the require_once bootstrap file. I'm assuming this adds a layer of security but if not, this pattern seems pointless. Why not just use the index.php file as the bootstrap? Any opinions, cautions, thoughts etc. are appreciated!
(By the way, my htaccess file is routing all requests to the index.php file...)
There is no inherent security difference, no matter whether you have your bootstrapoing process in the index file or a separate one.
Having a separate file is usually due to organization concerns (e.g. to have a file that can be included from elsewhere to import your app's functions, or to put all the tasks in properly named files, or to make it especially easy to add custom extensions to the boot process).
However, configuration files containing sensitive information - sometimes, more rarely, even all PHP files at all except for the index file - will be placed outside the web root where possible. That will make a security difference in that PHP files can not be accessed from outside in case of an accidental server misconfiguration.
in a secure enviroment only the index.php lies in the document root, all other PHP files should be outside document root, so it makes sense when the index.php file is only including a Bootstrap file outside the document root.
I don't know of any vulnerability that this exposes. Dropping a blank index.html or index.php into a folder can prevent an attacker from obtaining a directory listing if apache is misconfigured.

PHP include file strategy needed

I'm in the process of setting up a php project, but am not very familiar with how to properly use php's include/require commands. My layout currently looks like this:
/public --apache points into this directory
/public/index.php
/public/blah/page.php
/utils/util1.php -- useful classes/code are stored in other directories out here
/dbaccess/db1.php
dbaccess/db1.php
require '../utils/util1.php
public/index.php
require '../dbaccess/db1.php'
public/blah/page.php
require '../../dbaccess/db1.php'
The problem is this from the php 'include' documentation:
If filename begins with ./ or ../, it is looked only in the current working directory
So public/blah/page.php fails because it includes dbaccess/db1.php which blows up when it tries to include util1.php. It fails because it's relative path is from the original script in public/blah/, not from dbaccess/
This seems pretty stupid -- db1.php has to just know where it's being included from which isn't going to work.
I've seen strategies like this:
require_once dirname(__FILE__) . '/../utils/util1.php');
That apparently works since now the path is an absolute path, but just seems really bizarre to me.
Is that normal? Should I continue down that path or am I missing something obvious here?
Usually, the standard conventions are thus: like #grepsedawk said, you'll want to define a constant that contains the root of your project folder and if you can the root of your includes folder:
define('APP_ROOT', dirname(__FILE__));
define('INCLUDE_ROOT', APP_ROOT . "/includes");
Note: the constant name needs to be a string!
Also, you'll notice I'm using dirname(__FILE__);. If you place your constants definition file in a subdirectory, you can do a dirname(dirname(__FILE__));, which is the equivalent of a ../.
Now some other caveats. While PATH_SEPARATOR is a cool constant, it is not needed. Windows accepts / or \ in path names, and since Linux only users / as a path separator, go ahead and always use a / instead of mucking up your code with repeated references to PATH_SEPARATOR.
Now that you have your root constants defined, what you'll do when you need a configuration file included is a simple:
include INCLUDE_ROOT . '/path/to/some/file.php';
You'll probably want your constant definitions (the define(...)'s above) in a bootstrap script in your root directory:
www_root/
index.php
bootstrap.php
The bootstrap will contain the defines (or an include of the constants file), as well as an include of any files that will be required by EVERY page.
And finally the last standard convention you may not use, but if you start doing object oriented programming, the most common method (the PEAR standard) is to name your classes by using an _ to separate namespaces:
class GlobalNamespace_Namespace_Class
//...
And then organizing your file structure mapping name spaces to subdirectories (literally replacing all _'s with /'s):
include_dir/
GlobalNamespace/
Namespace/
Class.php
And using __autoload() functions to load your classes, but that's another question.
Have a configuration script that sets the "INSTALL ROOT" of your project and then use absolute paths. Relative path with multiple includes is a headache in php.
DEFINE("INSTALL_ROOT", "/path/to/www/project")
require_once(INSTALL_ROOT . '/util1.php')
in my config / setup file, i do something like
define('MYAPP_BASEDIR',realpath('.'));
then i reference everything relative to that.
... if your include directory relates specifically to class files and you are able to name them so that the include file name could be derived from the class, you might like to look into spl_autoload_register().
this latter part isn't a direct answer to your question, but it's very handy if you're doing includes for each class you use.
Keep in mind, it starts in the current working directory and then looks through the include paths. If you want to reference all of your paths from some central root directory (or many) you can add that directory in the php.ini file or you can do it programatically with set_include_path( $path.PATH_SEPERATOR.get_include_path());
I suggest an abstraction strategy.
In your application page area, have a single file that all pages include.
This "local" include file has one job: find the include file that is outside the application page area. It then includes that. It can probably be as simple as <?php include dirname(__FILE__).'/../include/include.php/'; ?>
This second file is the single entry point into your library structure. It, or something else it includes, has the job of finding where everything is and including it.
This structure means you have just one file as your library's entry point and how it finds the rest of the library is not the application pages' problem. It also means you have just one file in your application area which knows how to find your library's entry point.
If you need a way for different application pages to load different things, I would suggest a modularisation approach. This can either be a global array you set before the master include, or a function you can call to request libraries by name. Yes, this is a slightly fancier way of your master library file declaring a constant of where everything is -- but it removes the temptation of doing include LIBRARY_DIR.'/utils/util.php'; which straightaway makes it unnecessarily difficult to move util.php out of utils and into misc/util at a later date.
The other advantage of the chained files is that it is then much easier to make your codebase relocatable, which makes it possible for multiple versions to be runnable. And it makes it possible to have one tree for the application and another for your library. Which means another application could use your library. In fact, you could extend the chaining a bit more if you want to help with the isolation further.
You're right, your scripts doesn't have to know the physical path where your includes are.
IMO the location where the includes are should be configured in the PHP.INI file (or .htaccess if you preffer).
Suponse your includes (utils and database are stored here /home/scott/php_includes/).
PHP.INI:
include_path=.:/home/scott/php_includes/
Now your scripts can include the libraries in this way:
dbaccess/db1.php:
require_once 'utils/util1.php';
public/index.php
require_once 'dbaccess/db1.php';
public/blah/page.php:
require_once 'dbaccess/db1.php';
A lot of people have provided good solutions, but I've just got one performance-related remark while talking about includes and requires.
If you start include'ing and require'ing a lot of files, it can be tempting to use include_once or require_once. Cachegrinds of scripts that use a lot of _once's have shown that they really slow down performance as the script has to stop what its doing to scan and make sure the file hasn't been included already. Eliminating as many of the _once's as you can will help a lot.
There was perfect solution - pecl extension called "pwee" - it allowed user define his/her own extern superglobal constants / variable using XML file. Thus you were able to use absolute path as I recomend in such form:
require_once APP_ROOT."/path/to/your/script.php";
The advantage of such solution was:
accessible from everywhere
no server load - everything in server memory
The XML file contained
<Environments>
<Application name="www.domain.com" namespace="">
<Constants>
<Constant name="APP_ROOT" value="/full/path/to/project/source" />
</Constants>
<Constants>
<Constant name="WEB_ROOT" value="/full/path/to/project/public" />
</Constants>
</Application>
</Environments>
link to pwee project
You should distinguish these cases of inclusion:
standalone library - all includes should be relative - to let user integrate it to his/her project easily
executable scripts in your public directory - contain absolute includes to project files and to standalone libraries public files (which has relative includes inside - transparent to user). Using the APP_ROOT constant is elegant way.
a,link,script, form html elemets and header forwards should use relative path when diving into tree hierarchy and absolute path when using common files from higher levels of hierarchy
In case of relative path use this form:
require_once "./relative/path/to/script.php";
Why do I use past tense? Because the project is not more supported - works only with Php4. If anyone knows similar solution with support, please let me know.
The best way to do that is to build flexible autoload system.
Simple map of classnames and proprietary patches. Then any internal require_* or include_* is not needed.
There is of course matter of relative/absolute path for autoloader. Well, absolute is most system-efficient, so in the array I mentioned before u can prepend some kind of variable {I have used Phing-style variable} e.g.
<map>
<path classname="MyClass">${project_directory}/libs/my_classes/MyClass.php</path>
<path classname="OtherClass">${project_directory}/libs/some_new/Other.php</path>
<!-- its so flexible that even external libraries fit in -->
<path classname="Propel">${project_directory}/vendors/propel/Propel.php</path>
<!-- etc -->
</map>
This is xml (think about ini or yaml as well) file and requires compile to php during first start, but after that any path is absolute.
Oh, as you can see no file naming convention or file layout is mandatory - its huge advantage.
Cheers, Alan.
It seems that every time I move my simple scripts from one server to another I have to redefine where things are.
I set up a test environment at home, built a few things, and deployed them to a shared host. The result was that the $_server['DOCUMENT_ROOT'] was two folders higher than the public_html folder on one server, and on another server it was one folder higher.
That skewed all my references. So I tried $_server['WEB_ROOT'] and failed again. I was thinking that the web root was a reference to the root of publicly-accessible folders on the server, but I was wrong.
I have one to throw in the pile that did something really simple without adding a lot of code I don't understand (I don't understand a lot of this code either, I just kept adding as I read rules and got it to work).
This gave me a reference to the publicly-accessible web root on all three servers I tried it on. Now I can move my folder anywhere and it just works, no config file necessary!
pub-doc-root.php:
<?php
//You only need to paste the following line into your script once,
//and it must come before you reference the public document root of your website.
//Use $pubroot.'/path_from_public_document_root_to_file/filename.php
$pubroot = (str_replace(($_SERVER['PHP_SELF']), '', (str_replace('\\', '/', (realpath(basename(getenv("SCRIPT_NAME"))))))));
//uncomment the next line to show the calculated public document root
//relative to the document root.
//echo ("$pubroot");
?>
My test environment:
php 5.3.1
Apache 2.2.14 (Win32) mod_ssl 2.2.14 OpenSSL 0.9.8k
ZendServer-CE-5.0.0GA_RC181-5.3.1-Windows_x86
Why not require it based on it's full path?
For example, /sharedhost/yourdomain.com/apache/www is your document root, so why not use
require('/sharedhost/yourdomain.com/apache/www/dbutils.php');
This also has the advantage of you being able to store your includes outside of your wwwroot so they are far less likely to be inadvertenly exposed via the web.
You could also set up a global variable equal to the /sharedhost/yourdomain.com/apache/ part of it so you can move the site around.
require(WWWROOT . '/dbutils.php');
I use
require '../path/to/file.ext';
without problems.
Also require is a statement not a function so it should be used as
require '/path/to/file.ext';
not
require('/path/to/file.ext');

Categories