How to create a folder above the root directory using php - php

my root dir id
/var/www/html/
i want to create directory at /var/www/
ie /var/www/myfolder
i'm executing create_dir.php
from
/var/www/html/site/create_dir.php
when i execute this program it's unable to create folder.
in log i'm getting permission denide.
update
This is my code
<?php
$os_type=php_uname('s');
$cur_file_path=$_SERVER['PHP_SELF'];
echo "File path:$cur_file_path<br>";
$scount=substr_count($cur_file_path, '/');
echo "/ count:$scount<br>";
$doc_root= $_SERVER['DOCUMENT_ROOT'] ;
echo "doc root:$doc_root<br>";
if($os_type=='Linux')
{
$ds=substr_count("$cur_file_path","/");//directory seperator
echo "Count of /=$ds<br>";
}
if($os_type=='Windows')
{
$ds=substr_count("$cur_file_path","'\'");//directory seperator
}
$path="../";
for($i=1;$i<$scount;$i++)
{
$path.="../";
}
$dir="myfolder";
exec("mkdir ".$dir);
?>
how to solve this.

That is a security problem as it gives read and write access to the world. It may be that your apache user does not have read/write permissions on the directory.
Here's what you do if $os_type=='Linux':
1. Make sure all files are owned by the Apache group and user. In Linux it is the www-data group and user
exec('chown -R www-data:www-data /path/to/webserver/www',$ouput,$result);
2. Next enabled all members of the www-data group to read and write files
exec('chmod -R g+rw /path/to/webserver/www',$ouput,$result);
The php mkdir() function should now work without returning errors. You can also see the error output in $output in case of error.
There is the another way to create directory using ftp:
You can try mkdir with ftp, mkdir works with stream wrappers, so it's ok to write mkdir('ftp://user:pass#server/mydir');
OR
If you have problems with the SAFE MODE Restriction in effect i.e. if you try to create and access to subdirectorys recursive you can use ftp-lib like this.
<?php
DEFINE ('FTP_USER','yourUser');
DEFINE ('FTP_PASS','yourPassword');
/**
* Returns the created directory or false.
*
* #param Directory to create (String)
* #return Created directory or false;
*/
function mkDirFix ($path) {
$path = explode("/",$path);
$conn_id = #ftp_connect("localhost");
if(!$conn_id) {
return false;
}
if (#ftp_login($conn_id, FTP_USER, FTP_PASS)) {
foreach ($path as $dir) {
if(!$dir) {
continue;
}
$currPath.="/".trim($dir);
if(!#ftp_chdir($conn_id,$currPath)) {
if(!#ftp_mkdir($conn_id,$currPath)) {
#ftp_close($conn_id);
return false;
}
#ftp_chmod($conn_id,0777,$currPath);
}
}
}
#ftp_close($conn_id);
return $currPath;
}
?>
Maybe it helps.

The purpose of a "root" directory is to protect the hosting computer from malicious/buggy code that might damage information stored in other parts of the computer. It gives you an area in which you can safely do your thing while explicitly and deliberately preventing you from interfering with any data "above" your root directory. The root is as low as you can go, by design. Any host computer that has a vulnerability that would allow you to access data outside of your assigned space is a host computer begging to be hacked; you won't find many of those, hopefully.
It may be worthwhile to restructure the directories within your root directory to simulate a deeper root than what you are actually restricted to. Otherwise, it is a matter of convincing the system administrator for the host computer to allow you additional access.
In a properly designed and managed system, what you are asking for is intentionally not possible, and running into this particular roadblock is more a sign that you may need to reconsider what you want to do in light of your restrictions. Even if this is being hosted from your own computer and you are the system administrator, it would be wise to examine every possible way you can achieve the goals you hope to achieve without breaking that barrier. ANY means you implement to allow web-controlled code to break that barrier is a vulnerability in your system that someone, somewhere, is looking for an opportunity to exploit.

Related

Laravel permissions Ubuntu VPS - Dig. Ocean -Runs but Can't create directory error, OR if w/o changed permissions it's a monolog unable open fs 500 er

Please please help me. I'm miserable right now from all the back and forth attempts to fix this great project that ran great locally on myusername staff (user/group) setup. I'm a little confused in laravel about the user/group needed as git is was pulls the code in and I tried to directly SFTP it and it still claimed it root root.
My root looks like a normal laravel project which happily runs but when I go to open a photo in my CMS i spent time doing to save time and help repeat redundancy with a Laravel project CMS and components I can build add in the routes and go but now that i'm wanting to go live in production i have issues since i'm working with this VPS. (Laravel version is latest or semi-recent version) and php-4.3
/storage and /bootstrap directories were owned by root then changed to www-data, all directories but storage are owned by myuser (lets call it myuser , nginx's www-data , ubuntu's root I unfortunately clone the git repository before I fully setup the droplet up. I know root can cause issues or something for projects to just go smoother but with some danger. ALL else functions okay to my knowledge. I just dont get it and i'm happy to post more code and stacks, trees, etc. Anything to help me unscrew this thing is so very appreciated.
Symfony\Component\HttpFoundation\File\File::getTargetFile
vendor/symfony/http-foundation/File/File.php:109
Symfony\Component\HttpFoundation\File\Exception\FileException
Unable to create the "projectname/adminpanel/assets/img/profile/" directory.
Symfony\Component\HttpFoundation\File\File::getTargetFile
vendor/symfony/http-foundation/File/File.php:109
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
}
#chmod($target, 0666 & ~umask());
return $target;
}
/**
* #return self
*/
protected function getTargetFile($directory, $name = null)
{
if (!is_dir($directory)) {
if (false === #mkdir($directory, 0777, true) && !is_dir($directory)) {
throw new FileException(sprintf('Unable to create the "%s" directory.', $directory));
}
} elseif (!is_writable($directory)) {
throw new FileException(sprintf('Unable to write in the "%s" directory.', $directory));
}
$target = rtrim($directory, '/\\').\DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name));
return new self($target, false);
}
/**
* Returns locale independent base name of the given path.
*
Now i'm getting this
and php artisan storage:link run as user throws me
UnexpectedValueException : The stream or file "/var/www/personal/storage/logs/laravel-2021-03-31.log" could not be opened: failed to open stream: Permission denied
at /var/www/personal/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:111
107| restore_error_handler();
108| if (!is_resource($this->stream)) {
109| $this->stream = null;
110|
> 111| throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
112| }
113| }
114|
115| if ($this->useLocking) {
Exception trace:
1 Monolog\Handler\StreamHandler::write()
/var/www/personal/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php:121
2 Monolog\Handler\RotatingFileHandler::write()
/var/www/personal/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php:42
Please use the argument -v to see more details.
from earlier, an error I originally dealt with. I've now gone completely full circle, I was getting this and a 500 error but at least I can use the app, it looks fine, but something's totally wrong simple or a complication of things maybe if someone can help solve this new error we can id the real problem which may not have anything to do with what I was thinking, for all I know I just needed to start nginx all over again after sites-enabled changes and ubuntu setup changes, (perhaps a /bootstrap and a /storage dir change ownership to www-data then restarted and then ran without 500 errors a monolog error since and i've been using it and the database to add content, I just can't add img content which process has laravel create a related directory and file based on respective location in this case it's on the adminpanel side in profile settings so naturally the error was long a i.e ../../adminpanel/../../profile/ **speaking on uploading 128x128 px avatar in a section profile / directory and name is something also I think). I think I included it in the question however now i'm back and worried about Unable to open file stream the new error below. What information would be most useful to troubleshoot this again.
By default, the public disk uses the local driver and stores its files in storage/app/public. So, I'm assuming that's where your images are stored.
To make these files accessible from the web, you should create a symbolic link from public/storage to storage/app/public, which you can do by simply running:
php artisan storage:link

PHP file permissions, chmod & mkdir not working

I created a php function that allows me to add images to a folder within my web application project. Right now it only works when I manually set the permissions of the folder to write enabled. Unfortunately that is not exactly what I need, because when I push my code to my group members with git, they would still have to manually set the permissions of the folder to enable writing as well, in order for my pushed code to work. all my group members and I are each running this project locally via an apache server, and I believe the problem is that apache does not have access to write within any of the folders within the project unless the folders are somehow set to write enable for everyone. I feel like it's not feasible to tell all my group members to change their folder permissions just so my one function can write to a folder.
I am looking for a way to set file permissions within my php code, I have already tried php functions such as chmod and mkdir to set permissions, however it gives me errors saying that I don't have permission to use those functions, which I guess makes sense, but is there a possible work around?
$structure = 'path';
mkdir($structure, 0777, true)
or
$structure = 'path';
mkdir($structure)
chmod($structure, 0777);
<?php $result = mkdir ("/path/to/directory", "0777");
?>
Try this it will working
Try using this (if shell_exec() is allowed):
(list of issues: only works on linux, has a security issue with potential solutions at bottom of post)
<?php
function readFile($file) { return shell_exec("cat $file"); }
function writeFile($file,$cont) { return shell_exec("echo $cont > $file"); }
function makeFile($filename) { return shell_exec("touch $filename"); }
function makeFolder($filename) { return shell_exec("mkdir -pv $filename"); }
// the -pv was used so you could do makeFolder("1/2/3/4")
function appendFile($file,$cont) { fileWrite($file,readFile($file).$cont); }
function appendToTopOfFile($file,$cont) { fileWrite($file,$cont.readFile($file);); }
?>
Use escapeshellcmd or escapeshellargs to escape user input.
ex.
$file=escapeshellcmd($_GET['file']);
echo readFile($file);

PHP is_writable false for NFS folder although files can be written

Sorry, I'm not sure, if this is the correct forum because I don't know the cause for the issue, I'm facing.
I installed NextCloud on a Raspbian (Stretch 9) and moved the data directory to a mounted NFS folder. When I try to access NextCloud, I got the error message 'Data directory is not writable'.
So I dug a better deeper and could finally isolate the issue to the interaction between PHP7.0 and the NFS:
For some reason, the application can write to the directory but is_writable returns false.
I have created the following PHP script:
<?php
$dirname = '/var/churros/data/nextcloud/';
//$dirname = '/tmp/';
$myfile = fopen($dirname.'newfile.txt', "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
fclose($myfile);
echo nl2br("File ".$dirname."newfile.txt written\n");
if (touch($dirname.'/chkpt.tmp')) {
echo nl2br("touch(".$dirname."/chkpt.tmp) successful\n");
} else {
echo nl2br("touch(".$dirname."/chkpt.tmp) failed\n");
}
if (is_writable($dirname)) {
echo 'Directory '.$dirname.' is writable';
} else {
echo 'Directory '.$dirname.' is not writable';
}
phpinfo();
?>
The result is that
newfile.txt is created in the data directory with the given text (John Doe)
Touch succeeded, i.e. the checkpoint file is created
is_writable returns false Screenshot of 'debug.php' with NFS directory
When I change to directory to a local directory like \tmp everything is fine Screenshot of 'debug.php' with /tmp directory
My NFS is mounted as
192.168.1.100:/volume1/pidata/donut on /var/churros type nfs4 (rw,relatime,vers=4.0,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.103,local_lock=none,addr=192.168.1.100)
and obviously the user mapping and access rights are correct:
namei -l /var/churros/web/nextcloud/
f: /var/churros/web/nextcloud/
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root churros
drwxr-xr-x www-data www-data web
drwxrwxr-x www-data www-data nextcloud
On the command line, as user www-data, I can access the directory and write to it as well.
Finally, SELinux is not installed/enabled on the box.
So: Any idea why PHP is_writable fails on the NFS directory or how I can debug this PHP function?
The issue could be the unix user id is different for user "www-data" for the 2 different systems.
In detail, from the php src, you can see that:
is_writable() is defined at ext/standard/php_filestat.h, which uses:
php_stat header file defined at php_stat()
VCWD_ACCESS() function is used
In turn:
VCWD_ACCESS()
is a convenience wrapper for virtual_access()
virtual_access()
is thread safe wrapper around the access() function that takes
per-thread virtual working directories into account.
Finally, looking access() doc:
The access() function checks the file named by the pathname pointed to by the path argument for accessibility according to the bit pattern contained in amode, using the real user ID in place of the effective user ID and the real group ID in place of the effective group ID.
and also at the access() linux documentation, it states:
access() may not work correctly on NFS file systems with UID mapping enabled, because UID mapping is done on the server and hidden from the client, which checks permissions. Similar problems can occur to FUSE mounts.
Try:
var_dump(stat('nfs-filename'));
and see which uid you get.
Reference:
Similar issue with php session in nfs
Most likely this is is_writable() function's bug.
You may fix this NextCloud issue:
} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
//common hint for all file permissions error messages
$permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
[$urlGenerator->linkToDocs('admin-dir_permissions')]);
$errors[] = [
'error' => 'Your data directory is not writable',
'hint' => $permissionsHint
];
AND
/usr/share/webapps/nextcloud/lib/private/Console/Application.php
if ($input->getFirstArgument() !== 'check') {
$errors = \OC_Util::checkServer(\OC::$server->getSystemConfig());
if (!empty($errors)) {
foreach ($errors as $error) {
$output->writeln((string)$error['error']);
$output->writeln((string)$error['hint']);
$output->writeln('');
}
throw new \Exception("Environment not properly prepared.");
}
}
Source #1, Source #2

Magento Connect permissions are not correct (tried a number of solutions none work) how do I fix this?

I believe this is a common issue when you get the warning
Warning: Your Magento folder does not have sufficient write permissions.
I've tried
find . -type d -exec chmod 777 {} ;
and
find . -type f -exec chmod 755 {} ;
but that doesn't seam to help, I believe I used different permissions than 777 but I would like to keep it more secure...
I have a feeling that it might be because of my VirtualHost setup. My Magento is at /var/www/example.com/public_html and the VirtualHost part is function because example.com takes you to my site.
I am not sure ./mage handles everything properly and is a bit of a pain but I use SSH so that has been my only solution.
This isn't going to be your Apache setup -- this warning has to do with PHP's ability to write files to the file-system. That's how Magento Connect does its job -- when you're interacting with the GUI frontend PHP will download tgz Connect Packages to your local files system, and then uncompress and untar them into your Magento installation. PHP needs the ability to create folders. If you're running apache as an unprivileged user and your folders/files are owned by a privileged user (usually your user account), this means you need to give folders 777 if you want to use the Magento Connect GUI to install packages.
What 777 means is any user account on the computer has the right to create files in that directory. The security risk is if a hacker managed to gain access to an unprivileged user account they'll be able to create files in this folder that will help them exploit the server further, or exploit the web application itself. If you're on a server that has multiple user accounts (shared hosting) it also means those other users have the right to create files in those folders.
Good shared hosting companies have monitoring to help prevent this, but most shared hosting companies are not good, and this permissions problem is probably the most common reason for exploits to any PHP based web application.
Also, the Magento Connect GUI is notorious for passing on false information about permissions. You'll often run into situations where it reports something installed successfully, but hasn't. If you run into this situation I wrote an n98-magerun command a while back that can validate a connect extension as correctly installed or not.
So, to your specific problem, the best way to track this down is to look at Magento Connect's source and determine which file(s)/folder(s) it thinks have incorrect permissions.
$ ack 'Your Magento folder does not have sufficient write permissions' downloader
downloader/lib/Mage/Connect/Command/Install.php
105: 'Your Magento folder does not have sufficient write permissions, which downloader requires.'
downloader/template/install/writable.phtml
32:<p>Your Magento folder does not have sufficient write permissions, which this web based downloader requires.</p>
downloader/template/writable.phtml
28: <h4>Warning: Your Magento folder does not have sufficient write permissions.</h4>
The first place is an exception message
#File: downloader/lib/Mage/Connect/Command/Install.php
if (!$isWritable) {
$this->doError($command, $err);
throw new Exception(
'Your Magento folder does not have sufficient write permissions, which downloader requires.'
);
}
If you look in the try block, you'll see two places where isWritable could be set to false
$isWritable = is_writable($config->magento_root)
&& is_writable($config->magento_root . DIRECTORY_SEPARATOR . $config->downloader_path)
&& is_writable($config->magento_root . $dirCache)
&& is_writable($config->magento_root . $dirTmp)
&& is_writable($config->magento_root . $dirMedia);
$isWritable = $isWritable && is_writable($config->magento_root . $dirMedia)
&& is_writable($config->magento_root . $dirCache)
&& is_writable($config->magento_root . $dirTmp);
Adding some temporary debugging code after these lines can help you track down which directories Magento thinks don't have write permissions.
if(!$isWritable)
{
var_dump($config->magento_root);
var_dump(is_writable($config->magento_root));
var_dump($config->magento_root . $dirCache);
var_dump(is_writable($config->magento_root . $dirCache));
//etc..
}
Next up are those writable.phtml template files. Magento connect has its own simple template system, so we'll want to search for places where it renders these writable.phtml templates
$ ack 'writable.phtml' downloader
downloader/template/connect/packages.phtml
28:<?php if ($this->get('writable_warning')) echo $this->template('writable.phtml');?>
It's only mention is in another template. If we search for this packages.phtml template file
$ ack 'packages.phtml' downloader
downloader/Maged/Controller.php
315: echo $this->view()->template('connect/packages.phtml');
We'll find the writable_warning variable is set is the isWritable method
File: downloader/Maged/Controller.php
if (!$this->isWritable() && empty($remoteConfig)) {
$this->view()->set('writable_warning', true);
}
public function isWritable()
{
if (is_null($this->_writable)) {
$this->_writable = is_writable($this->getMageDir() . DIRECTORY_SEPARATOR)
&& is_writable($this->filepath())
&& (!file_exists($this->filepath('config.ini') || is_writable($this->filepath('config.ini'))));
}
return $this->_writable;
}
Again, some temporary debugging code can help us figure out why Magento thinks it doesn't have correct permissions.
if (is_null($this->_writable)) {
var_dump(is_writable($this->getMageDir() . DIRECTORY_SEPARATOR));
var_dump(is_writable($this->filepath()));
var_dump((!file_exists($this->filepath('config.ini') || is_writable($this->filepath('config.ini'));
//etc...
$this->_writable = is_writable($this->getMageDir() . DIRECTORY_SEPARATOR)
&& is_writable($this->filepath())
&& (!file_exists($this->filepath('config.ini') || is_writable($this->filepath('config.ini'))));
}
The answer should actually be: do not use Magento Connect. Use a proper version control system like git, separate core files from customisations via modman or composer. This is the correct and technically clean approach and prevents using Magento Connect.

Getting around PHP safe mode to write to server. Is it possible?

I have got the following problem since the server has safe mode turned on, and directories are being created under different users:
I upload my script to the server, it shows as belonging to 'user1'. All it is doing is making a new directory when a new user is created so it can store files in it.
New directory is created, but it belongs to 'apache' user.
'user1' and 'apache' are different users; and safe mode is turned on. So the php script cannot write to that newly created directory.
Now I have a problem!
One solution is to turn off safe mode. Also, a coworker suggested that there are settings that can be changed to ensure the directories are under the same user as the script. So I am looking to see if latter can be done.
But I have to ask. Is there a programatical solution for my problem?
I am leaning to a 'no', as safe mode was implemented to solve it at the php level. Also the actual problem may seem like the directory being created under a different user, so a programatic fix might just be a band-aid fix.
I've used this workaround:
instead of php mkdir you can create directories by FTP with proper rights.
function FtpMkdir($path, $newDir) {
$path = 'mainwebsite_html/'.$path;
$server='ftp.myserver.com'; // ftp server
$connection = ftp_connect($server); // connection
// login to ftp server
$user = "user#myserver.com";
$pass = "password";
$result = ftp_login($connection, $user, $pass);
// check if connection was made
if ((!$connection) || (!$result)) {
return false;
exit();
} else {
ftp_chdir($connection, $path); // go to destination dir
if(ftp_mkdir($connection, $newDir)) { // create directory
ftp_site($connection, "CHMOD 777 $newDir") or die("FTP SITE CMD failed.");
return $newDir;
} else {
return false;
}
ftp_close($connection); // close connection
}
}
You might be able to turn safe mode off for a specific directory via a .htaccess file (if on Apache).
php_value safe_mode = Off
You might need to get your hosting provider to make this change for you though in the httpd.conf.
I have had some success with setting the group bit of the upload directory to sticky.
PHP can then create directories inside it and write to it.
http://en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_directories
chmod g+s directory

Categories