{"id":"GHSA-3xc2-h5r3-wv3r","aliases":["CVE-2026-42267"],"title":"Kimai vulnerable to formula Injection via tag names in XLSX export","titleSource":"OSV","descriptionSource":"OSV","declaredSeverity":"MODERATE","description":"## Summary\n\nAny `ROLE_USER` can create a tag with a formula string as its name (e.g. `=SUM(54+51)`) via `POST /api/tags` and assign it to a timesheet. When an admin exports timesheets to XLSX, `ArrayFormatter.formatValue()` joins tag names with `implode()` and returns the result unchanged. OpenSpout promotes any `=`-prefixed string to a `FormulaCell`, writing `<f>SUM(54+51)</f>` into the XLSX archive. Excel evaluates the formula when the file is opened.\n\n## Details\n\n### 1. `ArrayFormatter` does not sanitize before returning\n\n`sanitizeDDE()` exists on `StringHelper` and is called by `TextFormatter`, but `ArrayFormatter` never calls it.\n```php\n// src/Export/Package/CellFormatter/ArrayFormatter.php:24\nreturn implode(', ', $value);  // no sanitizeDDE() call\n```\n\n### 2. Tag name validation does not block formula trigger characters\n\nThe API blocks commas in tag names but permits `=`, `+`, `-`, and `@` - all valid formula prefixes in Excel and LibreOffice Calc.\n\n### 3. OpenSpout silently promotes strings to formula cells\n\n`Cell::fromValue(\"=SUM(54+51)\")` returns a `FormulaCell` with no warning.\n\n### PoC\n\n1. It logs in as normal user, creates tag `=SUM(54+51)`, assigns it to a timesheet.\n2. Admin has to export timesheets to Excel version via `/en/export/` endpoint.\n\n<img width=\"1339\" height=\"700\" alt=\"image\" src=\"https://github.com/user-attachments/assets/884c7943-5e3b-4647-8bcc-e264d6719d66\" />\n\n<img width=\"1304\" height=\"128\" alt=\"formula_injection_tags\" src=\"https://github.com/user-attachments/assets/ef28f2ad-7491-4a15-bb18-1fcd6ff5e55a\" />\n\n## Impact\n\n- Any `ROLE_USER` can plant a formula that executes on the workstation of any user who exports and opens timesheet data\n- A single malicious tag poisons all future exports across all users and date ranges until the tag is deleted\n\n## Fixes\n\n1. Prevent `=` being part of the tag name (and other fields as well)\n2. Use OpenSpout `TextCell` for everything that is a string","severity":"medium","score":5.7,"published":"2026-05-05T20:53:38.000Z","modified":"2026-05-14T20:48:37.800Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"Packagist","name":"kimai/kimai","sources":[{"name":"OSV · GHSA-3xc2-h5r3-wv3r","url":"https://osv.dev/vulnerability/GHSA-3xc2-h5r3-wv3r"}],"ranges":[{"events":[{"introduced":"2.27.0"},{"fixed":"2.54.0"}],"type":"ECOSYSTEM"}],"versions":["2.27.0","2.28.0","2.29.0","2.30.0","2.31.0","2.32.0","2.33.0","2.34.0","2.35.0","2.35.1","2.36.0","2.36.1","2.37.0","2.38.0","2.39.0","2.40.0","2.41.0","2.42.0","2.43.0","2.44.0","2.45.0","2.46.0","2.47.0","2.48.0","2.49.0","2.50.0","2.51.0","2.52.0","2.53.0"],"fixed":["2.54.0"]}],"sourceAffected":[],"references":["https://github.com/kimai/kimai/security/advisories/GHSA-3xc2-h5r3-wv3r","https://nvd.nist.gov/vuln/detail/CVE-2026-42267","https://github.com/kimai/kimai","https://github.com/kimai/kimai/releases/tag/2.54.0"],"sources":[{"name":"OSV","id":"GHSA-3xc2-h5r3-wv3r","modified":"2026-05-14T20:48:37.800190Z","url":"https://osv.dev/vulnerability/GHSA-3xc2-h5r3-wv3r"}],"assessments":[{"source":"OSV","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N","score":5.7},{"source":"OSV","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:A/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P","score":5.4}],"products":[],"remediation":[],"kev":{"status":"not-listed","checkedAt":"2026-10-28T16:00:31.263Z"},"coverage":[{"source":"NVD","status":"not-checked"},{"source":"GHSA","status":"not-checked"},{"source":"EUVD","status":"not-checked"},{"source":"EPSS","status":"not-checked"}],"evidence":[]}