I know that PHP's include/require statements can append other .php files into the script, either from a local path or an url.
Today i tried to include and also to require a .ddf (a text file), and it worked, with no errors or warnings. Then PHP actually executed some code that was in that file!
After that i went into the PHP's documentation for include to see if including non-php files is fully supported and safe. Turns out that, the documentation barely mentions this procedure (include 'file.txt'; // Works.) that's it.
So i'm asking you guys, Is including non-php files safe? Also is it a bad practice?
I just want to say that it is completely unsafe. While yes, as long as you trust the page, you technically could do this. But the page when pulled up directly in the browser isn't parsed as php. Anyone who goes directly to the file in the web server, whether guessing or you made a framework or they just know some file names, would see the complete source of the file. Exposing your site and possibly releasing sensitive information like database credentials. Another thing to think about is that people are usually pretty good about not allowing *.php files to be uploaded to their site, but just imagine you are allowing other files to be included and someone uploads a text file named "someImage.jpg" with php script in it and for some dumb reason you include it. People now have a way to execute scripts on your server. Likely including calling shell commands (exec). It used to be common practice to use *.inc files to specify includes but that has been considered bad for quite a long time.
It is not advisable to include txt files in php scripts. Instead, you should use file_get_contents.
Related
I have a doubt about PHP, Apache, server interpretation... I know that when a PHP file is loaded by the browser from an Apache+PHP server it is interpreted and only the HTML and plain text is showed but is there a way to download this files instead of interpreting them?
In this case it would be very unsecure because MySQL passwords would be unsafe.
Is it any security measure to prevent this or it's impossible to download this files?
As long as your server is setup properly it isn't going to happen.
A good step though is to put all of your actual passwords and whatnot in a config.php and including it. That way you can use htacces too block that file so that should your server ever start serving the raw pages that file won't be accessible anyway.
To clarify if you create a .htaccess file and place it in the same folder as the config.php with the below information that file will not be served, even if requested directly. Simply define your config stuff (db name, user name, password, hashes, etc) in this file and include_once it at the top of each page that needs it and you will be good to go.
<files config.php>
order allow,deny
deny from all
</files>
There is no way to 'download' PHP files, but for more security you can place your 'core' PHP files outsite of the public_html folder
Unless the PHP interpreter stops working for some reason, it's not something to worry about. Most servers are designed to interpret the PHP files every time they are requested and serve only the interpreted HTML text. It's possible to secure your sensitive PHP settings files just in case - often by placing them outside of the root directory with modified permissions.
The only way someone could download the files is to have a server set up that serves the raw files. As long as you don't have such a server set up, they're inaccessible. If the only server software on your system is Apache and it's configured correctly, people cannot see your source code.
However, if somebody seeing your source would render your app vulnerable, you might want to give some thought as to how you can fix that problem. Lots of secure open-source software exists — why would yours being open-source cause problems?
With proper configuration apache guarantees that files will always get interpreted and won't be offered for download.
You always may install fault update or make wrong configuration, but with skilled admin and stable release those cases just don't happen.
I want to allow members the option of uploading content using a zip file. Once uploaded, I want to use PHP's ZipArchive class to decompress the zip file contents to a directory, and then move the files into our system.
I'm concerned about the potential security risks though, and I can't find any documentation on php.net. The first (Well, the only) risk that comes to mind, is someone creating a zip file with relative paths like "../../etc/passwd" (If they assume I decompress the file in /tmp/somedir).
I'm actually having a hard time creating a relative path in a zip file, so I can't test if such a thing would be possible. I also can't find any way to extract the contents of the zip file using ZipArchive, and have it ignore directories (Decompress all the files, but don't create the directory structure inside the zip).
Can anyone tell me if such an exploit is possible, and/or how to ignore the directory structure in a zip file using ZipArchive?
Interesting question, but I urge you to go about this a different way. I would highly recommend you run your web process with least privileges in a chroot jail. Assuming you do that, the WORST thing that can happen is your website get's defaced, and then you restore a backup and do some forensics to plug that specific hole.
New holes are discovered constantly, you will have a very difficult time completely securing your website going after hunches like these. Minimizing the attacker's sandbox really goes a long way.
I had the same concerns and had a look at the PHP 5.3 source code where I found this:
/* Clean/normlize the path and then transform any path (absolute or relative)
to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
*/
virtual_file_ex(&new_state, file, NULL, CWD_EXPAND TSRMLS_CC);
path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
if(!path_cleaned) {
return 0;
}
Looks fine to me. Checkout PHP and see ./ext/zip/php_zip.c for details.
You need to make sure that the extracted contents are not served directly by your application server. So if someone has a php file in his archive that he cant execute it via your webserver.
Another thing is you should keep things safe from being included in user generated content. But this should be considered also without having zip archives in place.
In the end I'm going with Pekka's solution, of using the command line unzip utility. It provides switches to ignore directories in the zip file. The concerns others have pointed out aren't an issue here. Once the files are unzipped, we add them to the system using the same process as our regular uploads, which means each file is scrutinized using the security measures we already have in place.
I have a series of web sites all hosted on the same server with different domains. I want to host some common PHP scrips and then be able to call these from the other domains.
Im am a bit fresh with my php so pls excuse code attempts - I have tried iterations of the following which may try and help you understand what I am aiming for!
from within php tags ...
include('http://www.mydomain/common_include.php?show_section=$section');
$show_section = $_GET['show_section'];
include('http://www.mydomain/common_include.php');//Then $show_section would be available to the included file/cod
Finally I have tried pulling in the include which contains a function then trying to run that include from the parent script.
I would much prefer to keep this PHP
orientated rather than getting
involved with the server (file
systems etc (but I can change
permissions etc)
I can but would prefer not to just upload the same library to each of the domains separately
I understand PHP is run on the server hence maybe problematic to include scripts across onto another server.
Thanks in advance.
#
EDIT
OK OK - I get that its bad practice so will not do it....THANKS VERY MUCH FOR THE QUICK ANSWERS.
However is there any other recommendations of how to esentially show this basic php app on all of the sites with out haveing to add the files to the root of each site? Just to prevent massive script duplication...(thinking out loud call the scripts in from a db or anyother soloutions)
Again thanks for your assistance
That would be a huge security risk if you could just include remote PHP files to your own projects. The PHP gets parsed before the server sends it to you so cross-domain includes would only contain the output the script generates. The only way to include PHP files so that they can be executed is via local filesystem.
If you look at PHP.net's documentation about include, you can find this:
If "URL fopen wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be included using a URL (via HTTP or other supported wrapper - see List of Supported Protocols/Wrappers for a list of protocols) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using a URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.
Which pretty much explains the whole thing.
The root of the original question seemed to be the poster's concern about using a PHP script or plugin on multiple sites and then having an onerous task each time it needs to be updated. While trying to include PHP files across sites is a bad idea, it is a better plan to structure your script to be as self contained as possible. Keep the entire plugin contained in one directory.... and ensure your function calls to utilize it are as well formed as possible - clean, well named functions, uniform naming conventions and a well thought out plan for what parameters each function needs. Avoid using global variables.
Ideally you should then have quite an easy time each time you need to update the plugin/script in all locations. You can even set up an automated process that will upload the new directory containing the plugin to each site replacing the old one. And the function calls within your code should rarely if ever change.
If your script is big enough you might implement an automatic update process like the more recent versions of Wordpress use. Click a button and it updates itself. In the past, updating a dozen sites running Wordpress (as an example) was a massive pain.
That is very bad practice.
Actually you're including not PHP but just HTML code.
Include files, not urls. It is possible for the same server.
Just use absolute path to these files.
Apart from the fact that it's a bad practice you should first check if include allows URLs if you really want to do that.
If however all the sites that need to use the script, you could put the script somewhere in a directory accessible by the user that executes php and add that dir to the php.ini include_path property (can also be done at runtime)
(Or you could create a php extension and load it as extension)
If you have root rights on that server, you could just use absolute path from filesystem root, but most hostings won't let you do this.
Just something I wonder about when including files:
Say I want to include a file, or link to it. Should I just for example:
include("../localfile.php");
or should I instead use
include("http://sameserver.com/but/adirect/linkto/localfile.php");
Is one better than the other? Or more secure? Or is it just personal preference?
Clearly it would be a necessity if you had a file that you would include into files in multiple directories, and THAT file includes a different file, or is there some other way of doing that?
Reading a file is much faster than making an HTTP request and getting the response. Never include(a_uri) if you can help it.
Use $_SERVER['DOCUMENT_ROOT'] if you want to calculate a complete file path for your include.
As said before, definitely include a local file and not do an HTTP request (which takes more time, is not cached and the contents are technically viewable to all the world, if he knows where to look for it).
One more small detail, if you use full paths to your included files, it will even be faster then relative paths, especially if you use some kind Byte Code Cache.
Definitely include the local file, because the php script doesn't really know or care that you're including a script on your local server, so the url path causes an http request, and network latency from http requests is pretty much the bottleneck for rendering any html page in general, the fewer of them you have, the better off you're going to be.
Personally, I try to avoid using include and require in general, in favor of require_once, because using require_once means that you are writing your code reusably instead of writing code that executes immediately when you include it. Pull in class definitions, pull in function libraries, but try to avoid code that executes immediately when you include it, because that will make it harder to reuse.
If your question is about keeping it so you don't have to change a billion paths when you move from staging to production, go with this little tidbit I learned:
define('BASE_DIR', '/path/to/root/');
Then use BASE_DIR in all of your path references. When it's time to move your site, just change that definition to the new path (which should just be / at that point).
In addition to what other people say, these invocations will have different results, since the remove invocation will execute php output, not the file contents. Unless you stop php from processing the file, in which case you're exposing your code to the world which is also not necessarily what you actually want to.
Always include locally, cause if you include remote someone can create a different file and do nasty things. And the other problem you can't really test this with remote includes. As far as i know you should use require_once instead...
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).