CVE-2026-93954 Overview
CVE-2026-93954 is an incorrect authorization vulnerability [CWE-285] in the grimmory-tools grimmory application through versions 3.3.3 and 3.4.1. The flaw resides in the AppSettingController.getAppSettings function within backend/src/main/java/org/booklore/controller/AppSettingController.java, which serves the Settings API endpoint. An authenticated remote attacker with low privileges can query GET /api/v1/settings and receive settings data that should be restricted by permission. The exploit has been publicly disclosed. Prior work in PR #2558 (merged as commit 53abc8b) moved the OpenID Connect (OIDC) secret into a dedicated setting but did not restrict the settings endpoint itself.
Critical Impact
Authenticated users can retrieve application settings that should be permission-gated, resulting in unauthorized disclosure of configuration data through the /api/v1/settings endpoint.
Affected Products
- grimmory-tools grimmory 3.3.3
- grimmory-tools grimmory 3.4.1
- Earlier versions of the grimmory backend exposing AppSettingController.getAppSettings
Discovery Timeline
- 2026-09-19 - CVE-2026-93954 published to the National Vulnerability Database (NVD)
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-93954
Vulnerability Analysis
The vulnerability is an incorrect authorization defect in the grimmory backend Settings API. The getAppSettings handler in AppSettingController.java returns application settings without validating whether the requesting user holds the permission required to read them. Any authenticated caller can therefore issue GET /api/v1/settings and receive the full settings payload.
An earlier change, PR #2558 (commit 53abc8b), attempted to reduce exposure by relocating the OIDC secret into a dedicated setting. That change did not add access control to the settings endpoint. The remediation in commit 2b66ca6df8110f6b512e030b54c16b9fbe318f17 (PR #2647) introduces AuthenticationService into the controller and restricts responses based on caller permissions. The patch also removes the CacheConfig bean that maintained publicSettings and appSettings caches, eliminating a stale-response surface for the newly permission-scoped endpoint.
Root Cause
The root cause is missing authorization enforcement in a controller method that returns sensitive configuration. The getAppSettings handler lacked a permission check tied to the authenticated principal, so authorization was effectively "authenticated" rather than "authorized for settings read." This maps to [CWE-285] Improper Authorization.
Attack Vector
Exploitation requires network access to the grimmory API and any authenticated low-privilege account. The attacker sends a GET /api/v1/settings request and parses the response for configuration values that should have been gated behind an administrative role. No user interaction or elevated privilege is required.
// Patch excerpt: AppSettingController.java (PR #2647, commit 2b66ca6d)
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
+import org.booklore.config.security.service.AuthenticationService;
import org.booklore.model.dto.settings.AppSettingKey;
import org.booklore.model.dto.settings.AppSettings;
import org.booklore.model.dto.settings.OidcProviderDetails;
// Source: https://github.com/grimmory-tools/grimmory/commit/2b66ca6df8110f6b512e030b54c16b9fbe318f17
Detection Methods for CVE-2026-93954
Indicators of Compromise
- Repeated authenticated GET /api/v1/settings requests originating from low-privilege user accounts or non-administrative service tokens.
- Access to the settings endpoint from source addresses that do not correspond to administrative workstations or automation hosts.
- Response bodies containing OIDC provider details or other privileged configuration fields returned to non-admin sessions.
Detection Strategies
- Instrument the grimmory backend to log the caller identity, granted authorities, and endpoint path for every AppSettingController invocation.
- Alert when a single account issues an unusually high volume of /api/v1/settings requests within a short window.
- Correlate settings-endpoint access with subsequent authentication or configuration changes to identify reconnaissance leading to abuse.
Monitoring Recommendations
- Forward reverse proxy, application, and WAF logs for the grimmory API into a centralized analytics platform for retention and query.
- Baseline normal callers of /api/v1/settings and alert on new principals accessing the endpoint.
- Review authentication logs for accounts that queried the settings endpoint before performing sensitive actions.
How to Mitigate CVE-2026-93954
Immediate Actions Required
- Upgrade grimmory to a version that includes commit 2b66ca6df8110f6b512e030b54c16b9fbe318f17 (PR #2647).
- Rotate any OIDC client secrets, API tokens, or credentials that may have been exposed through the unrestricted settings endpoint.
- Audit account inventory and disable unnecessary low-privilege accounts that could have reached the API.
Patch Information
The fix is delivered in commit 2b66ca6df8110f6b512e030b54c16b9fbe318f17 via PR #2647. The patch injects AuthenticationService into AppSettingController to enforce permission checks and removes the settings cache defined in CacheConfig.java. Additional context is available in the VulDB advisory for CVE-2026-93954 and GitHub Issue #2430.
Workarounds
- Restrict network access to /api/v1/settings at a reverse proxy or API gateway so only administrative source addresses can reach the endpoint.
- Enforce role-based access control at the ingress layer until the backend patch is deployed.
- Reduce the number of accounts able to authenticate to the grimmory API, minimizing the pool of principals eligible to exploit the flaw.
# Example nginx snippet: restrict the settings endpoint to admin IPs
location = /api/v1/settings {
allow 10.0.10.0/24; # admin subnet
deny all;
proxy_pass http://grimmory_backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.