WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#36936 new defect (bug)

Plugin update does not works via web with proper filesystem permissions.

Reported by: brudas Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.5.2
Component: Filesystem API Keywords:
Focuses: Cc:

Description

Hello all,

I run Wordpress 4.5.2 on Ext4 file system with POSIX ACL. Web server is Nginx, PHP runs as FPM daemon. Both under www-data user and group (for now).

When I try to update some plugin, Wordpress ask me to enter FTP credentials instead of doing update.

All output below was gathered under www-data account (PHP-FPM runs under it).

Here is my file system permissions:

Document root:

$ getfacl /var/www/html/
getfacl: Removing leading '/' from absolute path names
# file: var/www/html/
# owner: root
# group: root
user::rwx
user:www-data:r-x
group::---
group:SA:rwx
group:webdesigner:rwx
mask::rwx
other::---
default:user::rwx
default:user:www-data:r-x
default:group::---
default:group:SA:rwx
default:group:webdesigner:rwx
default:mask::rwx
default:other::---

wp-content

$ getfacl /var/www/html/wp-content/
getfacl: Removing leading '/' from absolute path names
# file: var/www/html/wp-content/
# 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::---

Plugins

$ getfacl /var/www/html/wp-content/plugins/
getfacl: Removing leading '/' from absolute path names
# file: var/www/html/wp-content/plugins/
# 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::---

Plugin to be updated:

$ getfacl /var/www/html/wp-content/plugins/postmatic/
getfacl: Removing leading '/' from absolute path names
# file: var/www/html/wp-content/plugins/postmatic/
# 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::---

Despite user www-data is explicitly granted to have write permissions to all required directories, Wordpress fails to start upgrade from web and asks for FTP credentials.

I believe PHP works well enough with POSIX ACL, here is simply proof script:

$ php -r 'if (posix_access( "/var/www/html/wp-content/", POSIX_R_OK | POSIX_W_OK)) {
echo "The file is readable and writable!\n";
} else {
    $error = posix_get_last_error();

    echo "Error $error: " . posix_strerror($error);
}'
The file is readable and writable!

If there are some reason to keep current filesystem permission check method intact - please, issue spcecial technical note regarding required permissions and how does Wordpress checking it.

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) 

There are no SuPHP, Suhosin or any suspicious extensions.

This issue could be related to https://core.trac.wordpress.org/ticket/34327

Thank you.

Change History (8)

#1 @andtrev
2 years ago

Hi @brudas,

I believe WordPress checks for ownership to see if it's allowed to write or not, in your case the owner is root, but your user is www-data, so it would fail that test.

A workaround for this type of setup is to add define('FS_METHOD', 'direct'); to your wp-config.php which will bypass the check and set it to write directly to files. - http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants

#2 @brudas
2 years ago

Hi @andtrev, thank you for FS_METHOD hint.

However, now days it is absolutely normal in Linux to have 000 legacy permission bytes with any owner and group on file and be able to read/write/execute it. POSIX ACL support available in mainline Linux kernel since at least year 2002 and PHP have posix_access() to check path availability. I hope posix_access() is binding for POSIX access(2) function which hides all access control machinery under the hood.

Are there any reasons for self-made interpretation of permission?

#3 @andtrev
2 years ago

It is by design, this has come up before and I don't remember exactly why this is the way they did it, but it has to do with shared hosting. If you look at the other tickets linked in the ticket you suggested as possibly related to your issue there are bits and pieces to why.

#4 @brudas
2 years ago

Many years ago posix_access() was banned due to CVE-2008-2665 on some shared hostings . Last discussion on similar topic was finished 3 years ago. It is nice to keep compatibility with very simply environment, but why not not to use general method instead of self-made?

#5 @andtrev
2 years ago

It could be because POSIX support is disabled automatically on some PHP installations and is not available on Windows. posix_access also falls back to checking ownership when safe mode is on, which would be for shared hosting situations.

#6 @brudas
2 years ago

PHP safe_mode in 2016? This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0

Windows NTFS have even more complicated ACL system.

I believe it is time to review this mechanics at least for Linux.

#7 @dd32
2 years ago

FWIW, the issue at play here isn't exactly read/write, it's the ability for the upgrade to happen in a way that the user can modify the files after the upgrade has occurred, and the web server can still serve them. It's possible for PHP to write a file to disk, be able to read it, but have the web server say "Nope! 403!" to someone who then tries to view that file.

WordPress operates on so many server configurations, and with PHPs very little support for/insight into the ACLs on both Windows and Linux leaves us with having to code for the lowest common denominator. That means that yes, we have to keep in mind PHP safe mode, we need to keep in mind linux ACLs, we need to keep in mind linux systems not using ACLs, Windows 2000~2010 servers, Unix servers, Mac servers.. etc, but then we also have to keep in mind FTP applications running upon those, which yes, a significant portion of WordPress users have as their only access to their WordPress files and hosting account.

So unfortunately at this time, WordPress can't really switch away from the existing owner-based checks while maintaining full compatibility that we currently have with those hundreds of thousands of configurations (okay, maybe it's not that many, but it wouldn't surprise me if it was).

We could use posix_access() if available, but that only operates on files (AFAIK) doesn't guarantee that we can actually modify the file even if it says we can, and isn't available on a significant portion of hosts either.

I know I'm not going to get a warm response to this, and that's okay, but I don't think we can support your configuration any better than we currently do, while also supporting everyone else, and having it "just work".

Last edited 2 years ago by dd32 (previous) (diff)

#8 @brudas
2 years ago

Please, document this behavior better. I see no useful information neither in Web nor in error log files, even nothing to Google. I've spent couple of days trying to 'fix' my permissions while Wordpress silently refuses me to update plugins via Web and search give me mostly ignorant advices to 777'em all. I believe, warning "Don't own our files, falling back to FTP" would be good enough.

Note: See TracTickets for help on using tickets.