🛡️ CVE-2026-52825 — kimai

⚪ Unknown ✅ No Known Exploit CWE-285 OSV
N/A
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Kimai has Improper Authorization in Team Member and Team Activity Assignment APIs Which Allows Expansion of Team Scope Beyond Authorized Visibility

Summary

Kimai contains an authenticated improper authorization vulnerability in Team-related assignment APIs. A Teamlead who can edit their own team can use backend API endpoints to add users or activities that fall outside their intended visible or manageable scope, even when the frontend correctly hides those targets.

This affects both team member assignment and team activity assignment. The issue is caused by treating "may edit this team" as equivalent to "may attach any referenced object to this team", without performing a second authorization check on the target user or activity.

Details

The issue affects at least the following API routes:

  • POST /api/teams/{id}/members/{userId}
  • POST /api/teams/{id}/activities/{activityId}

In both cases, the backend checks whether the caller may edit the Team, but it does not verify whether the referenced User or Activity falls inside the caller's allowed management scope.

For team member assignment, the frontend form correctly limits the visible user choices. In src/Form/TeamEditForm.php, the team edit form uses UserType:

```php

$builder->add('users', UserType::class, [

'label' => 'add_user.label',

'help' => 'team.add_user.help',

'mapped' => false,

'multiple' => false,

'expanded' => false,

'required' => false,

'ignore_users' => $team !== null ? $team->getUsers() : []

]);

```

In src/Form/Type/UserType.php, the user selector is built from UserRepository::getQueryBuilderForFormType():

```php

$query = new UserFormTypeQuery();

$query->setUser($options['user']);

$qb = $this->userRepository->getQueryBuilderForFormType($query);

$users = $qb->getQuery()->getResult();

```

And in src/Repository/UserRepository.php, Teamlead-visible candidates are limited to team members from teams they lead:

```php

if (null !== $user && $user->isTeamlead()) {

$userIds = [];

foreach ($user->getTeams() as $team) {

if ($team->isTeamlead($user)) {

foreach ($team->getUsers() as $teamMember) {

$userIds[] = $teamMember->getId();

}

}

}

$userIds = array_unique($userIds);

$qb->setParameter('teamMember', $userIds);

$or->add($qb->expr()->in('u.id', ':teamMember'));

}

```

However, the actual member-assignment API does not reuse that restriction. In src/API/TeamController.php:

```php

#[IsGranted('edit', 'team')]

#[Route(methods: ['POST'], path: '/{id}/members/{userId}', name: 'post_team_member', requirements: ['id' => '\d+', 'userId' => '\d+'])]

public function postMemberAction(Team $team, #[MapEntity(mapping: ['userId' => 'id'])] User $member): Response

{

if ($member->isInTeam($team)) {

throw new BadRequestHttpException('User is already member of the team');

}

$team->addUser($member);

$this->teamService->saveTeam($team);

}

```

For activity assignment, the same pattern appears. In src/API/TeamController.php:

```php

#[IsGranted('edit', 'team')]

#[Route(methods: ['POST'], path: '/{id}/activities/{activityId}', name: 'post_team_activity', requirements: ['id' => '\d+', 'activityId' => '\d+'])]

public function postActivityAction(Team $team, #[MapEntity(mapping: ['activityId' => 'id'])] Activity $activity, ActivityRepository $activityRepository): Response

{

if ($team->hasActivity($activity)) {

throw new BadRequestHttpException('Team has already access to activity');

}

$team->addActivity($activity);

$activityRepository->saveActivity($activity);

}

```

The Team voter only checks whether the current user may edit that team, not whether the referenced object is within the Teamlead's legitimate scope. In src/Voter/TeamVoter.php:

```php

if (!$user->isAdmin() && !$user->isSuperAdmin() && !$user->isTeamleadOf($subject)) {

return false;

}

return $this->permissionManager->hasRolePermission($user, $attribute . '_team');

```

For activities, this is especially risky because later authorization logic may trust the team assignment that was just written. In src/Security/RolePermissionManager.php:

```php

public function checkTeamAccessActivity(Activity $activity, User $user): bool

{

if ($activity->getProject() !== null && !$this->checkTeamAccessProject($activity->getProject(), $user)) {

return false;

}

return $this->checkTeamAccess($activity->getTeams(), $user);

}

```

So once a Teamlead is able to write a new team/activity relation, later access-control decisions may treat that relation as legitimate input.

*A PoC was provided, but removed for security reasons.*

Impact

This vulnerability allows a Teamlead to use their own editable team as an expansion container for objects that should remain outside their authorized scope. In the validated member-assignment case, the attacker can forcibly add users who are not supposed to be manageable thr

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. Rated impact: confidentiality none, integrity low, availability none.

Weakness class

CVE-2026-52825 is classified as CWE-285: Improper Authorization. A request is carried out without confirming that the caller is permitted to perform it on that specific resource.

Affected software

CVE-2026-52825 is recorded against 1 package.

  • kimai/kimai (fixed in 2.58.0)

Timeline and source

Published on 14 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Web)
github.com (Package)

Details

Severity Unknown
CVSS Score N/A
CVSS Vector CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
CWE CWE-285
Public Exploit ✅ No
Source OSV
Published 2026-07-14
Updated 2026-08-12
Modified 2026-07-14
Fix URL N/A

Affected Packages

Software From version Fixed in
kimai/kimai 2.58.0

Similar Threats

Free Vulnerability Check

Is your site affected by CVE-2026-52825?

BotEraser helps you identify potentially vulnerable plugins and themes by checking your installation against CVE-2026-52825 and other known CVE records.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026