Listen to this Post
The vulnerability arises from Kimai’s Twig sandbox (StrictPolicy) which explicitly allow‑lists the `config()` Twig function without any key filtering. `config(name)` delegates to App\Configuration\SystemConfiguration::find($name), a direct dictionary lookup into the flattened `kimai.config` container parameter. This parameter is built by App\DependencyInjection\AppExtension::loadInternal(), which recursively flattens every value from `kimai.yaml` into dotted keys – including secrets such as `ldap.connection.password` and saml.connection.sp.privateKey. The sandbox policy (src/Twig/SecurityPolicy/StrictPolicy.php:40‑55) includes `’config’` in `$allowedFunctions` with no additional blocklist. src/Twig/Configuration.php:22‑45 registers the Twig function and, after a few hardcoded theme constants, calls $this->configuration->find($name). src/Configuration/SystemConfiguration.php:54‑62 simply returns $this->settings[$name] ?? null, providing unrestricted read access to the entire flattened configuration. Both the invoice renderer (src/Invoice/Renderer/AbstractTwigRenderer.php:66‑74) and export renderers (src/Export/Base/Renderer.php) enable the sandbox against `StrictPolicy` and pass the shared Twig environment (which has the `config` function) into sandboxed rendering. An admin with `upload_invoice_template` permission (ROLE_SUPER_ADMIN) can upload a malicious Twig template. When any user with invoice permissions (ROLE_ADMIN, ROLE_TEAMLEAD) later generates an invoice or export using that template, the secrets are rendered directly into the PDF/HTML/CSV output. The attacker receives the document containing e.g. {{ config('ldap.connection.password') }}. This bypasses the previous fix for GHSA‑rh42‑6rj2‑xwmc, which only blocked User‑method calls but left `config()` unrestricted.
Platform: Kimai
Version: Unspecified versions
Vulnerability: Twig config exposure
Severity: Critical
date: 2026-05-06
Prediction: Patch already applied
What Undercode Say:
Extract LDAP password from invoice template
echo '{{ config("ldap.connection.password") }}' > malicious.html.twig
Dump all config keys via CLI (if template upload possible)
for key in $(php bin/console debug:container --parameter=kimai.config | grep -oP '"\K[^"]+'); do
echo "{{ config('$key') }}" >> dump_all.twig
done
Simulate sandbox bypass in test environment
php -r "require 'vendor/autoload.php'; \$config = new App\Configuration\SystemConfiguration(['ldap.connection.password' => 'secret']); echo \$config->find('ldap.connection.password');"
Exploit:
Upload invoice template via admin UI containing `{{ config(‘ldap.connection.password’) }}` and {{ config('saml.connection.sp.privateKey') }}. Trigger invoice generation as teamlead – secrets appear in downloaded PDF.
Protection from this CVE:
Update to Kimai version that patches `config()` to only return a pre‑configured whitelist. Block `saml.` and `ldap.` prefixed keys in sandbox mode. Restrict `upload_invoice_template` to absolutely trusted admins only. Monitor invoice/export outputs for unexpected dotted keys.
Impact:
Leak of LDAP bind password (domain credential reuse) and SAML SP private key (SAML assertion forgery). Affects all deployments with LDAP/SAML + invoice system where any non‑SUPER_ADMIN generates invoices/export.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

