WordPress Sample Code on GitHub
Considering WordPress Plugin Development? Do a search on GitHub for “WordPress plugin“ and find all the sample code you ever wanted.
Considering WordPress Plugin Development? Do a search on GitHub for “WordPress plugin“ and find all the sample code you ever wanted.
When WordPress fails to do something automatically, it’s almost always a permissions problem. This is no exception.
I haven’t found an easy and secure way to enable automatic WordPress updates. The only way I have found is to make all WordPress files and folders writable by the web server process...
chgrp -R web ...
This isn’t a good solution, but it may be the only option for clients that can’t do updates any other way. It’s too insecure and it’s not suitable for a production website. I need to keep looking for a better way. I’ll be looking into other ways of Hardening WordPress as well.
Any answer that includes chmod -R 777 ...
or chgrp -R ...
introduces a security problem. If you do this, anyone who visits your site can potentially add/delete/modify files and run arbitrary code.
By the way, most web hosts run their services in a Unix-like environment. If you’re not familiar with Unix file and directory permissions, it’s a good idea to learn.
If you say the only solution is to do a manual upgrade, you’re basically giving up on WordPress’ automated tools. It doesn’t fix anything and I’d almost certainly face the same problem next time it’s time for an upgrade.
Some would say that we sacrifice security when we rely on WordPress’ automated tools for installing themes, installing plugins, or performing updates. We should perform all server-side administration manually because it’s more secure.
Well, that’s a valid point. However, I’d argue that just by using WordPress we paint a big target on our website for hackers.
A site built with read-only files written in static HTML and CSS and no database would no doubt be more secure than any WordPress site, but we trad some of that security for the power and convenience of WordPress. There should be a way to balance security and convenience.
This option also doesn’t work for clients who are less technically inclined. I build sites for people who aren’t interested in learning about SSH, tar, and gzip. And I’m not interested in performing manual updates for a hundred clients with automatic updates disabled.
I started looking into the code with update-core.php
, which was mentioned in the error message. I’m not going to go into detail on the whole convoluted process, but the gist of it is that it checks a list of files for writability and if it finds any that can’t be overwritten, it appends their names to the end of the error message.
In this case there’s only one file, but I want to try and make this future-proof if I can.
Here’s a relevant block of the code from wp-admin\includes\update-core.php
:
// If we're using the direct method, we can predict write failures that are due to permissions.
if ( $check_is_writable && 'direct' === $wp_filesystem->method ) {
$files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) );
if ( $files_writable !== $check_is_writable ) {
$files_not_writable = array_diff_key( $check_is_writable, $files_writable );
foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) {
// If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
$wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE );
if ( $wp_filesystem->is_writable( $file_not_writable ) ) {
unset( $files_not_writable[ $relative_file_not_writable ] );
}
}
// Store package-relative paths (the key) of non-writable files in the WP_Error object.
$error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : '';
if ( $files_not_writable ) {
return new WP_Error( 'files_not_writable', __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ), implode( ', ', $error_data ) );
}
}
}
A WordPress update might need to overwrite any of the files that are part of the installation. It might need to add new files, too. As far as I can tell, the only way is to make all of these files and directories writable by the (UNIX / Linux) user that runs the website. That’s not a solution.
Most of the time, when you need to update a plugin, a theme, or even WordPress core, you just click an update button and the rest is handled automagically. This works because web hosts usually set the web server to use the same user as the one that owns the files. This has some inherent security problems.
My current hosting provider takes an opinionated approach to security which, among other things, breaks WordPress’ automated updates by default. They even discourage the use of FTP, calling it “an obsolete protocol that should never be used“.
Now that I understand the cause of the problem, I can easily fix it by changing the appropriate file and directory permissions. In fact, the first solution I’d be likely to find on the web would be to just recursively remove restrictions (chmod 777
) on certain directories. But my host’s admin team isn’t wrong. As the Hardening WordPress article at wordpress.org explains “allowing write access to your files is potentially dangerous”.
SSH seems like it should be a better solution. The login process itself is more secure than FTP and it allows you to perform updates with a different user than the one the web server uses. WordPress even has limited inbuilt support for SSH. The problem here is that it requires you to put your SSH login credentials within reach of WordPress and that usually means they’re also within reach of the entire Internet. This presents a far greater risk than file and directory permissions.
I thought that if automated updates are a basic WordPress feature, there must be way to get it to work without compromising security. But I’ve done a lot of reading and performed a lot of trial and error. I’ve even read carefully through code to understand the process more fully. After all that, I’m beginning to agree with the idea that WordPress shouldn’t update itself. Yes, you can get it to work but there’s always a trade-off between security and convenience. It would only take one bad experience to make you regret avoiding a few manually typed SSH commands.