Drupal 5.x and 6.x Core Contact Form XSS Vulnerability
Description of Vulnerability:
Drupal (http://drupal.org) is a robust content management system (CMS) written in PHP and MySQL that provides extensibility through various third party modules. The Contact module "enables the use of both personal and site-wide contact forms." The Contact module is one of the Drupal core modules, distributed with every Drupal site, but not enabled by default.
Systems affected:
Drupal 6.14 and 5.20 were tested and shown to be vulnerable.
Impact:
Cross site scripting (XSS) vulnerabilities may expose site administrative accounts to compromise which could lead to web server process compromise.
Mitigating factors:
To carry out the XSS exploit below the attacker must have 'administer site-wide contact form' permissions.
Proof of Concept:
- Install Drupal 6.14 and enable the Contact module from Administer -> Modules
- Click Administer -> Site building -> Contact form
- Click 'Add category'
- Enter "<script>alert('xss');</script>" in the 'Category' text area
- Enter arbitrary recipients and click the 'Save' button
- Observe the rendered JavaScript at ?q=admin/build/contact
Technical details:
The Contact module fails to sanitize the output of the contact category names before display. Applying the following patch fixes this vulnerability.
Patch
Applying the following patch mitigates these threats in Drupal 6.14.
--- drupal-6.14/modules/contact/contact.admin.inc 2007-11-09 02:55:13.000000000 -0500 +++ drupal-6.14/modules/contact/contact.admin.inc 2009-11-11 15:53:55.684432827 -0500 @@ -13,7 +13,7 @@ function contact_admin_categories() { $result = db_query('SELECT cid, category, recipients, selected FROM {contact} ORDER BY weight, category'); $rows = array(); while ($category = db_fetch_object($result)) { - $rows[] = array($category->category, $category->recipients, ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/build/contact/edit/'. $category->cid), l(t('delete'), 'admin/build/contact/delete/'. $category->cid)); + $rows[] = array(filter_xss($category->category), $category->recipients, ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/build/contact/edit/'. $category->cid), l(t('delete'), 'admin/build/contact/delete/'. $category->cid)); } $header = array(t('Category'), t('Recipients'), t('Selected'), array('data' => t('Operations'), 'colspan' => 2));
Applying the following patch mitigates these threats in Drupal 5.20
--- drupal-5.20/modules/contact/contact.module 2008-09-15 02:19:06.000000000 -0400 +++ drupal-5.20/modules/contact/contact.module 2009-11-11 15:55:33.252401609 -0500 @@ -145,7 +145,7 @@ function contact_admin_categories() { $result = db_query('SELECT cid, category, recipients, selected FROM {contact} ORDER BY weight, category'); $rows = array(); while ($category = db_fetch_object($result)) { - $rows[] = array($category->category, $category->recipients, ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/build/contact/edit/'. $category->cid), l(t('delete'), 'admin/build/contact/delete/'. $category->cid)); + $rows[] = array(filter_xss($category->category), $category->recipients, ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/build/contact/edit/'. $category->cid), l(t('delete'), 'admin/build/contact/delete/'. $category->cid)); } $header = array(t('Category'), t('Recipients'), t('Selected'), array('data' => t('Operations'), 'colspan' => 2));