VYPR
Moderate severityNVD Advisory· Published Dec 9, 2021· Updated Aug 3, 2024

Cross-Site Request Forgery (CSRF) in kevinpapst/kimai2

CVE-2021-4033

Description

Kimai2 is vulnerable to Cross-Site Request Forgery (CSRF), allowing attackers to perform unauthorized actions on behalf of authenticated users.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Kimai2 is vulnerable to Cross-Site Request Forgery (CSRF), allowing attackers to perform unauthorized actions on behalf of authenticated users.

Vulnerability

Kimai2 is vulnerable to Cross-Site Request Forgery (CSRF) attacks. This vulnerability affects versions prior to the commit that introduced proper CSRF token handling for invoice creation and search operations [1][3]. The application did not validate or refresh CSRF tokens on certain endpoints, leaving them open to forged requests.

Exploitation

An attacker can exploit this by crafting a malicious link or webpage that, when visited by an authenticated Kimai2 user, triggers unauthorized requests to the application. The attacker does not need to be authenticated, but the victim must have an active session. The attack can be performed by tricking the user into clicking a link or visiting a compromised site that automatically submits a form or sends a request to the vulnerable endpoints [3][4].

Impact

Successful exploitation allows an attacker to perform actions on behalf of the victim, such as creating invoices or modifying search parameters, leading to unauthorized changes and potential data integrity issues. The attacker can trick the user into performing actions without their consent [1].

Mitigation

The vulnerability is fixed in commit 1da26e04 [3]. Users should update to the latest version of Kimai2, which includes the CSRF token fixes. If immediate update is not possible, ensure that users are cautious of clicking on untrusted links or visiting suspicious sites while logged into the application [4].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
kevinpapst/kimai2Packagist
< 1.16.71.16.7

Affected products

2

Patches

1
1da26e041df6

fix invoice create and search (#2990)

https://github.com/kevinpapst/kimai2Kevin PapstDec 4, 2021via ghsa
3 files changed · +17 4
  • src/Controller/AbstractController.php+2 0 modified
    @@ -218,6 +218,8 @@ protected function handleSearch(FormInterface $form, Request $request): bool
                 }
             }
     
    +        $request->query->remove('_token');
    +
             if ($request->query->has('resetSearchFilter')) {
                 $data->resetFilter();
                 $this->removeLastSearch($data);
    
  • src/Controller/InvoiceController.php+10 3 modified
    @@ -66,7 +66,7 @@ public function __construct(ServiceInvoice $service, InvoiceTemplateRepository $
          * @Route(path="/", name="invoice", methods={"GET", "POST"})
          * @Security("is_granted('view_invoice')")
          */
    -    public function indexAction(Request $request, SystemConfiguration $configuration): Response
    +    public function indexAction(Request $request, SystemConfiguration $configuration, CsrfTokenManagerInterface $csrfTokenManager): Response
         {
             if (!$this->templateRepository->hasTemplate()) {
                 if ($this->isGranted('manage_invoice_template')) {
    @@ -100,6 +100,8 @@ public function indexAction(Request $request, SystemConfiguration $configuration
                         return $this->redirectToRoute('invoice');
                     }
     
    +                $csrfTokenManager->refreshToken('invoice.create');
    +
                     try {
                         return $this->renderInvoice($query, $request);
                     } catch (Exception $ex) {
    @@ -148,6 +150,7 @@ public function previewAction(Customer $customer, Request $request, SystemConfig
     
             if ($form->isValid()) {
                 try {
    +                $query->setCustomers([$customer]);
                     $model = $this->service->createModel($query);
     
                     return $this->service->renderInvoiceWithModel($model, $this->dispatcher);
    @@ -167,7 +170,7 @@ public function previewAction(Customer $customer, Request $request, SystemConfig
          * @Security("is_granted('access', customer)")
          * @Security("is_granted('create_invoice')")
          */
    -    public function createInvoiceAction(Customer $customer, InvoiceTemplate $template, Request $request, SystemConfiguration $configuration): Response
    +    public function createInvoiceAction(Customer $customer, InvoiceTemplate $template, Request $request, SystemConfiguration $configuration, CsrfTokenManagerInterface $csrfTokenManager): Response
         {
             if (!$this->templateRepository->hasTemplate()) {
                 return $this->redirectToRoute('invoice');
    @@ -185,9 +188,13 @@ public function createInvoiceAction(Customer $customer, InvoiceTemplate $templat
                 return $this->redirectToRoute('invoice');
             }
     
    +        $csrfTokenManager->refreshToken('invoice.create');
    +
             $query = $this->getDefaultQuery();
             $form = $this->getToolbarForm($query, $configuration->find('invoice.simple_form'));
    -        $form->submit($request->query->all(), false);
    +        if ($this->handleSearch($form, $request)) {
    +            return $this->redirectToRoute('invoice');
    +        }
     
             if ($form->isValid()) {
                 $query->setTemplate($template);
    
  • src/Form/Extension/SelectWithApiDataExtension.php+5 1 modified
    @@ -75,8 +75,12 @@ public function buildView(FormView $view, FormInterface $form, array $options)
             } while (($parent = $parent->getParent()) !== null);
     
             $formPrefix = implode('_', array_reverse($formPrefixes));
    +        $formField = $apiData['select'];
     
    -        $formField = $formPrefix . '_' . $apiData['select'];
    +        // forms with prefix (like toolbar & search) would result in a wrong field name "_foo" instead of "foo"
    +        if ($formPrefix !== '') {
    +            $formField = $formPrefix . '_' . $apiData['select'];
    +        }
     
             $view->vars['attr'] = array_merge($view->vars['attr'], [
                 'data-form-prefix' => $formPrefix,
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.