(This is a public service announcement related to security functionality. It does not detail an exploitable vulnerability. Rather, we wish to advise administrators and developers about an on-going change to improve security.)
CiviCRM v3.1 introduced a helper "CRM_Utils_Crypt" which encrypted the SMTP password. This mechanism is being phased-out circa 5.34 in favor of a more secure mechanism. We will briefly consider the purpose of the mechanism, some of its issues, and the details of the change.
Purpose: Storing the SMTP password in encrypted format provides defense-in-depth. It is not a primary defense - it is a secondary defense that gives extra protection in cases where another vulnerability exists.
In regular usage, administrators are the only parties who can access the SMTP password. But suppose an attacker gains read access to the database (by way of SQL injection or leaked SQL backup) - then they can extract the SMTP password and access your email system. Of course, the premise itself is problematic - it would mean that the attacker has compromised the confidentiality of the database. But getting the password makes it worse: they also compromise the integrity of the email system. For the hypothetical victim, this increases the scope and difficulty of incident-response.
Encrypting the SMTP password does not prevent the original compromise, but it helps to limit the damage.
Issues: There have been multiple issues with "CRM_Utils_Crypt". Here are a few:
- It uses an old crypto library ("mcrypt") that is deprecated and not provided on many PHP deployments.
- When you make unrelated configuration changes in PHP (e.g. upgrading or downgrading the PHP version), you may inadvertently lose access to the SMTP password.
- It uses ill-advised cryptographic parameters which are only effective when handling a very small amount of data. Consequently, it is not appropriate to use it for anything besides a short/mid-size SMTP password.
- It uses ill-advised cryptographic parameters which make it difficult to substitute the crypto library with a newer, supported library.
- The secret is repurposed from another subsystem (REST API). In some organizations, REST API access is shared with staff users. Consequently, the secret may not be a well-kept secret.
- It is difficult to provide an automatic or drop-in fix for "CRM_Utils_Crypt".
- "CRM_Utils_Crypt" only provides a secondary defense.
- In the broader PHP ecosystem, many applications do not provide this extra level of protection for "SMTP password".
Changes: CiviCRM v5.34+ replaces "CRM_Utils_Crypt" with better services. There are new APIs for developers who wish to securely store credentials, and there is a new setting for administrators ("CIVICRM_CRED_KEYS") which specifically addresses encryption. The data format is less brittle, and (going forward) cryptographic parameters may be transitioned incrementally. The upgrader facilitates this migration, removing the old crypto system and enabling the new crypto system.
However, as a replacement, it could potentially disrupt customizations which directly use "CRM_Utils_Crypt" or the SMTP password.
For CiviCRM v5.33 ESR, this poses a conceptual challenge. On one hand, an administrator may be drawn to ESR because they put on a premium on stability and change-minimization -- if they believe encryption is an optional/secondary defense, then this change is unnecessary and should be omitted from ESR. On the other hand, another administrator may be drawn to ESR because they put a premium on security -- if they believe that every defensive layer is important, then this change should be included. As a compromise, v5.33.4 ESR includes a passive backport. A simple upgrade will leave you running "CRM_Utils_Crypt"; however, with some extra steps (post-upgrade), the system administrator may optionally migrate to the new format.
Tim Otten of CiviCRM Core Team and Cure53/Mozilla Open Source Support (MOSS) for independently identifying the issue
Tim Otten of CiviCRM Core Team and Seamus Lee of JMA Consulting, Mikey O'Toole of MJCO, Justin Freeman of Agileware for fixing the issue
Deutsche Gesellschaft für Internationale Zusammenarbeit (GIZ) GmbH for funding the fix in 5.34+