Here at the $dayjob we are often asked about file permissions by our customers who are developing websites. The main issues seem to be when a CMS system like Joomla or WordPress is being used, however these notes are relevant to any system which allows the content to be generated through a web page on the same site, normally though an admin area.
Firstly, each file is given permissions which can be seen and altered via an FTP client, a typical example is:
drwxr-xr-x 19 myftpusername www 3072 Jun 28 2010 . drwxr-xr-x 218 root wheel 8704 Sep 16 12:26 .. -rw-r--r-- 1 myftpusername www 753 Mar 4 2011 .htaccess -rw-r--r-- 1 myftpusername www 529587 Jun 4 2009 index.php -rw-r--r-- 1 myftpusername www 9616127 Feb 16 2009 info.pdf
The important part of the listing is the first column which describes the permissions. The first charter denotes the type of object, but for the most part will be a ‘d’ meaning directory or a ‘-‘ meaning a file. The rest of the line is divided up into 3 x 3 characters which can either be:
r = readable w = writeable x = executable
the first block of 3 is the file owner, the second block is the group and the third block is ‘everybody’ or the world. e.g.
-rw-r--r-- 1 myftpusername www 753 Mar 4 2011 .htaccess
So the .htaccess file here can be read by and written to by the file owner (myftpusername) and read only by the www group and also read by the world. This is a normal set of permissions for a file on a web server for a normal non CMS website. Lets do another example…
-rwxr-xr-x 1 myftpusername www 9616127 Feb 16 2009 test.cgi
This file has full read, write & execute permissions for the the owner and read and execute permissions for the group (www) and the world. Its a cgi file suit needs to executable or it won’t run.
The file permissions can also be represented numerically as follows:
read permission adds 4 to its total write permission adds 2 to its total execute permission adds 1 to its total
So for read, write and execute the value is 7, for read and execute, the value is 5, etc. Here are some examples:
-rwxr-xr-x = 755 -rw-r--r-- = 644 -rw-rw-rw- = 666 -rwxrwxrwx = 777
More information on UNIX based systems: http://en.wikipedia.org/wiki/Filesystem_permissions
What permissions within the website?
These are some permissions which generally ‘just work’:
- .php files – 644
- Perl files (.cgi or .pl) – 755
- .html / .htm files – 644
- txt files – 644
- css files – 644
- directories – 755 (must be executable to be opened)
The most confusion comes from CMS based systems where the end user updates the content through a web page, hopefully this page will be secured with a password as a minimum. In order for this to work the www user (the user that Apache runs as) needs to have write permission in the target directory, otherwise it cannot save or create the files. It should be apparent from this that files written by the Apache user, are owned by the www user, which is a member of the www group.
Allowing 775 access to any folder in a web site is clearly a security issue. Any script executing on the web server can write to the directory. Using a php script or perl script, finding the writable directories is trivial. It also means any website with a security weakness that permits uploaded code to be executed can cause a significant threat to other sites hosted on the same community server. This issue is an inherent problem with ‘user administered’ web sites. The core of the problem is that with a normal community hosting setup using Apache, all the Apache child processes (the processes that server the web pages) use the www user and so now the directory which is now writable by the www user, is in fact writable by anybody’s script on the web server. To clarify, if you have a directory with 775 permissions, any customer sharing the community server with you can now write into your directory. A CMS based site, not protected properly can lead to hackers uploading files containing code which can:
- change the permissions of files and directories
- re-write web pages to suit their needs
- delete content
- redirect traffic
None of which is desirable, most of which is avoidable.
There are some steps that we can take to help protect websites from other users and protect other users from our websites.
- Assign a decent username and password o the the CMS management interface. It seems a bit basic but most issues we see are from compromised passwords.
- Change the admin password on a regular basis.
- Limit admin access to specific IP addresses through a .htaccess file if possible.
- Use the the most restrictive set of permissions possible, 644 is a good starting point, but remember directories need execute permissions in order to let the content be read.
- Disable php/perl scripts running in customer upload directories via a .htaccess file
- Keep any third party applications up to date, such as WordPress, Joomla, PHPBB and the like. Sometimes this means asking your ISP to update system software, but don’t be afraid to ask!
- Ensure that PHP, Perl, MySQL, Ruby, Python or whatever applications and languages you use are patched and up to date, also the OS needs patching, especially if its Windows based.
- Virus scans should be run on the data stored in the web space by the ISP and the developer.
- An easy way to see if the site has been compromised is to check that the site on the server is what you expect it to be. When inspecting by FTP you may see file changes that are not possible through the CMS, in which case its worth investigating.
This is not an exhaustive list by any means, but certainly a start. I’ll add some .htaccess based posts at a later date which may clarify some of the preventative methods described above.