Drupal's biggest strengths — ease of customization and flexible architecture — are also its main weaknesses... The easier it gets to get up a powerful, custom-made Drupal site up and running, with just some tweaking and modules mixing and matching, the higher are the chances that you mess up key configuration settings. And that you expose priceless private data all over the internet. So, the question that arises now is: how to secure private files in Drupal?
How do you set up a private file system? And how do you properly and safely configure your private Drupal files permissions?
There are a couple of tweaks that you can do for strategically structuring your file system and thus preventing the exposure of your Drupal private files to the internet.
So, let's just... expose these useful tweaks, shall we?
1. What Are "Private Files" in Drupal? Private vs Public Content
The “public vs private files” dichotomy is a universal one, irrespective of the platform that you've built your site/app on. Therefore, content served on your website can be either:
- public: served by the server directly and used mainly to provide information about your services and/or products; also, excepting the admins and content managers, it's the type of content that users don't need to log themselves in for accessing
- or private: it will have to pass through Drupal first, the one determining who's allowed to access it; needless to add that this “pre-validation” process will slow down things a bit
“When would I normally use private files more precisely?” “And is it possible to not even know that there are private files on my site and that I accidentally expose them online?”
Now let me answer your valid questions methodically:
a. The most common use cases for private files are web applications such as:
- online communities
- social intranets
- chat applications
It goes without saying that all these scenarios involve users uploading files (e.g. photos) that shouldn't be visible to just anyone without logging in. So, you'll need to structure your file system accordingly.
To these 3 most common use cases, feel free to add 2 more:
- newsletters that you want only site members to see
- files created by your site's Drupal modules themselves, that should be kept private (if not, they can easily turn into a potential security risk)
b. As for your concern on whether there could be private files on your site that you're not even aware of, my answer is: “Yes. Particularly if you're not familiar with the way some of the modules on your Drupal site work.”
In short: there might be modules, on your site, that are using private files, which makes it vital for you to identify them and to apply the due security on them.
2. Two Ways for Keeping Drupal Private Files... Private
And this is just a brief overview of the tweaks that you can do to secure private files in Drupal (we'll be getting “knee deep” into details in a bit).
The most important thing to keep in mind is that:
- public files should be placed where they belong to, in the public “web root” (so that your server can have direct access to them)
- private files should be placed outside the “web root” (for instance: under "sites/default/files/private"), so that they shouldn't be easily accessible to your server
Note: nevertheless, if you want them to keep them stored in there, you'll need to properly configure your web server so that it shouldn't access them and serve them. And this is where usually things risk turning bad...
3. Are Your Drupal Private Files Exposed? Check Your File System Settings
In order to fix that accidental exposure of your Drupal private files to the internet, you first need to find out whether you have, indeed, exposed them. And for this, you'll need to navigate through your file system's current settings.
Now, here's how to run your “investigations” in this respect:
- Log to your Admin Panel
- Go to Configuration -> Media -> File system
- Focus your attention on the "Private file system path"
- Next just enter a file (a “test.txt”, for example) at that given path (let's say: "sites/default/files/private") and try to access it from your web browser
Can you access it right away? Then it's a fact:
Your Drupal private files are not... private at all. They could be accessed by anyone online.
Note: If you're not comfortable with the idea of using SSH or FTP, then you could easily install the Security Review module and rely on its report instead. This will pinpoint all the private fields that got exposed, plus a bunch of other potential security issues that it will have detected. Pretty convenient, indeed!
And now that you know for sure that yes, your private files haven't been kept private, the next step is to configure the location of the uploaded files and to define the rules for accessing them.
Before we get into this, let's navigate some more through the file system's settings. Here's what you should be seeing if you're in the File system screen right now:
- Public file system path: this is the directory where your site's public files are saved
- Public file base URL: the URL placed before all public files
- Public file system path: the directory where your Drupal private files are saved; and, since you've already discovered that your private files have been exposed, it's obvious that this directory's not activated yet
- Default download method: the standard way to download files on your website
- Delete orphaned files after: the time before temporary files get removed
4. How to Secure Private Files in Drupal: Configure Private Files Directory
Now that we've explored your current system's settings — where your files are set on public — it's time to activate your private files to be saved by Drupal.
And here's the step-by-step guide for setting up your private file system- I'll assume that you've already gone through the Configuration -> Media -> File system steps already :
- Go to settings.php and configure your private files directory
- Select “../files” as your “Private files system path” and ensure that the directory's placed outside the webroot
- Next, when setting the Default download method, go with “Private local files saved by Drupal” instead of “Public local files saved by the server”
Voila! You've just set up a private file system on your Drupal site.
Now users who'll want to download a specific file or to have a look at an image, for instance, will do that by a Drupal system call and not right in their web browsers.
Upon that call, it's Drupal who'll decide whether the user has permission to access the specific file or not. It will be slower, no doubt about it, but safer.
A guarantee that all private files will be kept safe.
5. Set Up the Drupal Files Permissions Yourself
But what if, as you secure private files in Drupal, you decide to define the rules for accessing those files yourself? That instead of letting Drupal determine who is and who isn't allowed to download them.
What if there aren't suitable permissions for supporting particular scenarios — like those where you don't want users from group X to be able to access directly and to download group X's private files?
Then it's hook_file_download() that you can rely on for handling Drupal private files download permissions.
And here's how this function works:
- it checks who the user wanting to download the given private file is
- it checks whether he/she is a member of the group to which that particular file has been uploaded
- if he/she is, indeed, a member of that group, it's this code that will enable Drupal to load and return the file
- if Drupal determines that the user's not part of that group, it will just provide a “Not found” message, thus keeping the file “private” for visitors who're not granted access to it
6. Summing Up
The 3 main conclusions to draw from this mini-tutorial on how to set up private files in Drupal are the following:
- before anything, before you even “sketch” your online platform, app or website, decide whether it's a private or a public file system that you'll need
- this way, you'll be able to properly structure it, from the start, and thus to secure all private data; that instead of exposing it to the internet first and securing it afterward
- don't think that if you haven't set up a private file system in the first place, there will be no private files at all, used on your Drupal site; there might be modules that count on such type of files so, do keep that in mind, as well, and be ready to secure them