One of the most important security vulnerabilities in Drupal involves correctly configuring input formats. This blog post gives an overview of some of the issues involved and how to properly secure your site's input formats.
Here's how the problem typically starts. A Drupal site is built, and the standard input formats (Filtered HTML and Full HTML) are left with their default settings. The developer installs and configures a WYSIWYG editor and assigns it, for convenience, to the Full HTML format.
Another user comes along and begins entering content to the site, and of course, they must use the WYSIWYG editor all the time. Now, because "Filtered HTML" is set as the default input format, they have to click "Full HTML" each time to get the WYSIWYG editor to show up. This becomes annoying or tedious to them, so they hunt around for the configuration settings for input formats and decide to set "Full HTML" as the default input format.
This works great for that user - and for any attacker who wants to gain access to the site through a cross-site scripting (XSS) attack. Because seeing is believing, take two minutes to watch this video from Cracking Drupal where an XSS exploit is demonstrated.
Pretty bad, right? Here's how you can avoid having that problem happen to you.
What are input formats?
Let's start at the beginning by looking at what exactly is going on when you define input formats. The following text is from the input formats configuration page (admin/settings/formats), and please read it carefully because we'll contrast it later with what goes on in Drupal 7:
“ Input formats define a way of processing user-supplied text in Drupal. Each input format uses filters to manipulate text, and most input formats apply several different filters to text, in a specific order. Each filter is designed to accomplish a specific purpose, and generally either removes elements from or adds elements to text before it is displayed. Users can choose between the available input formats when submitting content.
Use the list below to configure which input formats are available to which roles, as well as choose a default input format (used for imported content, for example). The default format is always available to users. All input formats are available to users in a role with the "administer filters" permission. ”
This definition is accurate and, if it was read carefully, the misconfiguration described above would not occur so frequently. The problem, however, is that many users don't read carefully and the security risks are not clear enough to the end user.
At the end of the day, this is a usability issue because (a) it's trivial to set the default format incorrectly, and (b) it's easy for the administrator to inadvertently grant permissions to roles they did not intend.
Securing your input formats
Unfortunately, there is no red flag in Drupal 6 to warn you about this problem. But, it is not terribly difficult to secure your formats either.
At DesignHammer, we take the following steps in configuring the input formats:
- Correctly configure your permissions. Make sure the "administer formats" permission is assigned only to the most trusted users of your site. Make sure only trusted roles have access to full HTML input formats.
- Ensure that the default input format is set to Filtered HTML, or even better, create a new input format for "Plain text" and assign that as the default. Full HTML should never be set as the default input format because "the default format is always available to users". That means any authenticated user who has permission to create a node, or any anonymous user who has the ability to post comments. If they have the ability to enter unfiltered text or code, then you open your site up to all kinds of vulnerabilities.
- Use the Better Formats module to avoid the scenario described at the beginning of this post.
When you pick your default input format, make sure that "HTML Corrector" and "HTML Filter" are selected.
Then, when you configure your input format (admin/settings/filters/1/configure), think carefully about what you enter in the Allowed HTML tags section, and make sure that "Strip disallowed tags" is selected.
Input formats in Drupal 7
Input formats are handled in a much more secure and usable way in Drupal 7. Here is the text describing formats on the configuration page:
“ Text formats define the HTML tags, code, and other formatting that can be used when entering text. Improper text format configuration is a security risk. Learn more on the Filter module help page. Text formats are presented on content editing pages in the order defined on this page. The first format available to a user will be selected by default. ”
Note the explicit emphasis on security risk, unlike in D6. More importantly, Drupal 7 makes it more difficult for the site administrator to mess up. By default, Drupal 7 provides Filtered HTML, Full HTML, and Plain text input formats. Plain text is set as the format accessible to all user roles, while Full HTML is set to administrator only. Furthermore, there is no longer a "default" input format. Rather, the administrator has to grant access to a format per user role. This will force the administrator to click "anonymous user" on the Full HTML format settings and hopefully this will trigger a thought process that leads the admin to change their mind.
Unfortunately, it's still possible to set up input formats in an insecure way without getting warnings, but at least it is a bit more difficult to do.
There should be a module for that
Back to Drupal 6: we need to make it clearer to site administrators when they are making decisions that open up their sites to attacks. One way would be to provide some warnings in the admin interface when changes are made to input formats. I'm not aware of any modules that do this currently, but the way I would approach the problem is to implement a
hook_requirements() to do the following:
- Check if Full HTML is set as the default format, and if so, present a warning on the Status report page for your site. Of course, that assumes that the site administrator pays attention to the Status report page, which is often not the case.
- Search through all defined input formats and check the configuration to highlight which ones present security problems for your site.
At the end of the day, the vulnerability centers around permissions issues and understanding access control. Because Drupal is relatively easy to use, it also becomes easy to misconfigure a site and open it up to all kinds of vulnerabilities. Hopefully this explanation makes the issues around input formats a bit clearer and will help you secure your own site.