php error with completely wrong, not even possible filepath - php

The issue I am having is kind of amazing me, never seen something that is truly impossible happen to me before.
What I see is that when trying to access a specific file, php is making up a random filepath that is completely none existant.
$less_template = dirname(__FILE__).DIRECTORY_SEPARATOR.'less/template.less';
$css_template = dirname(__FILE__).DIRECTORY_SEPARATOR.'css/template.css';
$less_resp = dirname(__FILE__).DIRECTORY_SEPARATOR.'less/responsive.less';
$css_resp = dirname(__FILE__).DIRECTORY_SEPARATOR.'css/responsive.css';
These are where the filepaths being called are being generated.
Warning: file_exists() [function.file-exists]: open_basedir restriction in effect.
File(/home/rem/www/outpost/ashl/templates/default/less/template.less)
is not within the allowed path(s): (/var/www/vhosts/rehost.ca/httpdocs/rehost/:/tmp/) in
/var/www/vhosts/rehost.ca/httpdocs/rehost/a/ashl/ashl/templates/default/less/lessc.inc.php
on line 1741
Now given that this error (to me anyway) is about as possible as dividing by 0, I must be totally overlooking something. This worked before but now it just does not.
To give a bit more information the filepath its looking for is from before a move. That does not change the fact to me that its impossible though as its referenced by a global constant.
Just to explain my standpoint on this, I never had this happen to me before and never thought it was possible for PHP to do such an illogical thing, so I don't even know where to start to even think about fixing it. Everything causing the error is global.
Please correct me if I am over thinking this, this is just confusing me like crazy.
NOTE:
I have attempted disabling open_basedir with no effect (according to an answer).
I have disabled any and all kinds of caching.
I have "checked" individual cache files before disabling to ensure file paths were correct (they were).

So which path is the "impossible" one? Do the files exist under /home/... or under /var/www/...? Which path are you accessing the files under?
I would assume the file exists under the /home/... path now and you have a symlink under /var/www/... that points to the /home/... path. Apache is probably pointing to the symlink in the vhost and so the file being requested by apache under /var/www/..., but really exists under /home/... which is why __FILE__ returns the actual path under /home/... (php generated this path) but is reporting that the file loaded (which it gets from apache) is under /var/www/.... This would explain why the error reports that the file being loaded exists under /var/www/... but the php constant __FILE__ reports where the actual file is located.
To fix, you should point your vhost to the right path, not a symlink. You could also add the /home/... path to the open_basedir in php.ini, but you said turning off open_basedir didn't fix the problem. You could also create your own constant and use that.

Disable the open_basedir restriction in your PHP configuration.

Related

PHP error uploading file to a folder error: failed to open stream: Permission denied (changing permissions on windows won't help either)

I'm currently having an issue trying to upload a file (an image) and sending it to a folder, this for a CMS/blog where people can comment and create profiles with pictures, unfortunately, XAMPP won't allow me to send it and it displays this message
`Warning: move_uploaded_file(../images/ ): failed to open stream: Permission denied in C:\xampp\htdocs\CMS\CMS_TEMPLATE\admin\includes\add_post.php on line 19
Warning: move_uploaded_file(): Unable to move 'C:\xampp\tmp\php37A6.tmp' to '../images/ ' in C:\xampp\htdocs\CMS\CMS_TEMPLATE\admin\includes\add_post.php on line 19
I know is a problem with the permission or privileges to read and change files, but even when I changed those permissions on the folder to let it write and modify files, the error messages still appear, I'm working on windows 8.1 with XAMPP and I haven't found a solution to this, it would be really helpful if anyone could help me. Also here's the code if anyone needs to see it.
<?php
if(isset($_POST['create_post'])) {
$post_title = $_POST['title'];
$post_author = $_POST['author'];
$post_category_id = $_POST['post_category_id'];
$post_status = $_POST['post_status'];
$post_image = $_FILES['post_image']['name'];
$post_image_temp = $_FILES['post_image']['tmp_name'];
$post_tags = $_POST['post_tags'];
$post_content = $_POST['post_content'];
$post_date = date('d-m-y');
$post_comment_count = 4;
move_uploaded_file($post_image_temp, "../images/ " );
}
?>
<div class="form-group">
<input type="file" class="form-control" name="post_image">
</div>
Thank you!
The function move_uploaded_file is available in
(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)
and in PHP's official documentation defined as following
move_uploaded_file(string $from, string $to): bool:
This function checks to ensure that the file designated by from is a
valid upload file (meaning that it was uploaded via PHP's HTTP POST
upload mechanism). If the file is valid, it will be moved to the
filename given by to. This sort of check is especially important if
there is any chance that anything done with uploaded files could
reveal their contents to the user, or even to other users on the same
system.
This function is open_basedir aware. However, restrictions are
placed only on the to path as to allow the moving of uploaded files in
which from may conflict with such restrictions. move_uploaded_file()
ensures the safety of this operation by allowing only those files
uploaded through PHP to be moved.
Return Values
This functon returns true on success.
1. If from is not a valid upload file
Then no action will occur, and move_uploaded_file(...) will return false.
2. If from is a valid upload file, but cannot be moved for some reason
Then no action will occur, and move_uploaded_file(...) will return false. Additionally, a warning will be issued (#MiguelDavid your case).
Referring to open_basedir string
Limit the files that can be accessed by PHP to the specified directory-tree, including the file itself. This directive is NOT affected by whether Safe Mode is turned On or Off.
When a script tries to access the filesystem, for example using include, or fopen(), the location of the file is checked. When the file is outside the specified directory-tree, PHP will refuse to access it. All symbolic links are resolved, so it's not possible to avoid this restriction with a symlink. If the file doesn't exist then the symlink couldn't be resolved and the filename is compared to (a resolved) open_basedir.
open_basedir can affect more than just filesystem functions; for example if MySQL is configured to use mysqlnd drivers, LOAD DATA INFILE will be affected by open_basedir. Much of the extended functionality of PHP uses open_basedir in this way.
The special value . indicates that the working directory of the script will be used as the base-directory. This is, however, a little dangerous as the working directory of the script can easily be changed with chdir().
In httpd.conf, open_basedir can be turned off (e.g. for some virtual hosts) the same way as any other configuration directive with "php_admin_value open_basedir none".
Under Windows, separate the directories with a semicolon. On all other systems, separate the directories with a colon. As an Apache module, open_basedir paths from parent directories are now automatically inherited.
The restriction specified with open_basedir is a directory name, not a prefix. The default is to allow all files to be opened.
open_basedir can be tightened at run-time. This means that if open_basedir is set to /www/ in php.ini a script can tighten the configuration to /www/tmp/ at run-time with ini_set(). When listing several directories, you can use the PATH_SEPARATOR constant as a separator regardless of the operating system.
Also take a look at upload_tmp_dir string
The temporary directory used for storing files when doing file upload. Must be writable by whatever user PHP is running as. If not specified PHP will use the system's default.
If the directory specified here is not writable, PHP falls back to the system default temporary directory. If open_basedir is on, then the system default directory must be allowed for an upload to succeed.
In your case xampp temporary directory is located:
C:\xampp\tmp and it,s also writable, so nothing to do there!
... To fix your issue / finish ...
Now that function move_uploaded_file is open_dir aware as already mentioned, give the directory for your images the appropriate owner permissions (e.g.: 0755):
../images/
This will get you out of the issue!
According to Dan Delaney on https://www.php.net/manual/en/function.move-uploaded-file.php#86332 you might need to set the "upload_tmp_dir" to an existing directory within you websites directory structure, since you are running on Windows.
Search for "upload_tmp_dir" in your php.ini file and set it to a path pointing to an existing directory:
upload_tmp_dir = "path_to_your_custom_tmp_dir"

Sessions storage php/nginx

I'm having trouble with session variable in my setup. I'm storing some data in SESSION variables, but it seems like they're not stored properly, or at least I can't access them. On my local computr running MAMP it works ifne but in prod with php5/nginx, my session variables aren't stored. (I get an undefined index error).
I've read it can be related to the session.save_path and access rights, but I'm still confused. Where is this path defined? In my php.ini file there is this
;session.save_path = "/var/lib/php5"
But it starts with a ';' so I'm guessing it's ignored?
Also, what access should I give to the folder (once I've found it)? How can I know which user php is, and which group it belongs to? Seems like really basic stuff but I'm struggling to grasp it u__u
EDIT:
Apparently it's not a problem of permissions, since there are a lot of session folders in the directory, all created by php... So I really can't figure out why my session variables aren't accessible! :-(
It says undefined index...
Thanks in advance!
Aurélie
It is indeed ignored if it starts with ;. The default value is the temp directory, i.e. /tmp, but just to be sure, I suggest that you look in your phpinfo() and check it there because the file you checked might not be the only configuration your PHP uses.
The sessions path needs to be writable by PHP and it also has to be permitted by the open_basedir directive (if you use open_basedir which is highly recommended).
You use nginx so I'll assume you're using PHP-FPM. To find the PHP-FPM's user, you need to either find the user = ... directive in your php-fpm.conf (usually somewhere under /etc), or you can just find the running process using a tool like ps, htop, etc.

how to test open_basedir setting and make sure it is working correctly

I have a VPS using FastCGI (WHM/cPanel). As I understand it, open_basedir must be set using a php.ini file in each user's /home/ directory (E.g.: setting it globally in apache config file will not work).
I want to use open_basedir for improved security, as I recently had a hack that involved traversing through different user's directories
I have added this value to a home directory's php.ini file:
open_basedir = /home/USERNAME/public_html:/usr/lib/php:/usr/local/lib/php:/tmp
What I want to know is, is there a way to test that this is functioning properly? Presumably I would want to try and execute a .php file in another user's directory from within that first user...however I don't know of a good way to test this. Any suggestions would be greatly appreciated.
Try listing the contents of a different user's public_html folder:
<?php
print_r(shell_exec('ls /home/$anotheruser/public_html/'));
?>
If open_basedir is configured properly, you will see a directory listing for that folder.

PHP open_basedir with UNC path

Running PHP 5.3.1 on a Windows server, I have to modify a PHP script to access XML files on a network share. For various reasons the files cannot be placed on the PHP server, and I am not allowed to create a mapped drive on the PHP server so I have to modify the open_basedir parameter in PHP.ini to include the UNC path to the share, e.g.:
open_basedir = "E:\inetpub\;E:\DB_HubDataFiles\;\\stdmfps01\inter-departements$\CVSC-CDT-Estimation-Cedule\"
However when I try to access files on the share I get the "open_basedir restriction in effect" error. I am trying to access the files as follows:
$jobfilename = "//stdmfps01/inter-departements$/CVSC-CDT-Estimation-Cedule/" .$job . ".xml";
if (file_exists($jobfilename)) {
$jobxml = simplexml_load_file($jobfilename);
etc...
I have been assured that it is not a problem of rights, and anyway the error indicates a problem with open_basedir. So my questions are:
does open_basedir handle UNC paths under Windows (I have seen conflicting statements about this)?
if so is there some problem with my syntax?
do I have other options than using open_basedir?
Thanks.
Anyway, here's what ended up working for me, even if I am not totally clear why:
In php.ini changed the open_basedir parameter to use the IP address instead of the server name, and used the parent directory of the directory where my files are located, instead of the directory itself:
\\\nnn.nnn.nnn.nnn\inter-departements$\
instead of:
\\servername\inter-departements$\CVSC-CDT-Estimation-Cedule\
In the PHP script used the IP address as well:
$jobfile = "//nnn.nnn.nnn.nnn/inter-departements$/CVSC-CDT-Estimation-Cedule/" . ($jobid) . ".xml";
This worked for me: Replace the backslashes with slashes
open_basedir = "E:\inetpub\;E:\DB_HubDataFiles\;//stdmfps01/inter-departements$/CVSC-CDT-Estimation-Cedule/"

PHP Fatal Error Failed opening required File

I am getting the following error from Apache
[Sat Mar 19 23:10:50 2011] [warn] mod_fcgid: stderr: PHP Fatal error: require_once() [function.require]: Failed opening required '/common/configs/config_templates.inc.php' (include_path='.:/usr/share/pear:/usr/share/php') in /home/viapics1/public_html/common/configs/config.inc.php on line 158
I am definately not an expert of Apache but the file config.inc.php & config_templates.inc.php are there. I also tried navigating to a test.html page I placed in common/configs/ so I assume there is no rights issues going on. I also set the rights on config_templates.inc.php to give everyone read, write, and execute rights. Not sure what to do at this point, I checked to see if there was a /usr/share/php directory and I found there was not but when I did yum install php it said it had the latest. Ideas?
It's not actually an Apache related question. Nor even a PHP related one.
To understand this error you have to distinguish a path on the virtual server from a path in the filesystem.
require operator works with files. But a path like this
/common/configs/config_templates.inc.php
only exists on the virtual HTTP server, while there is no such path in the filesystem. The correct filesystem path would be
/home/viapics1/public_html/common/configs/config_templates.inc.php
where
/home/viapics1/public_html
part is called the Document root and it connects the virtual world with the real one. Luckily, web-servers usually have the document root in a configuration variable that they share with PHP. So if you change your code to something like this
require_once $_SERVER['DOCUMENT_ROOT'].'/common/configs/config_templates.inc.php';
it will work from any file placed in any directory!
Update: eventually I wrote an article that explains the difference between relative and absolute paths, in the file system and on the web server, which explains the matter in detail, and contains some practical solutions. Like, such a handy variable doesn't exist when you run your script from a command line. In this case a technique called "a single entry point" is to the rescue. You may refer to the article above for the details as well.
If you have SELinux running, you might have to grant httpd permission to read from /home dir using:
sudo setsebool httpd_read_user_content=1
Run php -f /common/configs/config_templates.inc.php to verify the validity of the PHP syntax in the file.
You could fix it with the PHP constant __DIR__
require_once __DIR__ . '/common/configs/config_templates.inc.php';
It is the directory of the file. If used inside an include, the directory of
the included file is returned. This is equivalent to
dirname __FILE__ . This directory name does not have a trailing slash
unless it is the root directory. 1
Just in case this helps anybody else out there, I stumbled on an obscure case for this error triggering last night. Specifically, I was using the require_once method and specifying only a filename and no path, since the file being required was present in the same directory.
I started to get the 'Failed opening required file' error at one point. After tearing my hair out for a while, I finally noticed a PHP Warning message immediately above the fatal error output, indicating 'failed to open stream: Permission denied', but more importantly, informing me of the path to the file it was trying to open. I then twigged to the fact I had created a copy of the file (with ownership not accessible to Apache) elsewhere that happened to also be in the PHP 'include' search path, and ahead of the folder where I wanted it to be picked up. D'oh!
you can set the include path in php.ini
include_path = ".:/home/viapics1/public_html"
I was having the exact same issue, I triple checked the include paths, I also checked that pear was installed and everything looked OK and I was still getting the errors, after a few hours of going crazy looking at this I realized that in my script had this:
include_once "../Mail.php";
instead of:
include_once ("../Mail.php");
Yup, the stupid parenthesis was missing, but there was no generated error on this line of my script which was odd to me

Categories