Drupal Biblio Module 6.x-1.6 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 Biblio module (http://drupal.org/project/biblio) "allows users manage and display lists of scholarly publications." The Biblio module creates customized views in order to display these listings.
The Biblio module contains a cross site scripting vulnerability because it does not properly sanitize output of titles before display.
Systems affected:
Drupal 6.13 with Biblio 6.x-1.6 was tested and shown to be vulnerable.
Impact:
XSS vulnerabilities may expose site administrative accounts to compromise which could lead to web server process compromise.
Mitigating factors:
The Biblio module must be installed. To carry out a Biblio based XSS exploit against the module the attacker must be able to inject malicious content into Biblio titles which requires the 'create biblio' permission.
Proof of Concept:
- Install Drupal 6.13
- Install Biblio 6.x-1.6
- Enable the Biblio module from Administer -> Site building -> Modules
- Click the Create content link
- Click Biblio
- Select 'Book' from the 'Publication Type' drop down
- Enter "
<script>alert('xss');</script>
" in the 'Title' field - Click the 'Save' button
- Browse to the site homepage and observe the JavaScript alert
Technical details:
The Biblio module fails to sanitize the output of the title of the Biblio on line 71 of biblio/biblio_style_cse.inc before display. This vulnerability is also present in other display files as detailed in the patch below. Applying the patch fixes this vulnerability.
Patch
Applying the following patch mitigates these threats.
diff -up biblio/biblio_style_apa.inc biblio_fixed/biblio_style_apa.inc - --- biblio/biblio_style_apa.inc 2009-06-18 16:41:47.000000000 -0400 +++ biblio_fixed/biblio_style_apa.inc 2009-08-18 09:03:14.836043896 -0400 @@ -79,7 +79,7 @@ function biblio_style_apa($node, $base = $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); //$output .= $inline ? l("$node->title", "$base/viewinline/$node->nid") : l("$node->title", "node/$node->nid"); $output .= ". </span> \n"; $output .= !empty ($node->biblio_contributors[2]) ? '(' . theme('biblio_authors', $node->biblio_contributors[2], 'apa', 2, $inline) . ', Ed.).' : ""; diff -up biblio/biblio_style_chicago.inc biblio_fixed/biblio_style_chicago.inc - --- biblio/biblio_style_chicago.inc 2009-07-29 14:11:33.000000000 -0400 +++ biblio_fixed/biblio_style_chicago.inc 2009-08-18 09:03:53.380044423 -0400 @@ -86,7 +86,7 @@ function biblio_style_chicago($node, $ba $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); //$output .= $inline ? l("$node->title", "$base/viewinline/$node->nid") : l("$node->title", "node/$node->nid"); if (!ereg("[?!.]$", $node->title)) $output .= "."; $output .= '"'; diff -up biblio/biblio_style_classic.inc biblio_fixed/biblio_style_classic.inc - --- biblio/biblio_style_classic.inc 2009-06-18 16:41:48.000000000 -0400 +++ biblio_fixed/biblio_style_classic.inc 2009-08-18 09:02:54.611150958 -0400 @@ -54,7 +54,7 @@ function biblio_style_classic($node, $ba $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); $output .= "</span>, \n"; $output .= '<span class="biblio-authors">' . $authors . "</span> \n"; if ($node->biblio_secondary_title) { diff -up biblio/biblio_style_cse.inc biblio_fixed/biblio_style_cse.inc - --- biblio/biblio_style_cse.inc 2009-06-18 16:41:48.000000000 -0400 +++ biblio_fixed/biblio_style_cse.inc 2009-08-18 09:02:09.807038112 -0400 @@ -68,7 +68,7 @@ function biblio_style_cse($node, $base = $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); $output .= (strpos($node->title, '?'))? " </span>" : ". </span>"; // if the title ends in a question mark, don't put a period after it. $output .= (!empty ($node->biblio_secondary_title)) ? check_plain($node->biblio_secondary_title) . '. ' : ''; $output .= (!empty ($node->biblio_volume)) ? check_plain($node->biblio_volume) : ''; diff -up biblio/biblio_style_ieee.inc biblio_fixed/biblio_style_ieee.inc - --- biblio/biblio_style_ieee.inc 2009-06-18 16:41:48.000000000 -0400 +++ biblio_fixed/biblio_style_ieee.inc 2009-08-18 09:02:51.649047645 -0400 @@ -61,7 +61,7 @@ function biblio_style_ieee($node, $base $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; if (!empty ($node->biblio_secondary_title)) { $output .= '<span class="biblio-title">"'; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); //$output .= $inline ? l("$node->title", "$base/viewinline/$node->nid") : l("$node->title", "node/$node->nid"); $output .= "", </span> \n"; $output .= '<i>' . check_plain($node->biblio_secondary_title) . '</i>'; diff -up biblio/biblio_style_mla.inc biblio_fixed/biblio_style_mla.inc - --- biblio/biblio_style_mla.inc 2009-07-29 14:11:33.000000000 -0400 +++ biblio_fixed/biblio_style_mla.inc 2009-08-18 09:04:11.180038853 -0400 @@ -80,7 +80,7 @@ function biblio_style_mla($node, $base = $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); //$output .= $inline ? l("$node->title", "$base/viewinline/$node->nid") : l("$node->title", "node/$node->nid"); if (!ereg("[?!.]$", $node->title)) $output .= "."; $output .= '"'; diff -up biblio/biblio_style_vancouver.inc biblio_fixed/biblio_style_vancouver.inc - --- biblio/biblio_style_vancouver.inc 2009-07-29 14:11:33.000000000 -0400 +++ biblio_fixed/biblio_style_vancouver.inc 2009-08-18 09:04:20.753048059 -0400 @@ -88,7 +88,7 @@ function biblio_style_vancouver($node, $ $link = ((variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? $node->biblio_url : ($inline ? "$base/viewinline/$node->nid":"node/$node->nid" ) ) ; $options['attributes'] = (variable_get('biblio_links_target_new_window',null) && variable_get('biblio_link_title_url', 0) && !empty($node->biblio_url)) ? array('target'=>'_blank') : null; $options['html'] = TRUE; - - $output .= l($node->title, $link, $options); + $output .= l(filter_xss($node->title, biblio_get_allowed_tags()), $link, $options); //$output .= $inline ? l("$node->title", "$base/viewinline/$node->nid") : l("$node->title", "node/$node->nid"); if (!ereg("[?!.]$", $node->title)) $output .= "."; }
Vendor Response
Upgrade to the latest version of the module. (SA-CONTRIB-2009-064)