May 6, 2026·6 min read·7 visits
The Twig `config()` function in Kimai failed to restrict access to sensitive configuration keys within sandboxed templates. Highly privileged users could exploit this to leak server secrets (LDAP/SAML) into rendered PDFs or HTML exports. The issue is resolved in version 2.56.0.
Kimai versions up to 2.55.0 suffer from an information exposure vulnerability where the custom Twig `config()` function lacks sufficient sandbox restrictions. This flaw allows users with template upload privileges to extract sensitive server-wide configuration values, such as LDAP credentials and SAML private keys, by rendering them into exported invoices or documents.
The Kimai time-tracking application utilizes the Twig templating engine to generate invoices and export documents in HTML and PDF formats. To support customization, administrators and users with the upload_invoice_template permission can upload custom Twig templates. These templates execute within a sandboxed environment designed to prevent arbitrary code execution and unauthorized access to application internals.
Kimai exposes a custom Twig function named config() to these templates, intended to provide access to basic branding and display settings. However, in versions prior to 2.56.0, this function operated without access controls or awareness of the sandbox state. The function queried the underlying system configuration repository directly and returned the requested value.
Because the config() function lacked restrictions, a user capable of uploading a template could request any configuration key known to the system. This included highly sensitive parameters required for enterprise integrations, such as LDAP directory credentials and SAML Service Provider private keys.
The exposure of these keys constitutes a significant confidentiality breach. While the vulnerability requires elevated privileges to exploit, the resulting credential theft allows the attacker to pivot and attack downstream identity providers or internal directory services.
The vulnerability originates in the src/Twig/Configuration.php file, which defines the config() Twig function for the Kimai application. When a Twig template calls this function, the engine delegates the execution to the corresponding PHP method.
The implementation of the get(string $name) method retrieved the specified key directly from the SystemConfiguration object. The method failed to implement any security policy or validate whether the execution context was sandboxed.
The Twig sandbox model restricts access to specific tags, filters, functions, and object properties. However, when a custom function is explicitly registered and exposed to the environment, it is the responsibility of that function's underlying PHP implementation to enforce boundary checks. By trusting the input parameter completely, the application inadvertently exposed the entire system configuration store to the presentation layer.
The vulnerable code path resided in the get method of the Configuration Twig extension. The method processed the string parameter and returned the corresponding configuration state without assessing the sensitivity of the requested key.
// src/Twig/Configuration.php (Vulnerable)
public function get(string $name)
{
// Missing sandbox and sensitivity checks
return $this->configuration->find($name);
}The vendor addressed the issue in Pull Request #5923 by introducing dual-layer protection. The first layer consists of an explicit blacklist that categorically denies access to authentication-related configuration keys, regardless of the execution context.
// src/Twig/Configuration.php (Patched - Blacklist)
if (str_starts_with($name, 'saml.') || str_starts_with($name, 'ldap.')) {
throw new SecurityError(\sprintf('Templates cannot access security configuration %s.', $name));
}The second layer integrates with Twig's SandboxExtension to enforce a strict whitelist when the template is executing within a restricted environment. If the sandbox is active, the function only permits access to specific, benign presentation keys.
// src/Twig/Configuration.php (Patched - Sandbox Whitelist)
if ($environment->hasExtension(SandboxExtension::class)) {
$sandbox = $environment->getExtension(SandboxExtension::class);
if ($sandbox->isSandboxed()) {
if (!in_array($name, ['theme.branding.logo', 'theme.branding.company', 'themeAllowAvatarUrls'])) {
throw new SecurityError('Sandboxed template tried to access configuration key: ' . $name);
}
}
}Additionally, the patch deprecated the kimai_config global variable to consolidate configuration access through the secured config() function, reducing the attack surface.
Exploitation requires the attacker to possess either the ROLE_SUPER_ADMIN capability or the explicit upload_invoice_template permission within the Kimai application. An attacker meeting these prerequisites begins by crafting a malicious Twig template payload.
The payload is embedded directly into the HTML structure of a custom invoice template. The attacker uses the Twig output syntax ({{ ... }}) to invoke the vulnerable config() function, passing the target secret key as the argument. For example, the attacker might insert <p>LDAP Password: {{ config('ldap.connection.password') }}</p>.
The attacker navigates to the 'System -> Invoices -> Templates' administrative interface and uploads the crafted template. The application accepts the file and makes it available for rendering.
To trigger the payload, the attacker (or an unaware user) generates a new invoice utilizing the malicious template. The Twig engine processes the template, executes the config() function, and retrieves the LDAP password. The final rendered document (PDF or HTML) contains the plain-text secret, which the attacker subsequently downloads and extracts.
The primary impact of this vulnerability is a high-severity breach of confidentiality. Attackers successfully exploiting this flaw gain unauthorized read access to internal configuration parameters that govern the security and connectivity of the Kimai instance.
The most critical assets exposed by this vulnerability are integration secrets. Specifically, the LDAP bind password (ldap.connection.password) and the SAML Service Provider private keys can be extracted. Access to LDAP credentials often provides an attacker with a foothold into the organization's broader Active Directory or OpenLDAP infrastructure.
Despite the severe consequences of the data exposure, the overall severity is rated as Low by the vendor. This rating reflects the high privilege barrier required to exploit the flaw. Administrators capable of uploading invoice templates already possess significant control over the application environment. However, this vulnerability elevates their capabilities from application administration to potential domain-level compromise through credential theft.
The vendor released Kimai version 2.56.0 in April 2026 to resolve this vulnerability. Administrators must upgrade their self-hosted Kimai instances to version 2.56.0 or later. The update introduces the necessary sandbox validation logic and explicit key blocklists to the Configuration Twig extension.
For organizations unable to immediately deploy the update, mitigation requires restricting access to the invoice template upload functionality. Administrators should review user roles and revoke the upload_invoice_template permission from all non-essential accounts.
Kimai Cloud customers are not exposed to this vulnerability. The cloud service employs a manual review process for custom templates, preventing the deployment of malicious Twig payloads that abuse the config() function.
| Product | Affected Versions | Fixed Version |
|---|---|---|
Kimai Kimai | <= 2.55.0 | 2.56.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-200 |
| Attack Vector | Application UI (Template Upload) |
| Impact | Confidentiality (Secret Leakage) |
| Privileges Required | High (ROLE_SUPER_ADMIN or upload_invoice_template) |
| Exploit Status | Proof of Concept Known |
| KEV Status | Not Listed |
Exposure of Sensitive Information to an Unauthorized Actor