{"id":"CVE-2026-80198","aliases":["GHSA-vrqv-52x7-rm4v"],"url":"https://o3.security/vulnerability/CVE-2026-80198","summary":"Kimai before 2.56.0 Information Disclosure via config() Twig Function","details":"### Summary\n\nKimai's Twig sandbox (`StrictPolicy`, used for admin-uploaded invoice and export templates) allow-lists the `config()` Twig function with no key filtering. `config(name)` delegates to `App\\Configuration\\SystemConfiguration::find($name)`, which returns arbitrary entries from the flattened `kimai.config` container parameter built in `App\\DependencyInjection\\AppExtension::loadInternal()`. Any admin who can upload a Twig template can therefore render server-wide secrets - the LDAP bind password, the SAML SP private key, and any other dotted configuration key populated from `kimai.yaml` - into the invoice or export output, which is then delivered to whoever generates an invoice or export from that template (including lower-privileged users such as teamleads with invoice permissions). This is a second, uncovered class of the same defense-in-depth issue patched in GHSA-rh42-6rj2-xwmc: the previous fix added a User-method blocklist but left the `config()` function unrestricted.\n\n### Details\n\n`src/Twig/SecurityPolicy/StrictPolicy.php:40-55` explicitly allow-lists `'config'`:\n\n```php\nprivate array $allowedFunctions = [\n    'max', 'min', 'range', 'constant', 'cycle', 'random', 'date',\n    't',\n    'encore_entry_css_source', 'encore_entry_link_tags', 'encore_entry_script_tags',\n    'is_granted',\n    'qr_code_data_uri',\n    'config',                       // <-- sink, no key filter\n    'create_date', 'month_names', 'locale_format',\n    'class_name'\n];\n```\n\n`src/Twig/Configuration.php:22-45` is the Twig function implementation:\n\n```php\npublic function getFunctions(): array\n{\n    return [new TwigFunction('config', [$this, 'get'])];\n}\n\npublic function get(string $name)\n{\n    switch ($name) {\n        case 'chart-class':                     return '';\n        case 'theme.chart.background_color':    return '#3c8dbc';\n        // ... 4 more theme constants\n    }\n    return $this->configuration->find($name);   // <-- arbitrary key lookup\n}\n```\n\n`App\\Configuration\\SystemConfiguration::find()` at `src/Configuration/SystemConfiguration.php:54-62` is a direct dictionary lookup. The dictionary `$this->settings` is initialised from the `kimai.config` container parameter, which the `AppExtension` flattens from `kimai.yaml` into dotted-notation keys.\n```\n\nThe LDAP and SAML schemas declared in `src/DependencyInjection/Configuration.php` define secret-valued scalar nodes that survive the flattening and become reachable keys:\n\n```php\n// getLdapNode()\n->arrayNode('connection')\n    ->children()\n        ->scalarNode('host')->defaultNull()->end()\n        ->scalarNode('username')->end()\n        ->scalarNode('password')->end()       // -> settings['ldap.connection.password']\n        ...\n\n// getSamlNode()\n->arrayNode('sp')\n    ->children()\n        ->scalarNode('x509cert')->end()\n        ->scalarNode('privateKey')->end()     // -> settings['saml.connection.sp.privateKey']\n        ...\n```\n\nThe invoice and export renderers both enable the sandbox against `StrictPolicy` and pass the shared Twig environment - the one with the `config` function registered - into sandboxed rendering: `src/Invoice/Renderer/AbstractTwigRenderer.php:66-74` and `src/Export/Base/{PDFRenderer,HtmlRenderer}.php`. An admin who uploads a malicious invoice or export template therefore gets an unrestricted read primitive against `kimai.config`.\n\nIn a real deployment the attacker template is uploaded through the admin UI (ROLE_SUPER_ADMIN, permission `upload_invoice_template`), saved by `src/Invoice/InvoiceTemplate*` and later rendered by whoever generates an invoice or export for that template. The rendering user is typically a teamlead or admin with invoice permission (`INVOICE` permission set: `['view_invoice','create_invoice','manage_invoice_template']`, granted to ROLE_ADMIN and ROLE_TEAMLEAD in `config/packages/kimai.yaml`). The rendered output is returned as the invoice PDF/HTML or as a CSV/XLSX export, so the secrets land in a document that is routinely downloaded and emailed.\n\n### Impact\n\nAny Kimai deployment that (a) has SAML or LDAP configured in `kimai.yaml`, and (b) has at least one user (other than the current SUPER_ADMIN) who will render a template-based invoice or export in the future, is affected. A malicious or compromised SUPER_ADMIN can upload a template once, leave, and subsequent invoice or export generations by teamleads or other admins silently exfiltrate `ldap.connection.password`, `saml.connection.sp.privateKey`, `saml.connection.sp.x509cert`, and any other dotted configuration key into an attacker-readable artifact. The LDAP bind password gives domain-credential access to the company directory and often to every downstream system that trusts the same directory; the SAML SP private key allows an attacker to forge signed SAML assertions to any service provider that trusts the same key pair. This is the same class of defense-in-depth leak that GHSA-rh42-6rj2-xwmc patched for user-level secrets, at a broader impact because the keys leaked here are system-wide rather than per-user, and the current StrictPolicy does not intercept the `config()` call path. \n\n### Solution\n\nThe `config()` function was patched to only return a pre-configured list of settings in sandboxed mode. \n\nAdditional checks were added to prevent access to configs that start with `saml.` or `ldap.`.\n\nKimai will not issue a CVE, because this requires a SUPER_ADMIN account and it only affects system with activated LDAP or SAML, which also uses the invoice system.","published":"2026-08-25T23:19:04.492Z","modified":"2026-10-28T02:30:25.105677158Z","cvss":null,"epss":{"score":0.00335,"percentile":0.26024,"asOf":"2026-08-27"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Packagist","name":"kimai/kimai","fixedVersion":"2.56.0"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/80xxx/CVE-2026-80198.json"},{"type":"ADVISORY","url":"https://github.com/kimai/kimai/security/advisories/GHSA-vrqv-52x7-rm4v"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-80198"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/kimai-before-2.56.0-information-disclosure-via-config-twig-function"},{"type":"PACKAGE","url":"https://github.com/kimai/kimai"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-28T02:30:25.105677158Z"}}