PHP set_inlude_path and include best practises - php

Where would
set_include_path("../../");
point to?
I am trying to run some PHP code on a standard XAMPP server. And put my stuff into the htdocs folder. The includes point to relative paths, But it does not work. Is there any best-practise for includes? The code has to run on machines of multiple developers.

Relative path should work fine (warning: apache on windows, as I know, don't follow the simlinks, or whatever are called on that os).
Maybe you should use the syntax (in order to avoid problem with different php versions)
ini_set('include_path', 'yourdir');
and test the return value to see if all is ok.
Turning to the best practices:
To me setting an configuration directive into a script, expecially if project-wide, is wrong, or at least dangerous.
A better practice is to put the directive into the .htaccess file in the directory that contains your php files project.
Even better, it is faster, put the directives into the appropriate virtualhost section of your apache config. For develop, though, .htaccess is more flexible and therefore preferable.
It should be something like this:
php_value include_path ".:../..:<your path collection>"
Doing this lets you share the php configuration w/o have fiddling with the ini_set directive in every php file you write.
Not to mention that if you have a special file that needs a custom include_path, you can set it in the file and this will be evident to everyone at a very rapid glance.

Two directories down from where the file (or the file which included it) is running from.
As for best practices there are only two advices i can give you.
Use relative paths.
If relative paths are giving you trouble, use an absolute path as a single static variable and the developers only change that one variable.

Related

How to get php include_path to work on a custom directory '/var/custom_directory'?

I thought php include path was a pretty simple concept. I've done it many times, but now am having trouble getting it to work.
I am running an
centos 7.1 server on azure with Apache/2.4.6 PHP/5.4.16
When I modify the include_path within php.ini. The error after restarting apache shows
Failed opening required 'xfile' (include_path='.:/var/custom_directory')...
The include path is in the proper file format.
I might have an ownership problem.
I can place my files inside the default usr/share/php directory and the pages "include". However when I try to put my own directory inside of /var they do not.
I have done this before so I do not know why it isn't working now.
I have chowned and chmod these directories and their contents to death. Even mimicing the server that works's directories. Switching ownership to apache and giving full grant access just trying to get it to see the file from my /var/www/html/index.php
Am I missing something?
Is there something I need to enable or grant access or modify in the php or http.conf files?
Further information:
This is the only php.ini file included in the system /etc/php.ini
The purpose of the include path is to provide coding / user files behind the firewall.
I don't think this maters, but my vm is in Azure.
Putting something like this
include('/var/custom_directory/file.php');
Doesn't work as well. Why?
The include_path ini setting sets the path, it doesn't add to it, so if you change it you most likely mean to add an extra path, e.g.:
include_path = ".:/usr/share/php:/var/custom_directory"
This ensures that both your own custom_directory and the standard /usr/share/php directory are in the path.
(N.B. On Linux the path seperator is a colon (:), on Windows it is a semi-colon (;))
However
You probably don't want to mess around with the php.ini setting, as this will affect all php files. If you put another site on your server which tries to include a file with the same name as one in your custom directory you're going to end up in a confusing situation.
I suggest you either qualify your includes:
include('../custom_directory/file.php');
include('/var/custom_directory/file.php');
include(SOURCE_DIR . 'file.php');
Or use set_include_path at the start of your script:
$path = '/var/custom_directory';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
I got a quick test to test your requirement.
(environment: CentOs 7.1, Apache/2.4.6 and PHP/5.4.16.)
I created a ‘includes’ folder in ‘/var/www/’ folder besides ‘html’, shows like:
Then I set include_path = ".:/var/www/includes" in php.ini.
In the includes folder I put a test class file named phpinfo.class.php with simple code:
class phpInfo{
public function echoinfo(){
phpinfo();
}
}
And in html folder, there is a test PHP file with simple code:
require('phpinfo.class.php');
phpInfo::echoinfo();
It worked fine to me.
So you may double check your files and path.
update
I moved the includes folder under to /var/ beside 'html', and modified the php.ini, and still worked fine to me, and the setting of include_path will be shown in the php runtime environment, we can check the configuration.

php access files outside of apache

I have a project where Red5 is recording videos. I need PHP to be able to access the videos and move them so they can be accessed by HTML.
How can I do this?
I found this post: Accessing files outside the document root with Apache
But it involves updating some file that was never specified. And I'm not sure it is a viable solution in this case anyway.
lee
PHP by default can already access files outside the web root, unless restricted with an open_basedir directive (or safe mode, but hope you're not in that cage).
It's normally a good practice to insert within a VirtualHost configuration an open_basedir restriction. You can specify multiple directories separated by : on Linux and ; on windows.
php_admin_value open_basedir /var/www/s/stage:/usr/share/php:/your/dir
To access those files either use an absolute path or a path relative to the position of the PHP file called. (So you'll have to ../ to reach levels above).
Also be sure that directories in which you want to write to are assigned to the webserver user and have write permission.

How secure is storing DB variables with SetEnv or in php.ini?

I don't like storing sitewide crypto keys and DB access information under document_root, so I was using Apache's SetEnv and php.ini files under conf.d to separate these from the codebase. The big question is, which one is better? Inside environment variables under apache vhost files (SetEnv SITEKEY 'oinkoink!') or inside conf.d/xxx.ini files (db_pass="oink?")? Maybe something else?
PROS n CONS:
SetEnv:
+Stored outside DOCUMENT_ROOT
+Only the given vhost has access
-Visible with PHPINFO() - Hacker needs direct access/upload exploit to files
get_cfg_var:
+Stored outside DOCUMENT_ROOT
+Not visible with PHPINFO()
-(VERY BAD) All the defined ini variables are included, so each vhost can query them via (ini_get_all), so not usable in a shared vhost environment
As long as *.ini and SetEnv are outside of the web root (document root) it doesn't matter either way. Just choose whichever you prefer. I like SetEnv, but it's really just personal preference. It makes more sense to me to use SetEnv since the variables are put into _SERVER. With the .ini, I think it makes more sense to leave it for initialization settings specific to how the code works.
Not storing under the document root is a good idea to prevent access to possibly secure data.
Note that phpinfo() will list any server variables that are set, so be very careful about that.
Finally, if you are including files, make sure that you don't allow gratuitous ../../ set by the user somehow or they will have access to potentially secure files (even including /etc/passwd!)
I think your main question is "how secure." Well, this probably about as secure as you can get without causing major headaches. The php code has access to these variables, so if you print them out they are easily visible, so it depends on how secure your code base is. It might be possible to use LDAP with MySQL, but that sounds like a huge pain.
It's common practice to use store non-public files outside of document_root. A typical layout could be this:
.../myProject
.../myProject/documentRoot
.../myProject/documentRoot/....
.../myProject/nonPublicFiles
.../myProject/nonPublicFiles/...
Store your PHP stuff in documentRoot and all non-public stuff in nonPublicFiles. documentRoot would be the Apache document_root of the vHost. Since nonPublicFiles is outside, Apache won't answer request.
Recarding security, SetEnv or *.ini tend to be equivalent: In case someone gains rights to execute arbitrary PHP-Code, both ways provide the sensible information to this code.
I'd prefer the SetEnv and *.ini method, since Apache won't disclose these details itself. A script is required.
Misconfiguration may disclose the contents of nonPublicFiles even without a script.
If case you are going to use nonPublicFiles, prepare upfront a script, which checks if everything is set up fine and forward an email, if it found problems. Probably call it using CRON.
I prefer storing them in either non-public folders, which can be accessed only by apache, or outside the document_root.

Share Code between multiple PHP sites

Good evening. I found a few questions that seemed to ask the same thing I am asking, but none of the answers seems to work for me. Basically, I have a few generic PHP files (mostly classes, but some are not) that I want to be usuable by multiple PHP sites.
Here is an example of my folder structure:
Site A Root
C:\Personal\WebSites\SiteA
Site B Root
C:\Personal\WebSites\SiteB
Shared Code
C:\Personal\WebSites\Shared
From Site A I tried using include("../Shared/foo.php") to reach the files, but this did not work. I have a feeling this is due to the folder being beyond the site root folder of SiteA. Is there a way to simply include files from the Shared directory? I can't imagine this is an uncommon practice, but I just can't figure it out.
BTW, I am using PHP 5.2.14 through IIS (via FastCGI) on Windows 7 if that matters. Eventually, I will be moving these sites to Linux/Apache hosting, so I would prefer any solution to work with either.
Thanks!!
In your php.ini you can add directories to the include_path, and them include files from then.
"C:\Personal\Websites\Shared;"
If you append a string like that to the already existing include_path you can do include 'specialDir\Class.php' wherespecialDiris a directory inShared`.
Your best bet is to setup a directory anywhere you wish (let's say C:\Personal\Shared), and edit your php.ini include_path to add this directory as an include path. Make sure you set permissions correctly so IIS allows you to access this directory (I'm not 100% on how to do that with Windows, but it should be pretty easy).
Then all you need to do is include the file as if it was in the same directory (PHP handles searching include directories for you).
For example if you had C:\Personal\Shared\foo.php you can include it like this:
include("foo.php");

PHP include file extensions?

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.

Categories