Drupal String Overrides Module XSS

1 December 2011

Reported to Vendor: March 16, 2011 15:25 EST

Description of Vulnerability:

Drupal (http://drupal.org) is a robust content management system (CMS) written in PHP and MySQL. The Drupal String Overrides module (http://drupal.org/project/stringoverrides) "Provides a quick and easy way to replace any text on the site." The module is intended as a lightweight translation module. Unfortunately the String Overrides module contains functionality that allows users to inject arbitrary code into translations of terms that are not sanitized by other modules (including Drupal core).

Systems affected:

Drupal 6.20 with String Overrides 6.x-1.8 and Drupal 5.21 with String Overrides 5.x-1.8 were tested and shown to be vulnerable. Drupal 7.0 with String Overrides 7.x-1.0 was tested and not found to be vulnerable. The demonstrated attack vector may affect other modules that trust input from translation files.

Impact

Malicious users could inject arbitrary scripts into pages affecting site administrators. This could result in administrative account compromise leading to web server process compromise. An attacker could also inject hidden content (such as iframes, applets, or embedded objects) that would attack client browsers in an attempt to compromise site users' machines. This vulnerability could also be used to launch cross site request forgery (XSRF) attacks against the site that could have other unexpected consequences.

Mitigating factors:

In order to exploit this vulnerability the attacker must have credentials to an authorized account that has been assigned the 'administer string overrides' permission. This could be accomplished via social engineering, brute force password guessing, or abuse or legitimate credentials.

Proof of Concept:

  1. Install Drupal and enable the String Overrides module
  2. Navigate to the 'String Overrides' page at ?q=admin/settings/stringoverrides
  3. Enter a new value with the Original set to "Optional" and the Replacement set to "Optional<script>alert('xss');</script>"
  4. Click the 'Save configuration' button
  5. View rendered JavaScript at the Page content type management screen ?q=admin/content/node-type/page

There are a number of other strings that are vulnerable to this type of injection at various locations throughout the Drupal administrative interface. This attack can also be accomplished by importing a malicious language file at ?q=admin/settings/stringoverrides/import

Patch:

The Drupal core Translation module will fail to import language files (.po or .pot) if illegal HTML characters are contained within them. It is reasonable to strip HTML out of imported translation strings. The following patch accomplishes this functionality in Drupal 6:

--- stringoverrides/stringoverrides.admin.inc	2010-08-22 16:36:43.000000000 -0400
+++ stringoverrides/stringoverrides.admin.inc	2011-03-16 15:17:11.502256648 -0400
@@ -87,7 +87,7 @@ function stringoverrides_admin_submit($f
     if (!empty($string['original'])) {
       // Get rid of carriage returns.
       list($orig, $replace) = str_replace("\r", '', array($string['original'], $string['replacement']));
-      $words[$string['enabled']][$orig] = $replace;
+      $words[$string['enabled']][$orig] = filter_xss($replace);
     }
   }
 
@@ -296,7 +296,7 @@ function stringoverrides_admin_import_su
       // Clean up and save the imported data
       fclose($handle);
       file_delete($file->filepath);
-      variable_set('locale_custom_strings_'. $form_state['values']['lang'], $overrides);
+      variable_set('locale_custom_strings_'. $form_state['values']['lang'], array_map('filter_xss',$overrides));
       drupal_set_message(t('The overrides have been imported.'));
     }
   }

Vendor Response

Vendor intends to release a public service announcement (https://drupal.org/security/psa).