Critical severityOSV Advisory· Published Apr 17, 2019· Updated Aug 4, 2024
CVE-2019-10641
CVE-2019-10641
Description
Contao before 3.5.39 and 4.x before 4.7.3 has a Weak Password Recovery Mechanism for a Forgotten Password.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
contao/contaoPackagist | >= 4.0.0, < 4.4.37 | 4.4.37 |
contao/contaoPackagist | >= 4.5.0, < 4.7.3 | 4.7.3 |
contao/core-bundlePackagist | >= 4.0.0, < 4.4.37 | 4.4.37 |
contao/core-bundlePackagist | >= 4.5.0, < 4.7.3 | 4.7.3 |
contao/corePackagist | >= 3.0.0, < 3.5.39 | 3.5.39 |
Affected products
1Patches
3119a1b5bd9e6Invalidate the user sessions if a password changes (see CVE-2019-10641)
5 files changed · +43 −0
system/docs/CHANGELOG.md+7 −0 modified@@ -1,6 +1,13 @@ Contao Open Source CMS changelog ================================ +Version 3.5.39 (2019-04-XX) +--------------------------- + +### Fixed +Invalidate the user sessions if a password changes (see CVE-2019-10641). + + Version 3.5.38 (2018-12-21) ---------------------------
system/modules/core/dca/tl_member.php+4 −0 modified@@ -608,6 +608,10 @@ public function setNewPassword($strPassword, $user) } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($user->id, session_id()); + return $strPassword; }
system/modules/core/dca/tl_user.php+24 −0 modified@@ -242,6 +242,10 @@ 'exclude' => true, 'inputType' => 'password', 'eval' => array('mandatory'=>true, 'preserveTags'=>true, 'minlength'=>Config::get('minPasswordLength')), + 'save_callback' => array + ( + array('tl_user', 'invalidateSessions') + ), 'sql' => "varchar(128) NOT NULL default ''" ), 'pwChange' => array @@ -732,6 +736,26 @@ public function checkAdminStatus($varValue, DataContainer $dc) } + /** + * Invalidate the user sessions if the password changes + * + * The password widget only triggers the save_callback if the password has actually + * changed, therefore we do not need to check the active record here. + * + * @param mixed $varValue + * @param DataContainer $dc + * + * @return mixed + */ + public function invalidateSessions($varValue, DataContainer $dc) + { + $this->Database->prepare("DELETE FROM tl_session WHERE name='BE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($dc->id, session_id()); + + return $varValue; + } + + /** * Prevent administrators from disabling their own account *
system/modules/core/modules/ModuleChangePassword.php+4 −0 modified@@ -186,6 +186,10 @@ protected function compile() } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($objMember->id, session_id()); + // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) !== null) {
system/modules/core/modules/ModulePassword.php+4 −0 modified@@ -254,6 +254,10 @@ protected function setNewPassword() } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($objMember->id, session_id()); + // Redirect to the jumpTo page if (($objTarget = $this->objModel->getRelated('reg_jumpTo')) !== null) {
b92e27bc7c9eInvalidate the user sessions if a password changes (see CVE-2019-10641)
4 files changed · +59 −10
CHANGELOG.md+1 −0 modified@@ -2,6 +2,7 @@ ## DEV + * Invalidate the user sessions if a password changes (see CVE-2019-10641). * Correctly check if a file or folder is excluded from synchronization (see 410). ## 4.7.2 (2019-03-25)
core-bundle/src/Resources/contao/dca/tl_user.php+16 −1 modified@@ -24,7 +24,8 @@ ), 'onsubmit_callback' => array ( - array('tl_user', 'storeDateAdded') + array('tl_user', 'storeDateAdded'), + array('tl_user', 'updateCurrentUser') ), 'sql' => array ( @@ -871,6 +872,20 @@ public function storeDateAdded(Contao\DataContainer $dc) ->execute($time, $dc->id); } + /** + * Update the current user if something changes, otherwise they would be + * logged out automatically + * + * @param Contao\DataContainer $dc + */ + public function updateCurrentUser(Contao\DataContainer $dc) + { + if ($this->User->id == $dc->id) + { + $this->User->findBy('id', $this->User->id); + } + } + /** * Return the "toggle visibility" button *
core-bundle/src/Resources/contao/library/Contao/User.php+39 −9 modified@@ -425,7 +425,7 @@ public function isMemberOf($id) return false; } - $groups = StringUtil::deserialize($this->arrData['groups']); + $groups = StringUtil::deserialize($this->groups); // No groups assigned if (empty($groups) || !\is_array($groups)) @@ -519,15 +519,15 @@ public static function loadUserByUsername($username) */ public function getUsername() { - return $this->arrData['username']; + return $this->username; } /** * {@inheritdoc} */ public function setUsername($username) { - $this->arrData['username'] = $username; + $this->username = $username; return $this; } @@ -537,15 +537,15 @@ public function setUsername($username) */ public function getPassword() { - return $this->arrData['password']; + return $this->password; } /** * {@inheritdoc} */ public function setPassword($password) { - $this->arrData['password'] = $password; + $this->password = $password; return $this; } @@ -573,15 +573,33 @@ public function setSalt($salt) */ public function serialize() { - return serialize(array($this->id, $this->username, $this->disable, $this->admin, $this->groups)); + $data = array + ( + 'id' => $this->id, + 'username' => $this->username, + 'password' => $this->password, + 'admin' => $this->admin, + 'disable' => $this->disable, + 'start' => $this->start, + 'stop' => $this->stop + ); + + return serialize($data); } /** * {@inheritdoc} */ public function unserialize($serialized) { - list($this->id, $this->username, $this->disable, $this->admin, $this->groups) = unserialize($serialized, array('allowed_classes'=>false)); + $data = unserialize($serialized, array('allowed_classes'=>false)); + + if (array_keys($data) != array('id', 'username', 'password', 'admin', 'disable', 'start', 'stop')) + { + return; + } + + list($this->id, $this->username, $this->password, $this->admin, $this->disable, $this->start, $this->stop) = array_values($data); } /** @@ -604,12 +622,12 @@ public function isEqualTo(UserInterface $user) return false; } - if ((bool) $this->admin !== (bool) $user->admin) + if ($this->password !== $user->password) { return false; } - if ($this->groups !== $user->groups) + if ((bool) $this->admin !== (bool) $user->admin) { return false; } @@ -619,6 +637,18 @@ public function isEqualTo(UserInterface $user) return false; } + $time = Date::floorToMinute(); + + if ($this->start !== '' && $this->start > $time) + { + return false; + } + + if ($this->stop !== '' && $this->stop <= ($time + 60)) + { + return false; + } + return true; }
core-bundle/src/Resources/contao/modules/ModuleChangePassword.php+3 −0 modified@@ -185,6 +185,9 @@ protected function compile() } } + // Update the current user so they are not logged out automatically + $this->User->findBy('id', $objMember->id); + // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
74c7dfafa0dfInvalidate the user sessions if a password changes (see CVE-2019-10641)
5 files changed · +39 −0
CHANGELOG.md+4 −0 modified@@ -1,5 +1,9 @@ # Change log +## DEV + + * Invalidate the user sessions if a password changes (see CVE-2019-10641). + ## 4.4.36 (2019-03-25) * Make custom layout section titles and IDs mandatory (see #341).
core-bundle/src/Resources/contao/dca/tl_member.php+4 −0 modified@@ -607,6 +607,10 @@ public function setNewPassword($strPassword, $user) } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($user->id, session_id()); + return $strPassword; }
core-bundle/src/Resources/contao/dca/tl_user.php+23 −0 modified@@ -254,6 +254,10 @@ 'exclude' => true, 'inputType' => 'password', 'eval' => array('mandatory'=>true, 'preserveTags'=>true, 'minlength'=>Config::get('minPasswordLength')), + 'save_callback' => array + ( + array('tl_user', 'invalidateSessions') + ), 'sql' => "varchar(255) NOT NULL default ''" ), 'pwChange' => array @@ -742,6 +746,25 @@ public function getModules() return $arrModules; } + /** + * Invalidate the user sessions if the password changes + * + * The password widget only triggers the save_callback if the password has actually + * changed, therefore we do not need to check the active record here. + * + * @param mixed $varValue + * @param DataContainer $dc + * + * @return mixed + */ + public function invalidateSessions($varValue, DataContainer $dc) + { + $this->Database->prepare("DELETE FROM tl_session WHERE name='BE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($dc->id, session_id()); + + return $varValue; + } + /** * Prevent administrators from downgrading their own account *
core-bundle/src/Resources/contao/modules/ModuleChangePassword.php+4 −0 modified@@ -187,6 +187,10 @@ protected function compile() } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($objMember->id, session_id()); + // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
core-bundle/src/Resources/contao/modules/ModulePassword.php+4 −0 modified@@ -254,6 +254,10 @@ protected function setNewPassword() } } + // Invalidate the user sessions if the password changes + $this->Database->prepare("DELETE FROM tl_session WHERE name='FE_USER_AUTH' AND pid=? AND sessionID!=?") + ->execute($objMember->id, session_id()); + // Redirect to the jumpTo page if (($objTarget = $this->objModel->getRelated('reg_jumpTo')) instanceof PageModel) {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-vcgg-hp4r-87gxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-10641ghsaADVISORY
- contao.org/en/news.htmlmitrex_refsource_CONFIRM
- contao.org/en/news/security-vulnerability-cve-2019-10641.htmlghsax_refsource_CONFIRMWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/contao/contao/CVE-2019-10641.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/contao/core-bundle/CVE-2019-10641.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/contao/core/CVE-2019-10641.yamlghsaWEB
- github.com/contao/contao/commit/74c7dfafa0dfa5363a9463b486522d5d526e28feghsaWEB
- github.com/contao/contao/commit/b92e27bc7c9e59226077937f840c74ffd0f672e8ghsaWEB
- github.com/contao/core/commit/119a1b5bd9e62d27ca2838727084d04f3b7fcd32ghsaWEB
News mentions
0No linked articles in our index yet.