By default, fully hosted domains run PHP as a user with a document root under the user’s home directory. PHP therefore has read and write access to any file/folder in the users’s home directory, which is pretty bad security. The control panel has tools for creating new users and groups, so I figured it would be an easy problem to solve, but it is not as trivial as I first anticipated…
For the sake of the discussion, assume that my username is ‘admin’, my default group is ‘admingroup’, and the domain that I am setting up is ‘example.com’. My web directory is set to the following in the control panel: /home/username/web/example.com/r01/docs/
I use the Smarty template engine, so the filesystem is as follows:
(1) ~/web/example.com/r01/docs/ contains display code,
(2) ~/web/example.com/r01/smarty/ is a symlink to Smarty code,
(3) ~/web/example.com/r01/data/cache/ is the cache dir,
(4) ~/web/example.com/r01/data/configs/ is the configuration dir,
(5) ~/web/example.com/r01/data/libs/ contains business logic,
(6) ~/web/example.com/r01/data/resources/ contains resources,
(7) ~/web/example.com/r01/data/templates/ contains templates,
(8) ~/web/example.com/r01/data/templates_c/ is the compiled templates dir
Since the document root is set to (1), Apache cannot access anything else without PHP. If all of the directories are set to admin:admingroup drwxr-xr-x, however, PHP has read and write access to every one (as well as other directories). The desired permissions would give PHP read-only access to (1), (2), (4), (5), and (7) and read-write access to (3) and (8). (6) should be read-only unless the system needs to support uploading. Ideally, any other files/directories in the home directory, including those for other websites, should not be accessible at all.
My idea for a solution was to create a new user (‘comadmin’ for this example) for the sole purpose of running PHP. A new group (‘comgroup’ for this example) could then be created with members ‘admin’ and ‘comadmin’. Read-only permissions could be granted to a directory as follows: admin:comgroup drwxr-sr-x. Read-write permissions could be granted to a directory as follows: admin:comgroup drwxrwsr-x. (Note the SGID permission, which ensures that files created in the directories keep the group.)
Problem 1: This user is automatically assigned to the default group ‘admingroup’. Unfortunately, this means that running PHP as this user would still give PHP read access to the whole home directory.
Problem 2: When you set PHP to run as the new user, the document root automatically changes to that user’s home directory, since you cannot change the ‘/home/username/’ part in the control panel.
I have two ideas for working around the second problem.
Idea 1: Use ‘…’ when setting the document root, as follows:
This is ugly, but it may work…
Idea 2: Create directory ~comadmin/web with permissions comadmin:admingroup drwxrwxr-x. Create ~comadmin/web/example.com with permissions admin:comgroup drwxr-sr-x. Move the web data to that directory with appropriate permissions, and create a symlink from ~admin/web/example.com to ~comadmin/web/example.com. I don’t like this because it is not very organized, but it may work…
The only way to work around the first problem would be to set group permissions of any file that I don’t want visible to PHP to -RWX. This still leaves any files owned by comadmin readable, but it is not a problem since the user is created for the sole purpose of running the example.com website and should not own any files.
Since both of my ideas are hacks, I figured that I would post here to see if anybody else has dealt with the permissions security problems. If you have any comments on my ideas or other solutions, please let me know! Thanks!