---
id: GHSA-m492-gv72-xvxj
title: Kimai Password Reset Link Remains Valid After Password Change
summary: Kimai Password Reset Link Remains Valid After Password Change
severity: low
cwe:
  - CWE-640
vendor: kimai
product: kimai/kimai
ecosystem: composer
affected:
  - kimai/kimai <= 2.57.0
patched:
  - kimai/kimai 2.58.0
published: '2026-07-01'
updated: '2026-07-01'
source: GHSA
sourceUrl: 'https://github.com/advisories/GHSA-m492-gv72-xvxj'
references:
  - url: 'https://github.com/kimai/kimai/security/advisories/GHSA-m492-gv72-xvxj'
  - url: 'https://www.kimai.org/en/security/ghsa-m492-gv72-xvxj'
  - url: 'https://github.com/advisories/GHSA-m492-gv72-xvxj'
tags:
  - ghsa
  - composer
ingestedAt: '2026-07-01T20:16:35.290Z'
---

## Overview

### Summary

The LoginLink signature used for password reset URLs covers only the user's `id` — it does not include the password hash. After a user clicks a reset link and successfully changes their password, the same link remains valid for up to 2 additional uses within a 1-hour window. Anyone who intercepts or caches the original link can log in as the user even after the password has been changed.

### Details

`config/packages/security.yaml:73-78` configures the login link:

```yaml
login_link:
    check_route: link_login_check
    signature_properties: ['id']
    lifetime: 900
    max_uses: 3
```

The HMAC signature covers only `id`, not `password`, `username`, or `email`. The effective lifetime for password reset links is extended to 3600 seconds by `PasswordResetController.php:106-119` via `getPasswordResetRetryLifetime()`.

After the first successful use (where the user sets a new password), the `__pw_reset__` session flag is cleared by `WizardController.php:105`. Subsequent uses of the same link bypass the forced-password-reset wizard and grant a normal authenticated session.

Symfony's `LoginLinkHandler::consumeLoginLink` decrements a per-link counter but allows up to 3 total uses. Re-issuing a new link does not invalidate the old one.

The same vulnerability affects `UserLoginLinkCommand.php:77`, which generates admin-on-demand login links with the same signature scheme.

### PoC

**Step 1 — Generate a password reset link:**

```bash
docker exec <kimai_container> bin/console kimai:user:login-link <username>
```

**Step 2 — Use the link to log in and change the password.**

**Step 3 — Open the same link in a different browser or incognito session.**

The link logs the attacker in as a fully authenticated user, despite the password having been changed in Step 2.

**Step 4 — The link works a third time (3 total uses within 1 hour).**

### Impact

A password reset link that leaks through any of the following channels remains a valid authentication credential even after the legitimate user has changed their password: corporate mail-relay scanners that pre-click links (Microsoft Defender ATP, Mimecast, Barracuda), shared inboxes, browser history sync across devices, HTTP referrer headers, or proxy/WAF logs. The user believes they have secured their account by setting a new password, but the leaked link still grants full access for up to 2 additional uses within the hour.

# Solution

Login links now also use the `password` hash for generating the signature, which will immediately expire the link after the user changed the password.

Read <https://www.kimai.org/en/security/ghsa-m492-gv72-xvxj> for more information.

## Affected packages

- `kimai/kimai <= 2.57.0`

## Remediation

Upgrade to a patched release:

- `kimai/kimai 2.58.0`
