Do file_get_contents and readfile execute PHP code? - php

I was always sure that the PHP functions file_get_contents and readfile execute any PHP code in any files - regardless of file type - that are given to it. I tried this on multiple setups, and it always worked.
I received a question regarding this here, and the user seems to think that this is not the case.
I looked at the PHP documentation for the functions, and they do not mention code execution (which is something that I would expect if this is normally the case, as it has serious security implications).
I also searched for it, and found a lot of claims that the functions do not execute PHP code. For example:
readfile does not execute the code on your server so there is no issue there. source
Searching for "php file_get_contents code execution" also returns various questions trying to execute the retrieved PHP code, which seems odd if it would indeed normally execute any given PHP code.
I also found one question that asks about not execution PHP code, so execution does seem to happen to others as well.
So my questions are:
do the functions file_get_contents and readfile execute PHP code in retrieved files?
does this depend on some php.ini setting? If so, what setting(s)?
does it depend on the PHP version, and if so, what versions are affected?
if it is not normally the case, what may be the reasons that they execute the PHP code in my setups?

file_get_contents and readfile do not execute code. All they do is return the raw contents of the file. That could be text, PHP code, binary (e.g. image files), or anything else. No interpretation of the files' contents is happening at all.
The only situation in which it may appear as if execution is happening is:
<?php ?> tags will likely be hidden by the browser because it's trying to interpret them as HTML tags, so this may lead to the impression that the PHP disappeared and hence may have been executed.
You're reading from a source which executes the code, e.g. when reading from http://example.com/foo.php. In this case the functions have the same effect as visiting those URLs in a web browser: the serving web server is executing the PHP code and returning the result, but file_get_contents merely gets that result and returns it.

Those functions are described in the «Function Reference / File System Related Extensions / Filesystem» section of the manual, while function to execute code are described at «Function Reference / Process Control Extensions».
I'm pretty sure the misunderstanding comes from a somehow widespread confusion between file system and network and that's made worse by the PHP streams feature that provides protocol wrappers which allow to use the same functions to transparently open any kind of resources: local files, networks resources, compressed archives, etc. I see endless posts here where someone does something like this:
file_get_contents('http://example.com/inc/database.inc.php');
... and wonders why he cannot see this database connection. And the answer is clear: you are not loading a file, you're fetching a URL. As a result, code inside database.inc.php gets effectively executed... though rather indirectly.

Related

When is a php include file parsed?

When is a PHP include file parsed? At startup, or during execution?
My web forms call a single php script. Depending on the arguements passed in the URL, a switch/case condition determines what the script will do. Each "case" within the switch has its own include files.
If include files are parsed during initial load, then my php script will take up more memory/time to process which leads me to believe having individual php files called from my web form is better, than having one which includes what it needs.
If include files are parsed when needed (thus, when a branch of the code reaches a specific case statement, that it then performs the include) it tells me my code will be reasonably conservative on memory.
So.... my question... When is a PHP include file parsed? At initial load, or during execution?
(note... I failed to find the answer here, and I have read http://php.net/manual/en/function.include.php)
Files are included if and when the include statement is reached at runtime. To very succinctly summarise what that means, the following file is never going to be included:
if (false) {
include 'foo.php';
}
Since you're concerned about memory usage from too many includes, I feel that a bit more detail will be useful over and above a direct answer to your question.
Firstly, to directly answer you, PHP files are parsed as soon as they are loaded -- if a file contains a syntax error, you will be told of that immediately; it won't wait till it gets to that line of code. However subsequent files are only included if the specific line of code containing the include statement is executed.
You're concerned about memory usage, but having a lot of included files is generally not a major memory issue, nor a major performance issue. Indeed, most modern PHP applications of any size will use a framework library that load hundreds of PHP files for every page load. Memory and performance issues are far more likely to be caused by bugs within your code rather than simply loading too much code.
If you are concerned about memory and performance from this, you should consider using PHP's OpCache feature. With this feature enabled, PHP stores a cache in memory of the compiled state of all the files it has included within a system. When it runs the page again, therefore, it does not need to actually load or parse anything when it encounters an include statement; it simply fetches it from the cache.
Using OpCache you can write your code with a very large number of files to include, and without any performance penalty at all.
The good news is that OpCache is enabled by default in recent PHP versions, and is completely transparent to the developer -- you don't even need to know that it's there; the only difference you'll see between it being turned on and off is your site running faster.
So, firstly, make sure your PHP version is up-to-date (v5.5 or higher). Then make sure OpCache is enabled in your PHP.ini file. Then just sit back and stop worrying about these kinds of things.
File included with include statement are parsed during exection. When your php code hits a include statement it will start parsing the file to see what is in there.
From w3schools
The include (or require) statement takes all the text/code/markup that
exists in the specified file and copies it into the file that uses the
include statement.
There is other questions with a similar topic:
In PHP, how does include() exactly work?

Include/Require non php file

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.

blocking highlight_file function in php

I'm having many websites installed on the same webserver. What i wanna do, is to be able to include a same file from different websites as
<?php include '/home/site/www/path/to/file.php'; ?>
and in the same time block functions like highlight_file and file so using the following code won't displays my files content
<?php echo hightlight_file('/home/site/www/path/to/file.php'); ?>
Any help will be appreciated.
If you want your PHP files to be runnable but be safe from being read, your best option is to encode them.
Take a look at IonCube PHP Encoder and SendGuard , they are both very popular options to protect source code.
Blocking PHP function can work, but you'll never be safe because you can forget functions (can you reall list them all? What if there's one you actually need?), or new functions could be added in the future and if you do not block them you'd be exposed.
...so using the following code won't displays my files content
Does that mean you want to allow other people to deploy code on the server which calls your code without revealing the PHP source? If so, then disabling highlight_file isn't going to help much. You also need to disable include, require, fopen, file_get_contents, the imap extension and several other things - which means they won't be able to access your code at all.
If you're letting other people whom you don't necessarily trust deploy code on your server then there are lots of things you need to do to isolate each account - it's not a trivial exercise and well beyond the scope of an answer here. But it's not really possible to allow access to a shared include file without providing access to the source code. Using encoded PHP solves some problems but introduces others. A better solution is to expose the functionality via a web or socket API (this solves the sharing problem but not the isolation problem).

using includes cross domain that contain php code - failing

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.

Calling fcsh from PHP script

My question is whether or not Flex's fcsh can be called from within a PHP script. Here is the background:
I have been created a simple process that creates a simple quiz/tutorial by converting a text file into a .mxml file and compiling to a .swf file using the mxmlc compiler. This works well from the command line, but I wanted to make the process easier by creating a web-interface to do this. My initial attempts with PHP's exec() function have not worked. The Python scripts I use to create the .mxml file work fine (using exec()), but I have not been able to get the mxmlc compiler to work.
After searching on the Web and on this site, I believe that using fcsh (instead of mxmlc) may be the way to go. Using fcsh would certainly compile the .mxml file faster (after the first run), and I think that fcsh can be launched as a service that might be able to be called from PHP.
On the other hand, maybe I am approaching this the wrong way. Would it be better to write a Flex application that calls fcsh and avoid using PHP?
Edit: Using fcshctl as hasseg suggested in his answer below worked very well. Thanks Ali.
The problem with calling fcsh from within scripts is that it works as an interactive shell instead of taking command-line arguments, compiling, and returning an exit status. There are different ways to get around this, which I've listed in this blog post of mine, where I mainly talk about fcshctl (which is my own solution for this,) but at the bottom of the post I've also listed other similar solutions to get fcsh integrated into nonstandard build workflows.
There are a few other ways in php to execute an external script. They are exec(), passthru(), system(), and backticks i.e. the key to the left of the 1 key. Each one has a different purpose and return mechanism.
You may have to put the command that executes your executable into a script and call that script via one of these functions.
Is there a particular reason why you can't use mxmlc directly? It seems like it would be easier to call than fcsh. Just specify all your compiler options in a XML file run it like mxmlc -load-config path/to/config.xml. You can find an example of the XML configuration format in FLEX_HOME/frameworks/flex-config.xml.

Categories