Drupal Security for Coders and Themers


Use These Resources

  • drupalsecurityreport.org - full white paper that discusses security for Drupal; a good resource if you are a project manager
  • drupal.org/writing-secure-code
  • drupal.org/security/secure-configuration
  • crackingdrupal.com - great book, by greggles, webchick says its the first book about drupal that she's going to buy
  • drupal.org/project/coder - does static analysis of your code and can show you problems like SQL injection, but it doesn't catch everything.
  • drupal.org/project/security_review - dynamic analysis; newer tool.

Cenzic Web Application Security Trends Report

Reported vulnerabilities have seen XSS and SQL injection grow to comprise almost 50% of all vulnerabilities. In Drupal's case, XSS is by far the most common vulnerability; SQL injection is a tiny sliver, due to Drupal's database layer. When we are analyzing problems, XSS is the largest vulnerability. If you're a Drupal developer or themer, XSS is the vulnerability that you should be most concerned about.

Keep Up To Date

  • Make sure Update module is enabled
  • Fill out your email address to notify you of available updates on a Daily basis, but only security updates.
  • In your d.o prrofile, subscribe to Security Advisory emails
  • Have a consistent method for updating your site, such as a VCS or drush, and don't put it off!

Don't Use Insecure Tools

  • No: FTP, Telnet, http
  • Avoid using Total Commander at all costs
  • Yes: SSH/sFTP, FTPS, https
  • Secure Pages allows you to set up https for admin users only
  • Is your server updated with security fixes for PHP, Apache, MySQL, etc?

XSS: User Input is Dangerous

  • Where does this text come from? If it's from the user, never trust it.
  • Is there a way a user can change it?
  • What context is it being used?
    • Web context
    • Mail context
    • Database (SQL) context
    • File system context
    • Shell exec context
  • http://acko.net/blog/safe-string-theory-for-the-web

Your default input format MUST be filtered

Although it may be annoying to set the filter to full HTML when creating content all the time, the default input format can be accessed by anybody using your site. Even if you change it back later, any comments posted when Full HTML was your default input format will still be set to Full HTML. Keep the default input format as filtered, and use the better formats module.


The message is that, if you can do it manually, XSS can do it much better. During the demo, the speakers demoed a site with comments enabled, which has Full HTML as the default input format. The comment was queued and went into the approval queue. When the administrator viewed the comment, the jQuery in the comment submitted a form to change the administrator's email address.

Custom Theme = Big Risk!

When some big sites have had vulnerability analyses done on their code, something like 90% of the XSS vulnerabilities were found in the custom theme. For example,


could even cause problems, since you're not using check_plain(). If you're pulling something out of the node object itself, that is unsafe user input that you're dealing with and you have to use check_plain() to excape any of the tags in this title. If you're a module developer, you should provide preprocess functions that takes any unsafe data and makes it safe; any templates that your module provides variables to should already be safe.

Theme functions are a little harder; in Drupal 7, even theme functions in general should be getting safe data to manipulate. In Drupal 6, it's generally better to use template files, so that you can preprocess.

XSRF: Cross site request forgery

  • An action is taken without confirmation
  • Can run via IMG tags
  • Can run via JS on a 3rd party site: If JavaScript makes a web request, it is running in your browser so it appears to come from you.
  • Both GET and POST are vulnerable: Drupal protects from this by using tokens. Any JavaScript coming from a 3rd party site will not be able to get access to this token.
  • Form tokens or URL tokens tied to your session protect you

Severities and Other Vulnerabilities

  • http://drupal.org/security/contrib has examples of a lot of other categories of vulnerabilities in addition to XSS and CSRF.
  • http://drupal.org/security-team/risk-levels also mentions some of them as examples. When we publish a security advisory we try to give some idea of how "bad" this is. Is every site in serious trouble, or can only certain privileged users carry out the attack?

Arbitrary Code Execution

  • This usually means some site user may be able to run PHP commands, or PHP in a file (maybe a log file) may be included and executed.
  • This may be the worst vulnerability of all; luckily we don't see it very often.
  • The most obvious is allowing users to use the PHP input format.
  • Recent examples include uses of preg_replace() where the result of a regular expression match could be executed as PHP (using the /e flag, which means "evaluate the pattern as code.") If you need to do this, use preg_replace_callback().

SQL Injection

  • If you use Drupal's API correctly, it's relatively invulnerable to this.
  • User input is added directly to the SQL sent to the database.
  • In some cases this can allow users to delete for alter anything in the database.
  • In other cases, it can reveal private information in the database - such as email addresses, hashed passwords, etc, which are used as the basis for further attack.

Access Bypass

  • Information Disclosure: content is supposed to be protected, but it is not.
  • Authentication Bypass: normal users can access an administrative page or operation. We'll see this when someone write a hook_menu implementation and don't get the access_check correct, and anonymous users can access the page and change the administrative settings for that module. There are plenty of cases of this, it has happened a number of times.

Directory Traversal

  • The contents of a file chosen by the attacker can be included into the output.
  • When filenames are taken from the URL or other user input and characters like / or \ are not correctly escaped.
  • This can reveal sensitive server information, for example your Drupal database credentials
  • Arbitrary code execution is the greatest danger.

Why worry if someone can execute code on my own server? In some cases, the file included may be the log file. Someone can access a bogus URL that gets recorded to the apache log file as a 404 error. If that URL can "execute" the log file and the bogus URL contains some PHP code, then an arbitrary code execution event has occurred.

SQL Injection + Access Bypass

db_query_range('SELECT * FROM {node} n WHERE n.uid = ' . arg(1), 0, 10);

... should be fixed as:

db_query_range(db_rewrite_sql('SELECT * FROM {node} n WHERE n.uid = %f'), arg(1), 0, 10);

This prevents SQL injection and access bypass vulnerabilities. However, if the site is running a node access module, that will not be respected by the first query. db_rewrite_sql() will expand your query to fix the node access issues, which fixes the access bypass.

Did you enjoy this post? Please spread the word.