I submitted the updates to the Trac site for vTiger as diff updates to the vtigercrm 5.2.1 code, which might be easier to use to update the code.
The current version of the vTiger Customer Portal (5.2.0) is susceptible to a brute force attack in that it doesn’t enforce strong passwords of Customer Portal users and that there is no Account Lockout feature when too many invalid login attempts are made on an account. In a previous post, I showed how you can enforce strong passwords in the Customer Portal.
In this post, I will demonstrate how you can implement Customer Portal User Account Lockout. This is very easy to do. There are only 2 changes that need to be made to implement this feature:
1.) Create a database field to record the number of failed login attempts that a portal user makes
2.) Update the SOAP function to authenticate a user
1.) First, create the new field. Login to vtigerCRM as admin. Go to Settings –> Module Manager. Click the edit button to the right of Contacts (it looks like a hammer). Click Layout Editor. In the Customer Portal Information block, add a new number field called “Number of Failed Attempts” (you can make it with a Length of 3 and 0 Decimal Places).
Now, you need to find out the name of the database field that you just created in the vtiger CRM Module Manager (I still haven’t found the most efficient way to do this, so just login to mysql (mysql -u username -D vtigercrm520 -p) and run this command: describe vtiger_contactscf;) For the sake of this example, we will use the field name of vtiger_contactscf.cf_674 (NOTE: Your field name might be different. Make sure to replace the cf_674 field in the code below with the new field that you created in your implementation of vtiger CRM). Once you have the name of the new field, we can implement the change in the SOAP interface.
2.) Make the changes to vtigercrm/soap/customerportal.php. These 3 changes need to be made to the authenticate_user function:
a.) On line 966, update the $sql query:
$sql = “select id, user_name, user_password,last_login_time, support_start_date, support_end_date, COALESCE(vtiger_contactscf.cf_674,0) as failed_attempts from vtiger_portalinfo inner join vtiger_customerdetails on vtiger_portalinfo.id=vtiger_customerdetails.customerid inner join vtiger_crmentity on vtiger_crmentity.crmid=vtiger_portalinfo.id inner join vtiger_contactscf on vtiger_portalinfo.id=vtiger_contactscf.contactid where vtiger_crmentity.deleted=0 and user_name=? and user_password = ? and isactive=1 and vtiger_customerdetails.portal=1 and vtiger_customerdetails.support_end_date >= ?”;
b.) On line 974, update the elsif:
elseif($num_rows <= 0)
{
// Increment number of failed attempts
if ($login == ‘true’) {
$sql = “update vtiger_contactscf inner join vtiger_portalinfo on vtiger_contactscf.contactid=vtiger_portalinfo.id set cf_674=COALESCE(vtiger_contactscf.cf_674,0)+1 where user_name=?”;
$adb->pquery($sql, array($username));
}
return $err[1];//No user
}
else {
$failed_login_attempts = $adb->query_result($result,0,’failed_attempts’);
if ($failed_login_attempts >= 5)
{
return $err[1];
}
}
c.) Just before the function return, add this code:
// If authentication is sucessful, reset number of failed attempts
$sql = “update vtiger_contactscf set cf_674=0 where contactid = ?”;
$adb->pquery($sql, array($customerid));
That’s it! You now have Account Lockout enabled to Customer Portal user accounts. After 5 failed login attempts, someone with access to the vtiger CRM system will need to reset the “Number of Failed Attempts” value in the Contact’s record back to a lower number than 5 for the user to be able to login to the Customer Portal again.