TYPO3 Vulnerable to Unverified Password Change for Backend Users
Description
TYPO3 is an open source, PHP based web content management system. Starting in version 9.0.0 and prior to versions 9.5.51 ELTS, 10.4.50 ELTS, 11.5.44 ELTS, 12.4.31 LTS, and 13.4.12 LTS, the backend user management interface allows password changes without requiring the current password. When an administrator updates their own account or modifies other user accounts via the admin interface, the current password is not requested for verification. This behavior may lower the protection against unauthorized access in scenarios where an admin session is hijacked or left unattended, as it enables password changes without additional authentication. Users should update to TYPO3 version 9.5.51 ELTS, 10.4.50 ELTS, 11.5.44 ELTS, 12.4.31 LTS, or 13.4.12 LTS to fix the problem.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
An unverified password change vulnerability in TYPO3 backend allows password reset without current credential verification, enabling privilege escalation if an admin session is hijacked.
Vulnerability
Description
CVE-2025-47938 is a security misconfiguration in TYPO3 CMS that permits backend user password changes without requiring the current password. In affected versions (9.0.0 through 13.4.11), both the DataHandler component (ext:core) and the Setup module (ext:setup) allow administrators — when updating their own account or modifying other user accounts — to submit a new password without verifying their identity first [1][4]. The issue is tracked as CWE-620 (Unverified Password Change) [4].
Exploitation
The attack surface is limited to authenticated backend sessions, requiring an attacker to have already gained administrative access via session hijacking, an unattended session, or other means [1][4]. Because the interface does not request the current password, an attacker who controls an active admin session can immediately change the password for the admin account or any other backend user, locking out the legitimate owner [1][2].
Impact
This weakness significantly lowers the barrier for privilege escalation in scenarios where an admin session is compromised or left unattended [4]. An attacker who obtains temporary backend access can achieve persistent control by changing passwords, then maintaining access even after the original session expires [1].
Mitigation
The fix introduces step-up authentication (sudo mode) before password changes, implemented through an authentication context configuration in the TYPO3 TCA forms and corresponding logic in the Setup module [2][3]. Patched versions are 9.5.51 ELTS, 10.4.50 ELTS, 11.5.44 ELTS, 12.4.31 LTS, and 13.4.12 LTS [1][4]. The advisory notes that administrators using remote SSO may need to handle new PSR-14 events (SudoModeRequiredEvent and SudoModeVerifyEvent) to integrate step-up authentication [4].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
typo3/cms-corePackagist | >= 9.0.0, < 9.5.51 | 9.5.51 |
typo3/cms-setupPackagist | >= 9.0.0, < 9.5.51 | 9.5.51 |
typo3/cms-corePackagist | >= 10.0.0, < 10.4.50 | 10.4.50 |
typo3/cms-corePackagist | >= 11.0.0, < 11.5.44 | 11.5.44 |
typo3/cms-corePackagist | >= 12.0.0, < 12.4.31 | 12.4.31 |
typo3/cms-corePackagist | >= 13.0.0, < 13.4.12 | 13.4.12 |
typo3/cms-setupPackagist | >= 10.0.0, < 10.4.50 | 10.4.50 |
typo3/cms-setupPackagist | >= 11.0.0, < 11.5.44 | 11.5.44 |
typo3/cms-setupPackagist | >= 12.0.0, < 12.4.31 | 12.4.31 |
typo3/cms-setupPackagist | >= 13.0.0, < 13.4.12 | 13.4.12 |
Affected products
4- ghsa-coords2 versions
>= 9.0.0, < 9.5.51+ 1 more
- (no CPE)range: >= 9.0.0, < 9.5.51
- (no CPE)range: >= 9.0.0, < 9.5.51
Patches
2b9a8bcb614ec[SECURITY] Require step-up authentication for password change
7 files changed · +147 −1
Configuration/TCA/be_groups.php+42 −0 modified@@ -43,6 +43,9 @@ 'size' => 3, 'autoSizeMax' => 10, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'file_mountpoints' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:file_mountpoints', @@ -75,6 +78,9 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'file_permissions' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.fileoper_perms', @@ -105,6 +111,9 @@ 'maxitems' => 17, 'default' => 'readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'workspace_perms' => [ 'displayCond' => 'USER:TYPO3\CMS\Core\Hooks\TcaDisplayConditions->isExtensionInstalled:workspaces', @@ -118,6 +127,9 @@ ['label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:workspace_perms_live'], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'pagetypes_select' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.pagetypes_select', @@ -128,6 +140,9 @@ 'size' => 5, 'autoSizeMax' => 50, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'tables_modify' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.tables_modify', @@ -138,12 +153,18 @@ 'selectFieldName' => 'tables_select', 'itemsProcFunc' => \TYPO3\CMS\Core\Hooks\TcaItemsProcessorFunctions::class . '->populateAvailableTables', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'tables_select' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.tables_select', 'config' => [ 'type' => 'passthrough', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'non_exclude_fields' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.non_exclude_fields', @@ -155,6 +176,9 @@ 'size' => 25, 'autoSizeMax' => 50, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'explicit_allowdeny' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.explicit_allowdeny', @@ -163,6 +187,9 @@ 'renderType' => 'selectCheckBox', 'itemsProcFunc' => \TYPO3\CMS\Core\Hooks\TcaItemsProcessorFunctions::class . '->populateExplicitAuthValues', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'allowed_languages' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:allowed_languages', @@ -173,6 +200,9 @@ 'itemsProcFunc' => \TYPO3\CMS\Core\Localization\TcaSystemLanguageCollector::class . '->populateAvailableSiteLanguages', 'dbFieldLength' => 255, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'custom_options' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.custom_options', @@ -191,6 +221,9 @@ 'size' => 5, 'autoSizeMax' => 50, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'mfa_providers' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:mfa_providers', @@ -201,6 +234,9 @@ 'size' => 5, 'autoSizeMax' => 50, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'TSconfig' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:TSconfig', @@ -222,6 +258,9 @@ 'size' => 5, 'autoSizeMax' => 50, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'category_perms' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:category_perms', @@ -235,6 +274,9 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], ], 'types' => [
Configuration/TCA/be_users.php+40 −0 modified@@ -39,6 +39,9 @@ 'eval' => 'nospace,trim,lower,unique', 'autocomplete' => false, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'password' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.password', @@ -48,6 +51,10 @@ 'size' => 20, 'required' => true, ], + 'authenticationContext' => [ + //'group' => 'be.userManagement', + 'once' => true, + ], ], 'mfa' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.mfa', @@ -56,6 +63,9 @@ 'type' => 'none', 'renderType' => 'mfaInfo', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'usergroup' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.usergroup', @@ -87,6 +97,9 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'avatar' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar', @@ -106,6 +119,9 @@ 'maxitems' => 100, 'autoSizeMax' => 10, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'file_mountpoints' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.options_file_mounts', @@ -139,13 +155,19 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'email' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.email', 'config' => [ 'type' => 'email', 'size' => 20, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'realName' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.name', @@ -168,6 +190,9 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'options' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.options', @@ -209,6 +234,9 @@ 'maxitems' => 17, 'default' => 'readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'workspace_perms' => [ 'displayCond' => 'USER:TYPO3\CMS\Core\Hooks\TcaDisplayConditions->isExtensionInstalled:workspaces', @@ -222,6 +250,9 @@ ['label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:workspace_perms_live'], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'lang' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.lang', @@ -248,6 +279,9 @@ 'autoSizeMax' => 50, 'maxitems' => 100, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'allowed_languages' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:allowed_languages', @@ -258,6 +292,9 @@ 'itemsProcFunc' => \TYPO3\CMS\Core\Localization\TcaSystemLanguageCollector::class . '->populateAvailableSiteLanguages', 'dbFieldLength' => 255, ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], 'TSconfig' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:TSconfig', @@ -289,6 +326,9 @@ ], ], ], + 'authenticationContext' => [ + 'group' => 'be.userManagement', + ], ], ], 'types' => [
Configuration/TCA/Overrides/be_groups.php+5 −0 added@@ -0,0 +1,5 @@ +<?php + +defined('TYPO3') or die(); + +$GLOBALS['TCA']['be_groups']['columns']['hidden']['authenticationContext']['group'] = 'be.userManagement';
Configuration/TCA/Overrides/be_users.php+4 −0 modified@@ -5,3 +5,7 @@ // New be_users are disabled by default and can not disable themselves $GLOBALS['TCA']['be_users']['columns']['disable']['displayCond'] = 'USER:' . \TYPO3\CMS\Core\Hooks\TcaDisplayConditions::class . '->isRecordCurrentUser:false'; $GLOBALS['TCA']['be_users']['columns']['disable']['config']['default'] = 1; + +$GLOBALS['TCA']['be_users']['columns']['disable']['authenticationContext']['group'] = 'be.userManagement'; +$GLOBALS['TCA']['be_users']['columns']['starttime']['authenticationContext']['group'] = 'be.userManagement'; +$GLOBALS['TCA']['be_users']['columns']['endtime']['authenticationContext']['group'] = 'be.userManagement';
Resources/Public/JavaScript/ajax/ajax-request.js+1 −1 modified@@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import{AjaxResponse as s}from"@typo3/core/ajax/ajax-response.js";import{InputTransformer as r}from"@typo3/core/ajax/input-transformer.js";class c{static{this.defaultOptions={credentials:"same-origin"}}constructor(e){this.url=e instanceof URL?e:new URL(e,window.location.origin+window.location.pathname),this.abortController=new AbortController}withQueryArguments(e){const t=this.clone();e instanceof URLSearchParams||(e=new URLSearchParams(r.toSearchParams(e)));for(const[o,n]of e.entries())this.url.searchParams.append(o,n);return t}async get(e={}){const t={method:"GET"},o=await this.send({...t,...e});return new s(o)}async post(e,t={}){const o={body:typeof e=="string"||e instanceof FormData?e:Object.keys(e).length?r.byHeader(e,t?.headers):"",cache:"no-cache",method:"POST"},n=await this.send({...o,...t});return new s(n)}async put(e,t={}){const o={body:typeof e=="string"||e instanceof FormData?e:r.byHeader(e,t?.headers),cache:"no-cache",method:"PUT"},n=await this.send({...o,...t});return new s(n)}async delete(e={},t={}){const o={cache:"no-cache",method:"DELETE"};typeof e=="string"&&e.length>0||e instanceof FormData?o.body=e:typeof e=="object"&&Object.keys(e).length>0&&(o.body=r.byHeader(e,t?.headers));const n=await this.send({...o,...t});return new s(n)}abort(){this.abortController.abort()}clone(){return Object.assign(Object.create(this),this)}async send(e={}){const t=await fetch(this.url,this.getMergedOptions(e));if(!t.ok)throw new s(t);return t}getMergedOptions(e){const{signal:t,...o}=e;return t?.addEventListener("abort",()=>this.abortController.abort()),{...c.defaultOptions,...o,signal:this.abortController.signal}}}export{c as default}; +import{AjaxResponse as o}from"@typo3/core/ajax/ajax-response.js";import{InputTransformer as r}from"@typo3/core/ajax/input-transformer.js";class i{static{this.defaultOptions={credentials:"same-origin"}}constructor(e){this.url=e instanceof URL?e:new URL(e,window.location.origin+window.location.pathname),this.abortController=new AbortController,this.fetch=t=>fetch(t)}withQueryArguments(e){const t=this.clone();e instanceof URLSearchParams||(e=new URLSearchParams(r.toSearchParams(e)));for(const[s,n]of e.entries())this.url.searchParams.append(s,n);return t}async get(e={}){const t={method:"GET"},s=await this.send({...t,...e});return new o(s)}async post(e,t={}){const s={body:typeof e=="string"||e instanceof FormData?e:Object.keys(e).length?r.byHeader(e,t?.headers):"",cache:"no-cache",method:"POST"},n=await this.send({...s,...t});return new o(n)}async put(e,t={}){const s={body:typeof e=="string"||e instanceof FormData?e:r.byHeader(e,t?.headers),cache:"no-cache",method:"PUT"},n=await this.send({...s,...t});return new o(n)}async delete(e={},t={}){const s={cache:"no-cache",method:"DELETE"};typeof e=="string"&&e.length>0||e instanceof FormData?s.body=e:typeof e=="object"&&Object.keys(e).length>0&&(s.body=r.byHeader(e,t?.headers));const n=await this.send({...s,...t});return new o(n)}abort(){this.abortController.abort()}addMiddleware(e){if(Array.isArray(e))return e.forEach(s=>this.addMiddleware(s)),this;const t=this.fetch;return this.fetch=s=>e(s,t),this}clone(){return Object.assign(Object.create(this),this)}async send(e={}){const t=await this.fetch(new Request(this.url,this.getMergedOptions(e)));if(!t.ok)throw new o(t);return t}getMergedOptions(e){const{signal:t,...s}=e;return t?.addEventListener("abort",()=>this.abortController.abort()),{...i.defaultOptions,...s,signal:this.abortController.signal}}}export{i as default};
Tests/Acceptance/Application/Impexp/UsersCest.php+41 −0 modified@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Tests\Acceptance\Application\Impexp; +use Codeception\Exception\MalformedLocatorException; use TYPO3\CMS\Core\Tests\Acceptance\Support\ApplicationTester; use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree; @@ -194,6 +195,20 @@ private function setPageAccess(ApplicationTester $I, PageTree $pageTree, array $ $recursionLevelOption = $I->grabTextFrom('//select[@id="recursionLevel"]/option[' . $recursionLevel . ']'); $I->selectOption('//select[@id="recursionLevel"]', ['value' => $recursionLevelOption]); $I->click($this->inModuleHeader . ' .btn[title="Save and close"]'); + $I->wait(0.5); + $I->switchToMainFrame(); + try { + $needsStepUp = count($I->grabMultiple('.modal-sudo-mode-verification')) > 0; + } catch (MalformedLocatorException) { + $needsStepUp = false; + } + if ($needsStepUp) { + $I->see('Verify with user password'); + $I->fillField('//input[@name="password"]', 'password'); + $I->click('//button[@name="verify"]'); + } + $I->switchToContentFrame(); + $I->wait(0.5); } private function setModAccess(ApplicationTester $I, int $userGroupId, array $modAccessByName): void @@ -219,6 +234,19 @@ private function setModAccess(ApplicationTester $I, int $userGroupId, array $mod $I->click($this->inModuleHeader . ' .btn[title="Save"]'); $I->wait(0.5); + $I->switchToMainFrame(); + try { + $needsStepUp = count($I->grabMultiple('.modal-sudo-mode-verification')) > 0; + } catch (MalformedLocatorException) { + $needsStepUp = false; + } + if ($needsStepUp) { + $I->see('Verify with user password'); + $I->fillField('//input[@name="password"]', 'password'); + $I->click('//button[@name="verify"]'); + } + $I->switchToContentFrame(); + $I->wait(0.5); $I->click($this->inModuleHeader . ' .btn[title="Close"]'); $I->waitForText('Backend user groups'); } @@ -245,6 +273,19 @@ private function setUserTsConfig(ApplicationTester $I, int $userId, string $user $I->executeJS("document.querySelector('" . $codeMirrorSelector . "').setContent('" . $userTsConfig . "')"); $I->click($this->inModuleHeader . ' .btn[title="Save"]'); $I->wait(0.5); + $I->switchToMainFrame(); + try { + $needsStepUp = count($I->grabMultiple('.modal-sudo-mode-verification')) > 0; + } catch (MalformedLocatorException) { + $needsStepUp = false; + } + if ($needsStepUp) { + $I->see('Verify with user password'); + $I->fillField('//input[@name="password"]', 'password'); + $I->click('//button[@name="verify"]'); + } + $I->switchToContentFrame(); + $I->wait(0.5); $I->click($this->inModuleHeader . ' .btn[title="Close"]'); $I->waitForElement('#typo3-backend-user-list'); }
Tests/Acceptance/Application/RecordList/RecordDownloadWithPresetCest.php+14 −0 modified@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Tests\Acceptance\Application\RecordList; +use Codeception\Exception\MalformedLocatorException; use TYPO3\CMS\Core\Tests\Acceptance\Support\ApplicationTester; use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\ModalDialog; use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree; @@ -102,6 +103,19 @@ private function setUserTsConfig(ApplicationTester $I, int $userId, string $user $I->executeJS("document.querySelector('" . $codeMirrorSelector . "').setContent('" . $userTsConfig . "')"); $I->click($this->inModuleHeader . ' .btn[title="Save"]'); $I->wait(0.5); + $I->switchToMainFrame(); + try { + $needsStepUp = count($I->grabMultiple('.modal-sudo-mode-verification')) > 0; + } catch (MalformedLocatorException) { + $needsStepUp = false; + } + if ($needsStepUp) { + $I->see('Verify with user password'); + $I->fillField('//input[@name="password"]', 'password'); + $I->click('//button[@name="verify"]'); + } + $I->switchToContentFrame(); + $I->wait(0.5); $I->click($this->inModuleHeader . ' .btn[title="Close"]'); $I->waitForElement('#typo3-backend-user-list'); }
60572dd050d8[SECURITY] Require step-up authentication for password change
3 files changed · +4 −44
Classes/Controller/SetupModuleController.php+3 −35 modified@@ -30,8 +30,6 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry; use TYPO3\CMS\Core\Core\Environment; -use TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException; -use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\DataHandling\DataHandler; @@ -177,7 +175,6 @@ protected function initialize(ServerRequestInterface $request): ModuleTemplate // if password is disabled, disable repeat of password too (password2) if ($this->tsFieldConf['password.']['disabled'] ?? false) { $this->tsFieldConf['password2.']['disabled'] = 1; - $this->tsFieldConf['passwordCurrent.']['disabled'] = 1; } return $view; } @@ -242,7 +239,7 @@ protected function storeIncomingData(ServerRequestInterface $request): void if (!in_array($field, $fieldList, true)) { continue; } - if (($config['table'] ?? '') === 'be_users' && !in_array($field, ['password', 'password2', 'passwordCurrent', 'email', 'realName', 'admin', 'avatar'], true)) { + if (($config['table'] ?? '') === 'be_users' && !in_array($field, ['password', 'password2', 'email', 'realName', 'admin', 'avatar'], true)) { if (!isset($config['access']) || $this->checkAccess($config) && ($backendUser->user[$field] !== $d['be_users'][$field])) { if (($config['type'] ?? false) === 'check') { $fieldValue = isset($d['be_users'][$field]) ? 1 : 0; @@ -304,26 +301,8 @@ protected function storeIncomingData(ServerRequestInterface $request): void } // Update the password: if ($passwordIsConfirmed && $passwordValid) { - if ($backendUser->isAdmin()) { - $passwordOk = true; - } else { - $currentPasswordHashed = $backendUser->user['password']; - $passwordOk = false; - $saltFactory = GeneralUtility::makeInstance(PasswordHashFactory::class); - try { - $hashInstance = $saltFactory->get($currentPasswordHashed, 'BE'); - $passwordOk = $hashInstance->checkPassword($be_user_data['passwordCurrent'], $currentPasswordHashed); - } catch (InvalidPasswordHashException $e) { - // Could not find hash class responsible for existing password. This is a - // misconfiguration and user can not change its password. - } - } - if ($passwordOk) { - $this->passwordIsUpdated = self::PASSWORD_UPDATED; - $storeRec['be_users'][$beUserId]['password'] = $be_user_data['password']; - } else { - $this->passwordIsUpdated = self::PASSWORD_OLD_WRONG; - } + $this->passwordIsUpdated = self::PASSWORD_UPDATED; + $storeRec['be_users'][$beUserId]['password'] = $be_user_data['password']; } elseif ($passwordIsConfirmed) { $this->passwordIsUpdated = self::PASSWORD_POLICY_FAILED; } else { @@ -806,14 +785,6 @@ protected function getLabel($str, $key = '', $addLabelTag = true) protected function getFieldsFromShowItem() { $allowedFields = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_USER_SETTINGS']['showitem'], true); - if ($this->getBackendUser()->isAdmin()) { - // Do not ask for current password if admin (unknown for other users and no security gain) - $key = array_search('passwordCurrent', $allowedFields); - if ($key !== false) { - unset($allowedFields[$key]); - } - } - $backendUser = $this->getBackendUser(); if ($backendUser->getOriginalUserIdWhenInSwitchUserMode() && $backendUser->isSystemMaintainer(true)) { // DataHandler denies changing the password of system maintainer users in switch user mode. @@ -957,9 +928,6 @@ protected function addFlashMessages(ModuleTemplate $view): void } if ($this->passwordIsSubmitted) { switch ($this->passwordIsUpdated) { - case self::PASSWORD_OLD_WRONG: - $view->addFlashMessage($languageService->sL('LLL:EXT:setup/Resources/Private/Language/locallang.xlf:oldPassword_failed'), $languageService->sL('LLL:EXT:setup/Resources/Private/Language/locallang.xlf:newPassword'), ContextualFeedbackSeverity::ERROR); - break; case self::PASSWORD_NOT_THE_SAME: $view->addFlashMessage($languageService->sL('LLL:EXT:setup/Resources/Private/Language/locallang.xlf:newPassword_failed'), $languageService->sL('LLL:EXT:setup/Resources/Private/Language/locallang.xlf:newPassword'), ContextualFeedbackSeverity::ERROR); break;
ext_tables.php+1 −6 modified@@ -35,11 +35,6 @@ 'label' => 'LLL:EXT:setup/Resources/Private/Language/locallang.xlf:newPasswordAgain', 'table' => 'be_users', ], - 'passwordCurrent' => [ - 'type' => 'password', - 'label' => 'LLL:EXT:setup/Resources/Private/Language/locallang.xlf:passwordCurrent', - 'table' => 'be_users', - ], 'avatar' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar', 'type' => 'avatar', @@ -110,7 +105,7 @@ ], ], 'showitem' => '--div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:personal_data,realName,email,emailMeAtLogin,avatar,lang, - --div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:accountSecurity,passwordCurrent,password,password2,mfaProviders, + --div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:accountSecurity,password,password2,mfaProviders, --div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:opening,colorScheme,theme,startModule,backendTitleFormat, --div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:editFunctionsTab,titleLen,edit_docModuleUpload,showHiddenFilesAndFolders,copyLevels, --div--;LLL:EXT:setup/Resources/Private/Language/locallang.xlf:resetTab,resetConfiguration',
Resources/Private/Language/locallang.xlf+0 −3 modified@@ -93,9 +93,6 @@ <trans-unit id="newPassword_ok"> <source>Password was updated.</source> </trans-unit> - <trans-unit id="passwordCurrent"> - <source>Current password</source> - </trans-unit> <trans-unit id="passwordPolicyFailed"> <source>The password was NOT updated, since it does not meet the password policy requirements.</source> </trans-unit>
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-3jrg-97f3-rqh9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-47938ghsaADVISORY
- github.com/TYPO3-CMS/core/commit/b9a8bcb614ecdd42aa27e1c430c6213d6b6b20b3ghsaWEB
- github.com/TYPO3-CMS/setup/commit/60572dd050d8d861921889a19599bfe045fed5fdghsaWEB
- github.com/TYPO3/typo3/security/advisories/GHSA-3jrg-97f3-rqh9ghsax_refsource_CONFIRMWEB
- typo3.org/security/advisory/typo3-core-sa-2025-013ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.