Make WordPress Core

Opened 9 years ago

Last modified 6 years ago

#33332 new defect (bug)

Default ACL entries are not set correctly when file is uploaded to WP

Reported by: slavafomin's profile slavafomin Owned by:
Milestone: Awaiting Review Priority: normal
Severity: major Version: 4.1.1
Component: Filesystem API Keywords:
Focuses: administration Cc:

Description

Hello there!

We are using ACL permissions on our server in order to isolate all websites from each other. Both nginx and php-fpm has it's own users. Actually, each website has it's own php-fpm user.

The ACL permissions are set for new files via default permission set:

getfacl -a ./sitename/wp-content/uploads

# file: sitename/wp-content/uploads
# owner: www-data
# group: www-data
user::rwx
user:nginx:r-x
user:fpm-sitename:rwx
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:nginx:r-x
default:user:fpm-sitename:rwx
default:group::rwx
default:mask::rwx
default:other::---

So, when I manually create a file, the correct ACL permissions will be set for it by the filesystem itself:

$ sudo -u fpm-sitename touch test
$ getfacl ./test

# file: test
# owner: fpm-sitename
# group: fpm-sitename
user::rw-
user:nginx:r-x			#effective:r--
user:fpm-sitename:rwx		#effective:rw-
group::rwx			#effective:rw-
mask::rw-
other::---

And nginx will be able to read and serve it.

However, when I upload a file through the WordPress it has no ACL entries at all.

I've looked through the code and the following part of the _wp_handle_upload() seems to be the culprit:

	// Set correct file permissions.
	$stat = stat( dirname( $new_file ));
	$perms = $stat['mode'] & 0000666;
	@ chmod( $new_file, $perms );

After commenting it out uploading works like a charm and proper ACL entries are set as expected.

We're using Ubuntu Server 14.04.3 LTS.

Cheers!

Change History (6)

#1 @SergeyBiryukov
9 years ago

Introduced in [2979], changed in [3501].

#2 @dd32
9 years ago

Hey @slavafomin - Sorry it's taken a while to get a reply.

Can you let us know what the permission bits look like when the file is created? Can we tell that the files permissions don't need changing at all?
ie. Is the file being reported as rw-rw-r--?

One of the problems with ACLs at present is that PHP applications don't have any way of seeing them, we can't verify or set them.. yet we can use the all-too-basic Owner/Group/World chmod values.
It seems that the best solution here is that we verify if the permissions need to be changed, before we change them, so as to avoid having the ACLs reset - to be clear, we're not going to be able to prevent the ACLs being reset in all cases, but we can work to avoid them being reset needlessly.

#3 @slavafomin
9 years ago

Hello! I'm sorry for such a late respond.

The thing is, that I'm not actually a frequent user of the Wordpress itself. I've just stumbled into this issue when were asked to deploy one of the projects to our server with ACL configuration. I'll not be able to provide additional information at this point.

However, I think this issue can be very easily tested and repeated in an isolated environment. Just fire up a virtual machine with latest Ubuntu server in it and setup an ACL.

I think the most simple solution/workaround would be to provide a global configuration option like "Do not change mode for uploaded files".

#4 @brudas
8 years ago

I've just checked this on 4.5.2:

Higher-level directory permissions, set manually with setfacl:

$ getfacl 2016
# file: 2016
# owner: root
# group: root
user::rwx
user:www-data:rwx
group::---
group:SA:rwx
group:webdesigner:rwx
mask::rwx
other::---
default:user::rwx
default:user:www-data:rwx
default:group::---
default:group:SA:rwx
default:group:webdesigner:rwx
default:mask::rwx
default:other::---

Wordpress-made directory permissions

$ getfacl 2016/05/
# file: 2016/05/
# owner: root
# group: root
user::rwx
user:www-data:rwx
group::---
group:SA:rwx
group:webdesigner:rwx
mask::rwx
other::---
default:user::rwx
default:user:www-data:rwx
default:group::---
default:group:SA:rwx
default:group:webdesigner:rwx
default:mask::rwx
default:other::---

Wordpress-uploaded file permissions

$ getfacl 2016/05/Exadel-Inc.-Calendar-Event-Details-Mozilla-Thunderbird-2016-05-24-09.59.34.png 
# file: 2016/05/Exadel-Inc.-Calendar-Event-Details-Mozilla-Thunderbird-2016-05-24-09.59.34.png
# owner: www-data
# group: www-data
user::rw-
group::rw-
group:SA:rw-
mask::rw-
other::---

Manulaly-created file permissions:

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ touch 2016/05/testfile.txt
$ getfacl 2016/05/testfile.txt
# file: 2016/05/testfile.txt
# owner: www-data
# group: www-data
user::rw-
user:www-data:rwx		#effective:rw-
group::---
group:SA:rwx			#effective:rw-
group:webdesigner:rwx		#effective:rw-
mask::rw-
other::---

So when I create file myself under web server account - permission inheritance works well.
When I upload files using Wordpress - something going wrong, not all permissions inherited, for example "webdesigner" group lost access, explicit ACL item for 'www-data' user that should be inherited from directory's default ACL lost too.

Here is my system information:

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.4 LTS
Release:	14.04
Codename:	trusty

$ php -v
PHP 5.5.9-1ubuntu4.16 (cli) (built: Apr 20 2016 14:31:27) 

Thank you.

Last edited 8 years ago by brudas (previous) (diff)

#5 @alin104n
8 years ago

  • Severity changed from normal to major

I use also a default ACL to secure WP(see setfacl command). Since WP insists on doing its own chmod stuff, it breaks the ACL. The thing is that in the past, the WP chmod stuff didn't protect me, the ACL did. This needs a fix. Until then just commenting the block suggested by @slavafomin is not enough. You have to comment the all the chmod functions content from wp-admin/includes/class*.

Last edited 8 years ago by alin104n (previous) (diff)

#6 @MarioLipinski
6 years ago

For me this looks like this issue is more related to file uploads being moved than to any chmod handling. When the file is moved, they keep the ACL they had before moving. As a workaround you could enforce the desired ACL on PHPs upload_tmp_dir.

Note: See TracTickets for help on using tickets.