CVE-2026-45551
Description
Group-Office is an enterprise customer relationship management and groupware tool. Prior to 26.0.25, 25.0.100, and 6.8.165, GroupOffice allows authenticated users to persist arbitrary legacy settings for any user_id via index.php?r=core/saveSetting. A separate client-side sink in the email module injects the email_font_size setting directly into JavaScript without escaping. By combining these two issues, any low-privileged authenticated user can overwrite an administrator's email_font_size setting with a JavaScript payload and trigger stored XSS in the administrator's browser when the GroupOffice web client loads views/Extjs3/modulescripts.php. This vulnerability is fixed in 26.0.25, 25.0.100, and 6.8.165.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Low-privileged users can write arbitrary settings, including a JavaScript payload into an admin's email_font_size, leading to stored XSS.
Vulnerability
Group-Office versions prior to 26.0.25, 25.0.100, and 6.8.165 contain a vulnerability in the www/controller/CoreController.php file. The legacy core/saveSetting action does not verify whether the authenticated user is allowed to modify settings for the requested user_id. This allows any authenticated low-privileged user to write arbitrary key-value pairs into the go_settings table for any user, including an administrator [1].
Exploitation
An attacker must be an authenticated low-privileged user. The exploit chain involves two steps. First, the attacker calls index.php?r=core/saveSetting with parameters name=email_font_size and value=, targeting the administrator's user_id. Second, when the administrator loads the Group-Office web client, the www/modules/email/scripts.inc.php reads the email_font_size setting and directly concatenates it into a JavaScript string without escaping [1]. The generated JavaScript is served via www/views/Extjs3/modulescripts.php, executing the payload in the administrator's browser [1].
Impact
Successful exploitation results in stored cross-site scripting (XSS) in the administrator's browser session. The attacker can execute arbitrary JavaScript in the context of the administrator's session, leading to full compromise of the administrator's account and effective privilege escalation [1].
Mitigation
The vulnerability is fixed in Group-Office versions 26.0.25, 25.0.100, and 6.8.165 released on or before 2026-05-29 [1]. Users should upgrade to these versions immediately. No workarounds are documented in the available references.
AI Insight generated on May 29, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2<26.0.25 || >=25.0.0,<25.0.100 || >=6.8.0,<6.8.165+ 1 more
- (no CPE)range: <26.0.25 || >=25.0.0,<25.0.100 || >=6.8.0,<6.8.165
- (no CPE)range: before 26.0.25, 25.0.100, 6.8.165
Patches
112be55447a2dfCore: Validate user ID param when saving settings
1 file changed · +8 −1
www/controller/CoreController.php+8 −1 modified@@ -31,7 +31,14 @@ protected function ignoreAclPermissions() { } protected function actionSaveSetting($params){ - $response['success']=GO::config()->save_setting($params['name'], $params['value'], $params['user_id']); + + if(go()->getModel()->getUserRights()->mayChangeUsers) { + $userId = $params['user_id']; + } else { + $userId = go()->getUserId(); + } + + $response['success']=GO::config()->save_setting($params['name'], $params['value'], $userId); return $response; }
3d446f616bacCore: Validate user ID param when saving settings
1 file changed · +8 −1
www/controller/CoreController.php+8 −1 modified@@ -28,7 +28,14 @@ protected function ignoreAclPermissions() { } protected function actionSaveSetting($params){ - $response['success']=GO::config()->save_setting($params['name'], $params['value'], $params['user_id']); + + if(go()->getModel()->getUserRights()->mayChangeUsers) { + $userId = $params['user_id']; + } else { + $userId = go()->getUserId(); + } + + $response['success']=GO::config()->save_setting($params['name'], $params['value'], $userId); return $response; }
9c995540b78eCore: Validate user ID param when saving settings
1 file changed · +8 −1
www/controller/CoreController.php+8 −1 modified@@ -32,7 +32,14 @@ protected function ignoreAclPermissions() { } protected function actionSaveSetting($params){ - $response['success']=GO::config()->save_setting($params['name'], $params['value'], $params['user_id']); + + if(go()->getModel()->getUserRights()->mayChangeUsers) { + $userId = $params['user_id']; + } else { + $userId = go()->getUserId(); + } + + $response['success']=GO::config()->save_setting($params['name'], $params['value'], $userId); return $response; }
9ef937d18a28Remove old code which had an authenticated stored XSS vulnerability
1 file changed · +1 −0
CHANGELOG.md+1 −0 modified@@ -1,6 +1,7 @@ - Calendar: Event location field allows free text input - Core: Fixed holidays error in billing because of type and case problem in generate() function - Calendar: update category list according to selected calendar in event window +- Email: Remove old code which had an authenticated stored XSS vulnerability 14-04-2026: 26.0.24 - Support: Mail sending was broken if SMIME was not configured
740f8be99dd9Remove old code which had an authenticated stored XSS vulnerability
1 file changed · +0 −6
www/modules/email/scripts.inc.php+0 −6 modified@@ -44,12 +44,6 @@ $GO_SCRIPTS_JS .= 'true;'; } -$font_size = \GO::config()->get_setting('email_font_size', \GO::user()->id); -if(empty($font_size)) - $GO_SCRIPTS_JS .= 'GO.email.fontSize="14px";'; -else - $GO_SCRIPTS_JS .= 'GO.email.fontSize="'.$font_size.'";'; - $GO_SCRIPTS_JS .= 'GO.email.permissionLevels={delegated:15};'; if(isset($_GET['mail_to']))
88b55ff91d96Remove old code which had an authenticated stored XSS vulnerability
1 file changed · +0 −6
www/modules/email/scripts.inc.php+0 −6 modified@@ -44,12 +44,6 @@ $GO_SCRIPTS_JS .= 'true;'; } -$font_size = \GO::config()->get_setting('email_font_size', \GO::user()->id); -if(empty($font_size)) - $GO_SCRIPTS_JS .= 'GO.email.fontSize="14px";'; -else - $GO_SCRIPTS_JS .= 'GO.email.fontSize="'.$font_size.'";'; - $GO_SCRIPTS_JS .= 'GO.email.permissionLevels={delegated:15};'; if(isset($_GET['mail_to']))
c8690c3837c6Remove old code which had an authenticated stored XSS vulnerability
1 file changed · +0 −6
www/modules/email/scripts.inc.php+0 −6 modified@@ -44,12 +44,6 @@ $GO_SCRIPTS_JS .= 'true;'; } -$font_size = \GO::config()->get_setting('email_font_size', \GO::user()->id); -if(empty($font_size)) - $GO_SCRIPTS_JS .= 'GO.email.fontSize="14px";'; -else - $GO_SCRIPTS_JS .= 'GO.email.fontSize="'.$font_size.'";'; - $GO_SCRIPTS_JS .= 'GO.email.permissionLevels={delegated:15};'; if(isset($_GET['mail_to']))
8bd044745a8e25.0 branch for goui
2 files changed · +2 −2
.gitmodules+1 −1 modified@@ -5,7 +5,7 @@ [submodule "www/views/goui/goui"] path = www/views/goui/goui url = ../goui.git - branch = main + branch = 25.0 [submodule "www/go/modules/community/activesync/Z-Push"] path = www/go/modules/community/activesync/Z-Push url = ../Z-Push.git
www/views/goui/goui+1 −1 modified@@ -1 +1 @@ -Subproject commit 7aaf0723ed2757862f9deea8b47f172b0b0b3bb5 +Subproject commit f4109e8acca54cb1989a471d0768b698c3c8bf8d
423e1baebce4CHANGELOG.md
1 file changed · +2 −0
CHANGELOG.md+2 −0 modified@@ -1,3 +1,5 @@ +- ActiveSync: Missing MSTZ function + 13-04-2026: 6.8.164 - Files: Move to trash could accidentally remove selected tree folder instead of selection in the thumbnail view - Files: Better validator for folder names for Windows compatibility
7094ca193e2736768 backport from 26.0
2 files changed · +7 −0
CHANGELOG.md+1 −0 modified@@ -1,6 +1,7 @@ - ActiveSync: Missing MSTZ function - Email: Remove old code which had an authenticated stored XSS vulnerability - Core: Validate user ID param when saving settings +- OTP: explicitly log username and IP upon wrong authentication 13-04-2026: 6.8.164 - Files: Move to trash could accidentally remove selected tree folder instead of selection in the thumbnail view
www/go/modules/community/otp/OtpAuthenticator.php+6 −0 modified@@ -2,6 +2,8 @@ namespace go\modules\community\otp; +use go\core\ErrorHandler; +use go\core\http\Request; use go\core\model\Token; use go\core\auth\SecondaryAuthenticator; use go\core\db\Query; @@ -21,22 +23,26 @@ public function authenticate(Token $token, array $data): bool /** @phpstan-ignore-next-line */ $otp = $token->getUser()->otp; + $user = $token->getUser(); if (!$otp) { $this->setValidationError('otp_code', ErrorCode::NOT_FOUND); + ErrorHandler::log("Token authentication failed for user ". $user->username . " from IP: '" . Request::get()->getRemoteIpAddress() . "'"); return false; } $expiresAt = $otp->expiresAt; if ($expiresAt && new DateTime($expiresAt) < new DateTime()) { $this->setValidationError('otp_code', ErrorCode::NOT_FOUND); + ErrorHandler::log("Token authentication failed for user ". $user->username . " from IP: '" . Request::get()->getRemoteIpAddress() . "'"); return false; } if (!$otp->verifyCode($data['otp_code'])) { $this->setValidationError('otp_code', ErrorCode::INVALID_INPUT); + ErrorHandler::log("Token authentication failed for user ". $user->username . " from IP: '" . Request::get()->getRemoteIpAddress() . "'"); return false; }
74b671e03cd8CHANGELOG.md
1 file changed · +2 −0
CHANGELOG.md+2 −0 modified@@ -1,4 +1,6 @@ - ActiveSync: Missing MSTZ function +- Email: Remove old code which had an authenticated stored XSS vulnerability +- Core: Validate user ID param when saving settings 13-04-2026: 6.8.164 - Files: Move to trash could accidentally remove selected tree folder instead of selection in the thumbnail view
Vulnerability mechanics
Root cause
"Missing authorization check in `actionSaveSetting` allows any authenticated user to write arbitrary settings for any other user, and the `email_font_size` setting is injected into JavaScript without escaping."
Attack vector
A low-privileged authenticated attacker sends a POST request to `index.php?r=core/saveSetting` with `name=email_font_size`, a JavaScript payload as `value`, and the target administrator's `user_id`. The setting is persisted in the `go_settings` table for that administrator. When the administrator next loads the GroupOffice web client, `modulescripts.php` serves the unescaped payload as `GO.email.fontSize="...";`, causing the JavaScript to execute in the administrator's browser within the GroupOffice origin [ref_id=1].
Affected code
The vulnerability spans two files. `www/controller/CoreController.php` (the `actionSaveSetting` method) accepted an arbitrary `user_id` parameter without authorization checks, allowing any authenticated user to write settings for any other user. `www/modules/email/scripts.inc.php` read the `email_font_size` setting and injected it directly into a JavaScript string literal without escaping, creating a stored XSS sink. The response is served via `www/views/Extjs3/modulescripts.php`.
What the fix does
Patches [patch_id=3077457] and [patch_id=3077455] fix the server-side authorization gap in `CoreController.php`: the `actionSaveSetting` method now checks `go()->getModel()->getUserRights()->mayChangeUsers` before accepting the caller-supplied `user_id`; if the caller lacks the right to change users, the setting is saved only for the caller's own user ID. Patches [patch_id=3077458] and [patch_id=3077456] remove the vulnerable client-side sink entirely by deleting the `email_font_size` injection block from `scripts.inc.php`, eliminating the stored XSS vector.
Preconditions
- authAttacker must have a valid authenticated session with any low-privileged GroupOffice account.
- inputThe target administrator must load the GroupOffice web client after the setting is poisoned.
- configThe application must be a version prior to 26.0.25, 25.0.100, or 6.8.165.
Generated on May 29, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1News mentions
0No linked articles in our index yet.