Convenient way to use wp_filesystem

No, there is not a more convenient way.

The thing is, your first example is insecure on the most common hosting systems because the directory will be “owned” by whatever user the webserver itself is running as. Thus, anybody else able to execute code on that same webserver will be able to access it, write to it, changes files in it, and so on.

Credentials are necessary to ensure that the files are owned by the correct person, preventing them from being accessed by others on the same server.

Additional info because the comments seem to need it:

On a “standard” shared hosting configuration, or even on some VPS hosting systems, the webserver is running as a different user than the person who actually owns the files. So, my WordPress install files might be owned by “otto”, but the webserver maybe runs under the “apache” account.

This means that when the WordPress code is running, it’s typically running as the “apache” user. Any files it creates will also be owned by “apache”, not by “otto”. Furthermore, the “apache” account is necessarily limited. It may not have the ability to write files in my web directories at all, or it may not have the ability to chown the files to be owned by the proper “otto” user. This is all for security reasons, it should not have those abilities.

The WP_Filesystem detects when this is the case, and then will display a form to the user asking for FTP credentials. This is what the request_filesystem_credentials call actually does: It performs that test and then generates a form for the user when necessary. The user puts in their information, and using that, on the next submit, the request_filesystem_credentials call can check if it can connect back to itself (loopback, sorta) via FTP.

See, when I create a file via FTP, then I’m connected as me, so the resulting file is owned by “otto”. Using this mechanism, the WP_Filesystem can create files as the correct user even though it’s running as “apache”. Those credentials are thus necessary and yes, you must ask the user for them. Simply naively creating files and directories using normal PHP methods can lead to a security issue, especially on shared hosting.

On a shared host, other people have accounts on the same machine. They are running their code using the same webserver processes. And that code runs as “apache” too. So, if I have directories and files owned by “apache”, then other people can run their code as “apache” and modify my files. That’s a problem. Having the files owned by me and not “apache” prevents that.

Now, on some of the most common shared hosting systems, you’ll find that making the request_filesystem_credentials call actually doesn’t pop up a form. Instead, it simply returns true and the WP_Filesystem code carries on. This happens when a hosting system is running with a configuration known as “setuid” or “suphp”.

In a setuid configuration, the webserver runs as “apache” or whatever, but the PHP process that it spawns to handle a request sets its own user/owner to be the same as the owner of the PHP file that it initially runs. So when the php process runs, and loads the initial WordPress index.php file (or whatever file), it sees that the file is owned by “otto” and so it sets it own user account to “otto” for that particular run.

A lot of shared hosting providers do this configuration because it is actually more secure for that case. If the php process runs as the user account, then it is not “apache” any more and cannot access files in other people’s accounts. It can only access the files for the account it’s supposed to have access to. As a nice side effect, this means that the request_filesystem_credentials call performs its test and finds that a) yes it can write files and b) those files will be owned by the correct user, because the user of the process is now set to the same as the owner of the files. In that case, the “direct” mode is used, request_filesystem_credentials returns true, and no form is displayed to the user for FTP credentials.

Note that setuid methods like this are actually less secure on non-shared hosting accounts. When there is only one web user, then there’s no need to do setuid to protect other web users on the same server. So on VPS hosting and similar, this setup is not as common, and requiring FTP credentials is commonplace. This is more secure because even if an attacker can cause the system to execute code, they may not be able to have that code modify any files because it’s not running as the correct process.

Security is complex. The WP_Filesystem is fundamentally a security thing, and you should use it if you need to manipulate files in the installation. And yes, sometimes this means you need to display a credentials form. I suggest coping with it, because anything else is a potential security risk that you should not simply wipe away just because it’s somewhat unpleasant.

Leave a Comment