# CVE-2026-44298: kimai — Fixed in 2.56

🐘

🐘 Packagist

Not in CISA KEV

MEDIUM severity

# CVE-2026-44298 — kimai

MEDIUM 

CVE-2026-44298 is a medium-severity (CVSS 4.1) Path Traversal vulnerability in kimai/kimai. A fix is available for kimai/kimai — see the affected versions and patch details below.

Kimai: Arbitrary file read in invoice PDF renderer (admin)

Also known as[GHSA-h5fh-7hwr-97mw](/vulnerability/GHSA-h5fh-7hwr-97mw)

Published

May 8, 2026

Updated

Oct 28, 2026

Affected

1 pkg

Patched

1 / 1

Exploits

None indexed

Exploitation data as of Nov 8, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

## Exploitation Status

### No confirmed exploitation observed yet

-   CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-44298.

## EPSS Exploitation Probability

[via FIRST.org ↗](https://www.first.org/epss/)

0.3%probability of exploitation in next 30 days

Lower Risk0.00%

Lower risk than most CVEs20th percentile — riskier than 20% of all scored CVEsHighest risk

0.00%0.31%0.61%0.92%0.1%0.3%Jun 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from [FIRST.org EPSS](https://www.first.org/epss/).

## How urgent is this, really

## Where this sits among everything scored

## Real-World Exposure

1 pkg affected

🐘`kimai/kimai`

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

## Description

### Summary

Users with the role `System-Admin` (`ROLE_SYSTE_ADMIN`) and the permission `upload_invoice_template` can upload PDF invoice templates, which can call `pdfContext.setOption('associated_files', ...)` inside the sandboxed Twig render.

This is forwarded to mPDF's `SetAssociatedFiles()`, whose writer calls `file_get_contents($entry['path'])` during PDF output and embeds the bytes as a FlateDecode stream in the PDF. Any file readable by the PHP worker is returned to the attacker inside the rendered invoice.

### Root cause

1.  `src/Twig/SecurityPolicy/StrictPolicy.php:123-128` explicitly whitelists `PdfContext::setOption()`:
    
    ```
    if ($obj instanceof PdfContext) {
        if ($lcm !== 'setoption') { throw ...; }
        return;
    }
    ```
    
2.  `src/Pdf/MPdfConverter.php` keeps `associated_files` in the pass-through allowlist:
    
    ```
    $allowed = ['mode','format','default_font_size','default_font', ... , 'associated_files','additional_xmp_rdf'];
    ```
    
    and then forwards it to mPDF:
    
    ```
    if (array_key_exists('associated_files', $options) && is_array($options['associated_files'])) {
        $associatedFiles = $options['associated_files'];
        unset($options['associated_files']);
    }
    ...
    $mpdf->SetAssociatedFiles($associatedFiles);
    ```
    
3.  mPDF 8.3.1 `MetadataWriter::writeAssociatedFiles()` calls `file_get_contents`, which respects PHP stream wrappers:
    
    ```
    if (isset($file['path'])) {
        $fileContent = @file_get_contents($file['path']);
    }
    ...
    $filestream = gzcompress($fileContent);
    $this->writer->write('<</Type /EmbeddedFile');
    ```
    

The sandbox and the option allowlist were both written defensively (short whitelists, not blacklists), but neither side considered that `associated_files` is a PDF/A file-embedding feature whose `path` key is a sink.

### Fix

The implemented fix has two aspects:

1.  The `PdfContext` now works with a strict allow-list, that excludes `associated_files`
2.  The `MPdfConverter` now removes any `path` from the `$associatedFiles` array, which can still be used by plugins:

```
        if (\count($associatedFiles) > 0) {
            // remove "path" so mPDF will not use file_get_contents() on local files
            // callers must pre-read and pass the bytes via "content"
            $associatedFiles = array_map(static function ($entry): array {
                if (!\is_array($entry)) {
                    return [];
                }

                if (\array_key_exists('path', $entry)) {
                    unset($entry['path']);
                }

                return $entry;
            }, $associatedFiles);
            $mpdf->SetAssociatedFiles($associatedFiles);
        }

```

## Affected Packages

1 total 1 fixed

Ecosystem

Package

Vulnerable range

Fix

🐘Packagist

`kimai/kimai` 

≥ 2.32.0&&< 2.56

2.56`composer require kimai/kimai:^2.56`

## Affected Products

1 product · 1 configurations

Application

`kimai`kimai

≥ 2.32.0 && < 2.56.0

range

## Detection & mitigation playbook

Open-source dependency

1.  ### Detect
    
    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for kimai/kimai, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
    
2.  ### Fix
    
    Update kimai/kimai to 2.56 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-44298 is resolved across your whole dependency graph.
    
3.  ### Workarounds
    
    Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.
    

## Frequently Asked Questions

\## Summary Users with the role \`System-Admin\` (\`ROLE\_SYSTE\_ADMIN\`) and the permission \`upload\_invoice\_template\` can upload PDF invoice templates, which can call \`pdfContext.setOption('associated\_files', ...)\` inside the sandboxed Twig render. This is forwarded to mPDF's \`SetAssociatedFiles()\`, whose writer calls \`file\_get\_contents($entry\['path'\])\` during PDF output and embeds the bytes as a FlateDecode stream in the PDF. Any file readable by the PHP worker is returned to the attacker inside the rendered invoice. ## Root cause 1. \`src/Twig/SecurityPolicy/StrictPolicy.php:123-128\` explicitl

O3 Security · Impact-Aware SCA

### Is CVE-2026-44298 in your dependencies?

Find it across Packagist, including transitive dependencies.

[Scan my dependencies](/book-demo) [How O3 SCA works](/impact-aware-sca)