13

What are the perfect minimal permissions in octal format for the followings in a web application written?

  1. A directory where user uploaded static files (images/swf/js files) will reside
  2. A directory where admin uploaded static files (images/swf/js files) will reside
  3. A directory where libraries used in the application reside
  4. A directory where executable/browsable server side scripts will reside
  5. A directory where the already existing files (txt or xml) will be edited by code on server side

Here are my suggestions and justifications

  1. 555, everyone can read and write, no one can execute
  2. 544, owner alone can write, everyone else can only read, no one can execute
  3. 000, nobody needs to read, write nor execute, will only be used by web server?
  4. 661, owner can read, write, everyone else can only execute
  5. 600, owner can read, write (may not be needed), no one else can do anything

Now I'm interested in two things:

  1. Is there something commonly used in web based applications that I have missed in the first list?
  2. Is there anything you disagree with in the second list, what is your alternative, and why is it better?
user9517
  • 114,104
  • 20
  • 206
  • 289
user893730
  • 614
  • 2
  • 12
  • 20

3 Answers3

20

Presuming that a 'web application' runs on a server (like apache, nginx, etc) and is written in some dynamic scripting language (like PHP, Ruby, etc), you have a misunderstanding in who the 'user' is.

The user is not the person who is logged into your application - that, and their role in the application (admin, etc) is completely irrelevant to the scenario. The user is the linux system user that the process runs under. The code of your website is run as only one user - it may be the user of your webserver (which isn't really a good thing), or it may be a user specific to your site (which is much better).

On linux, users belong to groups - we can add a user to another group and assign privileges to that group.

A good setup will have your server run as one user (let's call this user 'webserver') and your dynamic scripting language run (e.g. via FastCGI) as its own user (one user per site - let's call our first user 'site1').

To serve your files, the webserver needs access to them, and the scripting language needs access to them. That means: 'site1' and 'webserver' need to be able to read your files. Only one of them, however can 'own' the files. The owner is the 'user' (in user, group, other). We also need our scripting language to be able to write to the directory (and read the files it has written). The user 'site1' therefore, needs read and write permissions. Since we want group and other permissions to be as restrictive as possible, our 'owner' will be 'site1', and the corresponding user permissions will be read and write.

Since we cannot specify the permissions for our webserver as another 'user', we will add 'webserver' to the 'site1' group (you could of course, create a different group with both 'site1' and 'webserver' in it. All members of this group will be given the same permissions. The most lax permissions (of the user, group, other set) will be applied to any given user to determine their permissions.

It is worth noting that a good setup should not require files to have execute permissions for a dynamic language. The files are not directly run, but rather are read into an interpreter - only read permissions are needed to run a typical script (one that doesn't write anything).

The 'execute' permission on directories has a different meaning - it permits traversal without being able to read the contents. In order to be able to read a file in a directory, a user must have 'execute' permissions on EVERY directory above it.

For a web application, every file must have read permissions by its owner - otherwise, it is a fairly pointless file. Whether a user or an admin uploads files (via your web application) the 'owner' (i.e. the dynamic language) needs write permissions. An efficient setup will try to serve static files directly via the web server, as dynamic languages tend to be slow at reading in large files and echoing out the contents. The web server therefore needs read access to your static files.

Therefore, the minimal file permissions may be:

  • A file in a directory where user uploaded static files (images/swf/js files) will reside: 640
  • A file in a directory where admin uploaded static files (images/swf/js files) will reside: 640
  • A file in a directory where libraries used in the application reside: 400 (or 440)
  • A file in a directory where executable/browsable server side scripts will reside: 400 (or 440)
  • A file in a directory where the already existing files (txt or xml) will be edited by code on server side: 640 or 600
    • (depends on whether the web server will display these, unmodified at times)

While, the minimal directory permissions may be:

  • A directory where user uploaded static files (images/swf/js files) will reside: 750
  • A directory where admin uploaded static files (images/swf/js files) will reside: 750
  • A directory where libraries used in the application reside: 500 (or 550) [should be 510 at least]
  • A directory where executable/browsable server side scripts will reside: 500 (or 550) [should be 510 at least]
  • A directory where the already existing files (txt or xml) will be edited by code on server side: 750 or 700
    • (depends on whether the web server will serve files from here, unmodified at times)

Once again - your web server must have 'execute' permissions on every directory above the one it needs access to - so even if the web server won't serve files from a given directory, we should grant it execute permissions.

It is fairly common to give the web server read access to most of the files (so change those 500 to 550). Default 'somewhat secure' permissions are commonly 755 for directories and 644 for files - no execute permissions, everyone can read, and only the user can write - you will note that the vast majority of files on a linux system have these permissions.

Keep in mind that the 'other' permissions refer to any system user who is not the owner or in the group (i.e. all remaining system users). Keeping your 'other' permissions restrictive is good, because these users are an unknown - you haven't explicitly given them permission. The other permissions are often the easiest to take advantage of on a compromised system (e.g. one of the reasons why /tmp is a common target).

In the context of the above, I don't think your last two questions are that relevant. Set your directory permissions to 550 (and file permissions to 440), and then grant the user write permissions for whatever directories your application will be writing to (i.e. directory: 750; file: 640).

(You will obviously need write permissions to upload the files - but if you wish, you can remove those afterwards - arguably though, if someone is writing to a directory which only the owner can write to - your account has been compromised - which is one of the reasons for keeping restrictive permissions).

cyberx86
  • 20,620
  • 1
  • 60
  • 80
1

It is normal to have the minimum set of permissions to get the job done. If you have your webserver and users share a common group then you can remove the need to give any access to o. Permissions are also related to users. You appear to have misunderstood the octal permissions.

  1. 555 is r-xr-xr-x not rw-rw-rw. As it's a directory then to create/delete files you need to have x set so 750 rwxr-x--- would be a good place to start. This allows the user that owns the directory to add/remove files and everyone in the common group to access them.
  2. The same as 1. above.
  3. If they are truly static files than 050 would give the web server access however to create the files in the first place 750 would be a minimum.
  4. The same as 3 above.
  5. 070 would be the minimum to allow the webserver to read and change the files but the files need to be created so 770 is probably more realistic.
user9517
  • 114,104
  • 20
  • 206
  • 289
  • Wouldn't the web server need execute permissions on the directory to read the files (points #1 (740?), 3, 5)? – cyberx86 Jan 02 '12 at 09:25
  • Doh! indeed x is required to access the files r just allows you to list them... ambles off for more coffee. – user9517 Jan 02 '12 at 09:45
0

In general one would use mode 0755, 0775, or 2775 on directories (the SGID bit on directories, for BSD and for Linux if the filesystem is mounted with BSD semantics will make the group association of new files match the parent directory settings rather then the default GID of the file's creator). This allows all users to traverse (chdir into and through) and read (run the ls command or perform the readdir/read system calls) the directories in question. The alternatives add group/write options and, as noted, the SGID bit, on directories, can help keep all the files and subdirectories associated with a suitable group.

For files one would normally use 0644 or possibly 0664 (world readable and either group writeable or not). Obviously for CGI scripts and binaries one must add the x-bit; and for some special situations, with extremely well tested binaries, one might add SUID or SGID bits. Normally UNIX and Linux will ignore the SUID/SGID bit on scripts and only honor its semantics for native compiled, executable binaries. However you might be running your site under something like Apache with some module like the "setuidhack" which can be used to make the web server honor the SUID/SGID bits even on interpreted scripts. (This is done by the HTTP daemon stat()ing each file and using its own custom fork()/execve() code, interpolating the correctly interpreter string into the execve() vector rather than simply passing the executable's name directly to an execve() system call).

Those are just the most general guidelines. They aren't "perfect" for all situations and you should definitely consult the docs for your web server and any web application or frameworks that you're installing and configuring ... and you probably want to consult with a UNIX security expert before you expose any of your files, code or servers to the public Internet.

Jim Dennis
  • 807
  • 1
  • 10
  • 22