Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘 Packagist

GHSA-jv9x-w4gm-hwcm

LOW

GHSA-jv9x-w4gm-hwcm is a low-severity (CVSS 3.3) vulnerability in kimai/kimai. O3 Security confirms whether GHSA-jv9x-w4gm-hwcm is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Kimai has Missing Object-Level Authorization in the Team API

Also known asCVE-2026-41498
Published
Apr 24, 2026
Updated
May 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

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

The Team API endpoints use #[IsGranted('edit_team')] instead of #[IsGranted('edit', 'team')], causing Symfony TeamVoter to abstain from voting. This removes entity-level ownership checks on team operations, allowing any user with the edit_team permission to modify any team, not just teams they are authorized to manage.

Details

All 8 team association endpoints in src/API/TeamController.php (lines 177, 201, 229, 252, 275, 298, 321, 339) use #[IsGranted('edit_team')] with a single argument. The web controller at src/Controller/TeamController.php:118 correctly uses #[IsGranted('edit', 'team')] with two arguments, passing the $team parameter as the subject. When edit_team is passed as the attribute, TeamVoter::supportsAttribute() returns false because it only recognizes view, edit, and delete. The voter abstains entirely. Only RolePermissionVoter fires, which checks the role-level permission without any entity-level ownership validation.

PoC

Authenticate as a user with edit_team permission who is NOT a member of Team 1

curl -X POST https://TARGET/api/teams/1/members/2 \
  -H "Authorization: Bearer <API_TOKEN>" \
  -H "Content-Type: application/json"

Expected: 403 Forbidden (user is not ROLE_ADMIN/ROLE_SUPER_ADMIN, or member of Team 1)

Actual (pre-2.54.0): 200 OK, user added to Team 1

Impact

In default configuration, only ROLE_ADMIN and ROLE_SUPER_ADMIN have edit_team, and both roles already have irrevocable view_all_data access, making the missing check redundant. The vulnerability becomes exploitable if an administrator grants edit_team to a lower-privilege role (such as ROLE_TEAMLEAD) through the permissions UI. In that scenario, the lower-privilege user could modify any team's membership, customer assignments, project assignments, and activity assignments without being a member or teamlead of that team.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistkimai/kimaiall versions2.54.0

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. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update kimai/kimai to 2.54.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-jv9x-w4gm-hwcm is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-jv9x-w4gm-hwcm is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-jv9x-w4gm-hwcm. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary The Team API endpoints use #[IsGranted('edit_team')] instead of #[IsGranted('edit', 'team')], causing Symfony TeamVoter to abstain from voting. This removes entity-level ownership checks on team operations, allowing any user with the edit_team permission to modify any team, not just teams they are authorized to manage. ### Details All 8 team association endpoints in src/API/TeamController.php (lines 177, 201, 229, 252, 275, 298, 321, 339) use #[IsGranted('edit_team')] with a single argument. The web controller at src/Controller/TeamController.php:118 correctly uses #[IsGranted('ed
O3 Security · Impact-Aware SCA

Is GHSA-jv9x-w4gm-hwcm in your dependencies?

O3 detects GHSA-jv9x-w4gm-hwcm across Packagist dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.