I've set up Drupal for the private file access method (from the first day on), and in "access control" only certain roles have the privilege to access uploaded files - anonymous users have no access at all. Still it is possible to directly access any uploaded files by entering its address into the browser (like "http://mysite.com/files/secretfile.txt"), even if not logged in at all.

I manually added a "Deny From All" line to the .htaccess file Drupal created. It seems to be working for me, but is there a correct way to do it? Like, did I miss a configuration option?

I also noticed that Drupal changes the permission of the file & temp directories to 0775. Now that is bad, because it enables every other user on my server not only to read all the contents, but also to tamper with them. Again, all drupal access mechanisms are bypassed. Another user could even delete the .htaccess file and create a new one like RewriteRule ^(.*)$ badscript.php?p=$1 [L], and then the attacker would be in total control of any visitor accessing the file system path. Is there a special reason that the directories are world-readable and group-writeable or can I just change it into something more restrictive?

Where did I miss something during installation and configuration and messed up my Drupal?

Comments

dman’s picture

I've not tried it much, but I believed that 'private' files should have been stored outside of the webroot, not under /files/. Wasn't there an alternative path configuration?
Yes, if you are storing files anywhere under webroot, they can be accessed, but an htaccess is a reasonable solution.

Regarding permissions, you can imagine how many users on shared hosts can get crippled if the permissions are NOT opened up like that.
If Drupal (the http user) creates a file, the user, with a different login would have no access to administer those files via shell or FTP. Drupal has to grant group permissions to allow you to retain some control.

If you are worried about other users on the same host, you have a right to be, but there is NO FIX for this in many hosting configurations. Consider, if both you and j.Random.Hacker are running Drupal, or ANY PHP/CGI application on the same machine with the same httpd user working the web requests.
Hacker can simply run a script, invoked from a web page, to system('rm -r /path/to/YOUR/files/*');
- The script runs as httpuser, which is the same identity that Drupal ran when making those files. Thus, it can do what it likes. Hopefully it can't mess with your code files, but you are right, a malicious .htacces file is possible.
This vulnerability exists in many hosting environments, I've used it a few times just to get around access restrictions to fix things for clients :) EG: reading the current httpd.conf file to me when I wasn't allowed to see it myself.
The solution (which I haven't seen much) would be to run each webserver process with a different, site-specific username, or using cgiwrap or similar, with the users username. Depends on your host.

For slightly better security, it would have been good to have made the /files/ directory yourself, instead of letting Drupal do so. httpuser now owns it entirely, and I doubt either of you can 'chown' so the best you can do is 'share to group' - which is the behaviour you've seen.

Ask Drupal to GIVE you access

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

aw-1’s picture

Thanks for your ideas, dman. It seems you have been dealing with this topic before.

Now I understand the reasons for the settings and location of the /files directory (I'm quite new to Drupal, maybe a week or so, and inexperienced persons better follow the installation instructions word by word :) ). A choice between higher security for few, or higher support demands by many.
With the "Deny From All" directive in the .htaccess file, everything seems to be working as before. May I suggest that Drupal itself adds that line to the .htaccess if the private file access method is selected? It creates that file anyway and I can't think of any disadvantages of that setting.

Another way of achieving better access control for uploaded files would be to store them not in the file system but in the database. There a quite a few modules providing upload functionality, but I couldn't find any kind of "database document management" module. Any suggestions?

Your posting inspired me to try a few tests and - yes! - it IS trivial to get the contents of any file in the public_html directory of the other users on my shared hosts with a simple php script. This made me aware of another problem: the sites/*/settings.php can be easily viewed by other users as long as the webserver user can access it. Alas!, this contains my DB access settings!

So now I was really concerned. I can prevent other users from browsing the directories by setting their permissions to 0701 (... --x), except /files which got 0733 (... -wx) (my user owns them). This is enough for the webserver user to still access the files. Still, j.Random.Hacker can access files directly with knowledge of full path+name.

So I implemented your cgiwrap suggestion, which works fine. Now I can give my files a 0600 permission, at the price of putting a higher load on the server (apache module vs. cgi). I haven't had any idea yet how to reduce that, e.g. wrapping only critical files (like the one containing passwords). I don't know if that even would prove advantageous, as the settings.php is probably included with every Drupal page, that means the overhead of starting the suid-cgi exists anyway. Still thinking ... :)

dman’s picture

All those steps make sense, good one.

I'm not sure what that .htaccess file does if not that - Drupal_Security_Do_Not_Remove_See May have been related to an 'execution vulnerability' mentioned on http://drupal.org/security

I really don't know what to do about the readable settings.conf problem - sounds like it could be a really bad problem from your neighbours! I hadn't probed that direction before. I did a proof-of-concept snoop once when I first set up with my ISP, then shrugged and forgot about those things.
I think this IS an issue, Can't see if it's noted anywhere.

'private' files path should have been placed OUTSIDE of the file system. See admin/settings and change the "File system path" to either /usr/you/private/files or ../private/files .
Although I hadn't read the fine print before (haven't configured private for Drupal), it makes sense when you look at it.
Problem solved. I think there are a few file manager modules that also attempt to help with this.

Please do not consider using the DB as a filestore. It can be done, I think there was a 4.6 module that did so, but it's a painfully bad idea for maintainence.
Can you imagine being asked to fix a website that didn't have any files ?

Good one for starting up cgiwrap if you are trying to be careful, but problems still exist.
The $db_connect_string (or wratever it's called) is globally available to all modules. ... I can now imagine a Drupal trojan :) Yowza.

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

pwolanin’s picture

One host I'm currently using uses phpsuexec to run PHP under each user's own UID. Here's a modestly informative forum exchange about how that relates to site/files security:

http://drupal.org/node/65737#comment-123975

As well as some others:
http://drupal.org/node/39887
http://drupal.org/node/51834
http://drupal.org/node/14339

---
Work: BioRAFT