The methods used by the Joomla core to validate tokens generated by a password reset request are a weak spot in the security of the system when coupled with the introduction of insecure third party components. A fundamental change in this handling could assist in hardening a typical Joomla web site. I am proposing an added security measure to the Joomla core in order to mitigate possible intrusion due to vulnerabilities in third party components.
Currently, Joomla will generate a reset token for any user found to have an email address submitted to the reset form and store it in the #__users database. When a token is submitted, the submission is checked against the stored value based upon string equality. In other words, the token to reset an account is stored in plaintext in the database.
If this information is coupled with an SQL injection vulnerability introduced by a third party script, it would be trivial for an attacker to take control of an administrative account on the victim's site. The process would go as follows:
- exploit vulnerable extension and extract the username and email of a Super Administrator
- submit the reset form on the victim site using the extracted email, generating a token
- exploit vulnerable extension again, extracting the token
- submit extracted token to the token validation form
- change the password of Super Administrator
Thus any vulnerable extension could lead to compromise.
It is my contention that the Joomla core should be altered such that the activation code is not directly stored in the database. Instead, I propose storing some sort of checksum salted with the site secret stored in configuration.php. During the token check, the submitted token can then be verified against what is stored in the database without a direct string comparison.
Granted, an insecure extension that allows arbitrary data to be extracted from the database is the true security flaw, but if such a system were implemented, it would make this type of attack more difficult.
Posted on the Joomla forums.
UPDATE: Joomla! 1.5.16 now hashes the reset token, so this is no longer an issue with up-to-date installs.