- umask
- Список параметров
- Возвращаемые значения
- Список изменений
- Примеры
- Примечания
- User Contributed Notes 14 notes
- PHP File Permissions
- Checking file permissions
- Changing file permissions
- Summary
- File permissions and umask in PHP and Shopware
- Permissions of new files and directories
- What is the umask?
- Examples
- Umask in PHP
- Umask in shopware
- Setting the umask
umask
umask() устанавливает PHP umask в значение mask & 0777 и возвращает старую umask. Если PHP используется в качестве серверного модуля, umask будет восстанавливаться после окончания каждого запроса.
Список параметров
Возвращаемые значения
Если параметр mask равен null , функция umask() просто возвращает текущую umask, в противном случае возвращается старая umask.
Список изменений
Примеры
Пример #1 Пример использования umask()
$old = umask ( 0 );
chmod ( «/path/some_dir/some_file.txt» , 0755 );
umask ( $old );
?php
// Проверка
if ( $old != umask ()) die( ‘При восстановлении umask произошла ошибка’ );
>
?>
Примечания
Замечание:
Избегайте использования этой функции в многопоточных веб-серверах. Лучше изменить права файла с помощью функции chmod() после его создания. Использование umask() может привести к неожиданному поведению одновременно работающих скриптов и самого веб-сервера, т.к. они все будут использовать одну и ту же umask.
User Contributed Notes 14 notes
I think that the best way to understand umask is to say that umask is used to revoke permissions, not to set permissions.
umask sets which permissions must be removed from the system default when you create a file or a directory.
For example, a mask 0022 means that you don’t want group and others modify the file.
default 0666 rw-.rw-.rw-
umask 0022 —.-w-.-w-
Final 0644 rw-.r—.r—
That means that any file from now on will have 0644 permissions.
It is important to understand that umask revokes, deletes permissions from system default, so it can´t grant permissions the system default hasn’t. In the example above, with the 666 system default, there is no way you can use umask to create a file with execute permission. If you want to grant more permissions, use chmod.
Be aware that system default permissions are not related to PHP (they depends upon server configuration). PHP has a default umask that is applied after system default base permissions. And there are different system default base permissions for files and directories.
Usually, system default permissions for files are 666 and for directories 0777. And usually, default PHP umask is 0022
«It is better to change the file permissions with chmod() after creating the file.»
The usual lacking of security knowledge within the PHP team rears its head once again. You *always* want to have the file created with the proper permission. Let me illustrate why:
(a) you create new file with read permissions
(b) an attacking script opens the file
(c) you chmod the file to remove read permissions
(d) you write sensitive data to the file
Now, you might think that the changes of an attacking script getting to open the file before you chmod them are low. And you’re right. But low changes are never low enough — you want zero chance.
When creating a file that needs increased permissions, you always need to create the file with the proper permissions, and also create it with O_EXCL set. If you don’t do an exclusive create, you end up with this scenario:
(a) attacker creates the file, makes it writable to everyone
(b) you open the file with restricted permissions, but since it already exists, the file is merely opened and the permissions left alone
(c) you write sensitive data into the insecure file
Detecting the latter scenario is possible, but it requires a bit of work. You have to check that the file’s owner and group match the script’s (that is, posix_geteuid(), not myuid()) and check the permissions — if any of those are incorrect, then the file is insecure — you can attempt to unlink() it and try again while logging a warning, of course.
The only time when it is reasonable or safe to chmod() a file after creating it is when you want to grant extra permissions instead of removing them. For example, it is completely safe to set the umask to 0077 and then chmoding the files you create afterward.
Doing truly secure programming in PHP is difficult as is, and advice like this in the documentation just makes things worse. Remember, kids, anything that applies to security in the C or UNIX worlds is 100% applicable to PHP. The best thing you can possibly do for yourself as a PHP programmer is to learn and understand secure C and UNIX programming techniques.
PHP File Permissions
Summary: in this tutorial, you will learn how to deal with PHP file permissions, including checking and changing file permissions.
File permissions specify what a user can do with a file, e.g., reading, writing, or executing it. Notice that PHP automatically grants appropriate permissions behind the scenes.
For example, if you create a new file for writing, PHP automatically grants the read and write permissions.
PHP provides some useful functions for checking and changing the file permissions.
Checking file permissions
PHP has three handy functions that check file permissions:
- is_readable() function returns true if the file exists and is readable; otherwise, it returns false .
- is_writable() function returns true if the file exists and is writable; otherwise, it returns false .
- is_executable() function returns true if the file exists and executable; otherwise, it returns false .
Let’s take a look at the following example:
$filename = 'readme.txt'; $functions = [ 'is_readable', 'is_writable', 'is_executable' ]; foreach ($functions as $f) < echo $f($filename) ? 'The file ' . $filename . $f : ''; >
Code language: HTML, XML (xml)
Besides those functions, PHP also provides the fileperms() function that returns an integer, which represents the permissions set on a particular file. For example:
$permissions = fileperms('readme.txt'); echo substr(sprintf('%o', $permissions), -4); //0666
Code language: HTML, XML (xml)
Changing file permissions
To change the file permission or mode, you use the chmod() function:
chmod ( string $filename , int $permissions ) : bool
Code language: PHP (php)
The chmod() function has two parameters:
- $filename is the file that you want to change the permissions.
- $permissions parameter consists of three octal number components that specify access restrictions for the owner, the user group in which the owner is in, and everyone else in this sequence.
The chmod() function returns true on success or false on failure.
The permissions argument is represented by an octal number that contains three digits:
- The first digit specifies what the owner of the file can read, write, or execute the file.
- The second digit specifies what the user group in which the owner is in can read, write, or execute the file.
- The third digit specifies what everyone else can read, write, or execute the file.
The following table illustrates the value of each digit that represents the access permission for particular users ( owner, user group, or everyone else) :
Value | Permission |
---|---|
0 | cannot read, write or execute |
1 | can only execute |
2 | can only write |
3 | can write and execute |
4 | can only read |
5 | can read and execute |
6 | can read and write |
7 | can read, write and execute |
The following example sets permission that the only owner can read and write a file, everyone else only can read the file:
$filename = './readme.txt'; chmod($filename, 0644);
Code language: HTML, XML (xml)
Notice that we put 0 before 644 to instruct PHP to treat it as an octal number.
Summary
- Use the is_readable() , is_writable() , is_executable() to check if a file exists and readable, writable, and executable.
- Use the chmod() function to set permissions for a file.
File permissions and umask in PHP and Shopware
This post requires basic understanding of Unix File system permissions.
Permissions of new files and directories
Have you ever wondered how the permissions are chosen for newly created files and directories?
Let’s assume the following example that creates a new directory named somedirectory and a new file called examplefile .
mkdir('somedirectory'); file_put_contents('examplefile', 'somedata')
What permissions will these files have?
It depends on the processes umask environment.
What is the umask?
The umask is the file mode creation mask. The mask is applied with a bit wise operation whenever a file is created.
It is represented in logic notation as: C: (P&(~Q)) This says that the file’s permission mode ( C ) is a result of a logical AND operation between the negation of the mask ( Q ), and the process’ requested permission mode setting ( P ).
New files are requested with permission mode 666 , directories with permission mode 777 . Given we have a umask of 022 as octal value and we create a new file the following permissions are calculated:
Requested File permissions: 666 (P) Umask: 022 (Q) 666 & ~(022) = 644 (C)
Examples
A umask 000 will allow read, write, and execute permission for all. This is a potential security risk and should not be used in production.
$ umask 000 # set umask $ mkdir testdirectory # create new directory $ touch somefile # create new empty file $ ls -l # list file permissions drwxrwxrwx testdirectory # 777 in octal -rw-rw-rw- somefile # 666 in octal
A umask 002 will allow allow read, write, and execute permission for the user and the group, others will only have read access.
$ umask 002 $ mkdir testdirectory $ touch somefile $ ls -l drwxrwxr-x testdirectory # 775 in octal -rw-rw-r-- somefile # 664 in octal
777 & ~(002) = 775 666 & ~(002) = 664
umask 077 Is the most restrictive umask. Only the user has access to the generated files.
$ umask 077 $ mkdir testdirectory $ touch somefile $ ls -l drwx------ testdirectory # 700 in octal -rw------- somefile # 600 in octal
777 & ~(077) = 700 666 & ~(077) = 600
Umask in PHP
PHP respects the umask even if the mkdir $mode parameter is set:
umask(0027) // set directly or by environment $mode = 0775; mkdir('somedirectory', $mode);
Given we have a umask of 027 this will result in the following permission:
PHPs chmod() on the other hand does not respect the umask.
umask(0027) // set directly or by environment $mode = 0775; chmod('somedirectory', $mode);
This will result in 775 permissions regardless of the umask setting of the process.
Umask in shopware
Shopware already respected the umask for some caches. Some other caches used hard coded permissions.
The Smarty Compile Cache for example used hard coded permission values:
// file engine/Library/Smarty/Smarty.class.php public $_file_perms = 0644; public $_dir_perms = 0771;
This is now changed to respect the umask:
// file engine/Library/Enlight/Template/Manager.php $this->_file_perms = 0666 & ~umask(); $this->_dir_perms = 0777 & ~umask();
Also the permissions of cache files are now using the umask instead of hard coded permissions:
// file: engine/Shopware/Configs/Default.php 'cache' => [ 'backendOptions' => [ - 'hashed_directory_perm' => 0771, - 'cache_file_perm' => 0644, + 'hashed_directory_perm' => 0777 & ~umask(), + 'cache_file_perm' => 0666 & ~umask(), ] ]
You can find all the changes in the Github Pull Request.
This changes will be included in the upcoming Shopware 5.1.4 release.
Setting the umask
Now that Shopware respects the umask for all cache files there no need to configure individual file creation permissions anymore. Just set the umask and Shopware will create files accordingly. The umask can be set in your Apache or PHP-FPM configuration, or by calling umask(0077); in you projects config.php .