By default, your site is set up with secure default permissions that don't allow web scripts to write files anywhere except in /tmp. You must set permissions to allow any additional locations to be written.
In order for a PHP or CGI script, or a daemon processes run as the "web" user, to write to a file, the "web" user must have write access to that file. There are two ways to accomplish this.
- Set the file to be owned by the web group and set the permissions to allow group-writes. (E.g. chgrp web example.file and either chmod g+w example.file or chmod 664 example.file from the command line.)
- Set the file to allow any writes. (E.g. either chmod a+w example.file or chmod 666 example.file from the command line.)
In order for a script or web process to create a file, it's the permissions of the directory in which the file is to be created that matter. To allow this, do either of the following:
- Set the parent directory to be owned by the web group and allow group writes. (E.g. to create /parent/dir/example.file, first chgrp web /parent/dir and then either chmod g+w /parent/dir or chmod 775 /parent/dir from the command line.)
- Set the parent directory to allow any writes. (E.g. to create /parent/dir/example.file, do either chmod a+w /parent/dir or chmod 777 /parent/dir from the command line.)
The choice of whether to use group-write or all-write is one of personal preference. There is no meaningful difference on our system at this time. Likewise, the choice of semantic ("a+w") vs. octal (777) is one of personal preference. Just be careful not to set directories to 666 permissions, as they will not work correctly and the result can be very confusing.
If you look online, you may find advice telling you to set all directories to 777 and all files to 666. This is terrible advice. Roughly translated it means "I don't understand Unix file permissions well enough to help you, but doing this will hide the problem for now, and I'll be long gone when this terrible advice I'm giving you lets hackers completely overwrite your site."
PHP's security track record is not very good, and our system security is designed primarily to protect sites from each other; it does not (and cannot) protect sites from themselves. So while "writeable everything" may appear to work initially, and it seems easy, sooner or later a flaw will be found in your site's PHP code or in PHP itself, and if your site is full writeable files and directories, hackers will make short work of it. When deciding what to make writeable, please keep in mind the old adage, "If you don't have time to do it right, when will you have time to do it over?"
In particular, we strongly discourage members from making script files and key directories (like /home/public) writeable by the web user. This setting is used by some applications to enable self-updating over the web. We discourage that practice as well; if you can update your site over the web, so can someone else, and the site may look very different when they finish with it. We recommend using out-of-band methods to update site applications. For example, we support and recommend the use of the WP-CLI command line tool to keep WordPress installations up-to-date without exposing them to massive compromise resulting from the frequent security problems WordPress is so famous for.
Therefore, the final rule of thumb for writing files is not to set anything to be writeable over the web unless you don't mind restoring it from backup after hackers get to it. We hope this encourages you to both be conservative in what you allow PHP to write, and to keep good backups. :-)
Note: If you are still using a version of PHP older than 5.4, there are additional requirements. However, if you are still using a version of PHP prior to 5.4, stop now and upgrade because writing files is the least of your problems.