GHSA-jg2j-2w24-54cg: Kimai has an Authenticated Server-Side Template Injection (SSTI)
Kimai 2.45.0 - Authenticated Server-Side Template Injection (SSTI)Vulnerability Summary| Field | Value |
|-------|-------|
| **Title** | Authenticated SSTI via Permissive Export Template Sandbox || **Attack Vector** | Network |
| **Attack Complexity** | Low |
| **Privileges Required** | High (Admin with export permissions and server access) |
| **User Interaction** | None |
| **Impact** | Confidentiality: HIGH (Credential/Secret Extraction) |
| **Affected Versions** | Kimai 2.45.0 (likely earlier versions) |
| **Tested On** | Docker: kimai/kimai2:apache-2.45.0 |
| **Discovery Date** | 2026-01-05 |**Why Scope is "Changed":** The extracted `APP_SECRET` can be used to forge Symfony login links for ANY user account, expanding the attack beyond the initially compromised admin context.Vulnerability DescriptionKimai's export functionality uses a Twig sandbox with an overly permissive security policy (`DefaultPolicy`) that allows arbitrary method calls on objects available in the template context. An authenticated user with export permissions can deploy a malicious Twig template that extracts sensitive information including:**Environment Variables** (APP_SECRET, DATABASE_URL)**All User Password Hashes** (bcrypt)**Serialized Session Tokens****CSRF Tokens**Prerequisites**Authenticated Access**: Valid account with export permissions (typically ROLE_ADMIN, ROLE_SUPER_ADMIN, or ROLE_TEAMLEAD)**Template Deployment**: Ability to place a malicious `.pdf.twig` template in `/opt/kimai/var/export/` via:Filesystem access (server admin)Test EnvironmentUsers in Test InstanceThe test environment contains 2 users whose password hashes were successfully extracted:Kimai Users Page - screenshot_users.png:
<img width="1124" height="1119" alt="screenshot_users" src="https://github.com/user-attachments/assets/89771b84-a95c-4c6d-9515-7e9a38ef3235" />| User | Role | Hash Extracted |
|------|------|----------------|
| admin | ROLE_SUPER_ADMIN | ✅ Yes |
| lowpriv | ROLE_USER | ✅ Yes |Confirmed Exploitation EvidenceTest Date: 2026-01-05Extracted Data (Actual Output from Exploit)Root Cause AnalysisVulnerable Code: `src/Twig/SecurityPolicy/ExportPolicy.php`The export functionality uses `ExportPolicy` which includes `DefaultPolicy`:The Problem: `src/Twig/SecurityPolicy/DefaultPolicy.php`This allows templates to call methods like:`app.request.server.get("APP_SECRET")` - Environment variable access`app.session.get("_security_secured_area")` - Session data access`entry.user.password` - Password hash accessExploitation StepsStep 1: Deploy Malicious TemplateSave the following as `/opt/kimai/var/export/ssti-extract.pdf.twig`:Step 2: Run the ExploitStep 3: Extract Text from PDFDetailed Exploit UsageRequirementsCommand SyntaxExample UsageExpected OutputOutput Files| File | Description |
|------|-------------|
| `kimai_extracted_data.pdf` | PDF containing all extracted sensitive data |Manual PDF Text ExtractionError Handling| Error Message | Cause | Solution |
|---------------|-------|----------|
| `Cannot connect to <url>` | Target unreachable | Check URL and network |
| `Authentication failed` | Wrong credentials | Verify username/password |
| `Template not found` | Template not deployed | Deploy template first (Step 1) |
| `Access denied` | Insufficient permissions | Use admin account with export perms |
| `pdftotext not installed` | Missing tool | Run `apt install poppler-utils` |Complete Exploit Script (ssti_exploit.py)Impact Analysis| Extracted Data | Security Impact |
|---------------|-----------------|
| `APP_SECRET` | Can forge Symfony login links to access ANY user account |
| `DATABASE_URL` | Direct database connection credentials exposed |
| Password Hashes | Offline password cracking possible (bcrypt) |
| Session Tokens | Session structure analysis, potential replay attacks |
| CSRF Tokens | Bypass CSRF protection for subsequent attacks |Attack Chain ExampleExploit SSTI → Extract `APP_SECRET`Use `APP_SECRET` to forge login link for target userAccess target user's account without knowing their passwordRemediationImmediate FixReplace `DefaultPolicy` with `InvoicePolicy` in `ExportPolicy`:Additional Hardening**Block environment access in templates:****Block session access in templates:****Restrict User object property access:**Reported by: Mahammad Huseynkhanli
CVSS v3.1: 6.8