Every CVE Search/ Get API key

CVE-2026-111919

Vikunja 0.22.0 before 2.7.0 Improper Access Revocation via Webhooks

7.1 High

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.36%Up 0.1 points since Oct 18, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.1

Vikunja 0.22.0 before 2.7.0 Improper Access Revocation via Webhooks

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Record
CVE-2026-111919
CVSS 4.0
7.1 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-613
Updated
2026-11-02
EUVDEUVD-2026-103287 7.1

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Record
EUVD-2026-103287
CVSS 4.0
7.1 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-276j-w3vx-r5jh 7.1

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows...

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Record
GHSA-276j-w3vx-r5jh
CVSS 4.0
7.1 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-613
Updated
2026-11-02
GitHub AdvisoriesGHSA-hjx8-qv73-f7cm 6.5

Vikunja: Webhooks and link shares survive every revocation path, so a removed collaborator keeps a live feed

Summary

A collaborator removed from a project keeps a live, automatic feed of that project's contents, because nothing on any revocation path deletes the webhook they created while they had access.

Vikunja already has a revocation-cleanup routine that deletes other derived rows for exactly this reason. Its set is {task_assignees, subscriptions}. webhooks and link_shares — the only two rows that carry a live channel into the project — are not in it, and the routine is wired to one of four revocation paths.

Details

pkg/models/teams.go:411 — cleanupTaskMembersAfterTeamRemoval, added in 9358954c9, whose commit message states the invariant: "cleanup team memberships, assignments and subscriptions when users lose access to a project".

		canRead, _, permErr := project.CanRead(s, &user.User{ID: memberID})
		...
		if !canRead {
			projectsToCleanup = append(projectsToCleanup, projectID)
		}
	...
		_, err = s.In("task_id", taskIDs).And("user_id = ?", memberID).
			Delete(&TaskAssginee{})
		_, err = s.In("entity_id", taskIDs).
			Where("entity_type = ? AND user_id = ?", SubscriptionEntityTask, memberID).
			Delete(&Subscription{})
	_, err = s.In("entity_id", projectsToCleanup).
		Where("entity_type = ? AND user_id = ?", SubscriptionEntityProject, memberID).
		Delete(&Subscription{})

So you have already decided that losing read access must delete rows the departing user left behind, and that the test is a live project.CanRead. The gap is which rows are in the set.

And there is a second level, which is the sharper one. That routine has exactly one caller:

pkg/models/listeners.go:1642    err = cleanupTaskMembersAfterTeamRemoval(s, event.Team.ID, event.Member.ID)

against four revocation paths:

pkg/models/project_team.go:151   TeamProject.Delete
pkg/models/project_users.go:141  ProjectUser.Delete      <- grep -c cleanup inside: 0
pkg/models/project_users.go:248  ProjectUser.Update      <- the downgrade path
pkg/models/team_members.go:91    TeamMember.Delete       <- the only one wired up

Removing a user directly from a project — the ordinary operation — dispatches nothing at all.

PoC

Released vikunja/vikunja:2.6.0 Docker image.

The harness was proved first by reproducing a known-fixed advisory: GHSA-qfwc refuses the read-only member and returns the hash to the owner. Every run carries its own negative control.

The strongest form is on the team-removal path, where your cleanup routine does fire:

== OWNER removes collab from the TEAM ==

-- did the cleanup routine run? --
  assignees now: []                            <- POSITIVE CONTROL: it ran
  collab direct read of task: HTTP 403         <- NEGATIVE CONTROL: access is gone

-- webhook still delivering? --
WEBHOOK RECEIVED  task_title='post-team-removal secret'
                  task_desc='cleanup ran, webhook did not'

-- link share still redeemable? --
[{"title":"post-team-removal secret","description":"cleanup ran, webhook did not"}]

The two controls are the argument: your own routine executed and removed the assignee rows, and the collaborator's direct read is refused with 403 — and the webhook created before removal still delivers the contents of a task created after it.

On the ProjectUser.Delete path the same thing happens with no cleanup running at all.

One lab accommodation, stated plainly: non-routable outbound IPs were enabled so a loopback sink was reachable. In a default deployment an attacker simply uses a public URL, so this changes nothing about reachability.

Impact

A former collaborator receives task titles and descriptions for the whole project, continuously, after their access has been revoked — including content created after revocation.

The honest counter-argument, which we would rather state than have you find. Both artefacts stay visible and auditable to the owner afterwards: GET /projects/{p}/webhooks still shows…

Record
GHSA-hjx8-qv73-f7cm
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-613, CWE-863
Updated
2026-11-02
NVD 7.1

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Record
CVE-2026-111919
CVSS 4.0
7.1 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-613
Updated
2026-11-02
OSV 7.1

Vikunja 0.22.0 before 2.7.0 Improper Access Revocation via Webhooks

Vikunja 0.22.0 before 2.7.0 contains an improper access revocation vulnerability that allows removed collaborators to keep receiving project data through webhooks they created. Former collaborators keep receiving task titles and descriptions through their webhook, including content created after their access was revoked.

Record
CVE-2026-111919
CVSS 4.0
7.1 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-613
Updated
2026-11-02
OSVGHSA-hjx8-qv73-f7cm 6.5

Vikunja: Webhooks and link shares survive every revocation path, so a removed collaborator keeps a live feed

Summary

A collaborator removed from a project keeps a live, automatic feed of that project's contents, because nothing on any revocation path deletes the webhook they created while they had access.

Vikunja already has a revocation-cleanup routine that deletes other derived rows for exactly this reason. Its set is {task_assignees, subscriptions}. webhooks and link_shares — the only two rows that carry a live channel into the project — are not in it, and the routine is wired to one of four revocation paths.

Details

pkg/models/teams.go:411 — cleanupTaskMembersAfterTeamRemoval, added in 9358954c9, whose commit message states the invariant: "cleanup team memberships, assignments and subscriptions when users lose access to a project".

		canRead, _, permErr := project.CanRead(s, &user.User{ID: memberID})
		...
		if !canRead {
			projectsToCleanup = append(projectsToCleanup, projectID)
		}
	...
		_, err = s.In("task_id", taskIDs).And("user_id = ?", memberID).
			Delete(&TaskAssginee{})
		_, err = s.In("entity_id", taskIDs).
			Where("entity_type = ? AND user_id = ?", SubscriptionEntityTask, memberID).
			Delete(&Subscription{})
	_, err = s.In("entity_id", projectsToCleanup).
		Where("entity_type = ? AND user_id = ?", SubscriptionEntityProject, memberID).
		Delete(&Subscription{})

So you have already decided that losing read access must delete rows the departing user left behind, and that the test is a live project.CanRead. The gap is which rows are in the set.

And there is a second level, which is the sharper one. That routine has exactly one caller:

pkg/models/listeners.go:1642    err = cleanupTaskMembersAfterTeamRemoval(s, event.Team.ID, event.Member.ID)

against four revocation paths:

pkg/models/project_team.go:151   TeamProject.Delete
pkg/models/project_users.go:141  ProjectUser.Delete      <- grep -c cleanup inside: 0
pkg/models/project_users.go:248  ProjectUser.Update      <- the downgrade path
pkg/models/team_members.go:91    TeamMember.Delete       <- the only one wired up

Removing a user directly from a project — the ordinary operation — dispatches nothing at all.

PoC

Released vikunja/vikunja:2.6.0 Docker image.

The harness was proved first by reproducing a known-fixed advisory: GHSA-qfwc refuses the read-only member and returns the hash to the owner. Every run carries its own negative control.

The strongest form is on the team-removal path, where your cleanup routine does fire:

== OWNER removes collab from the TEAM ==

-- did the cleanup routine run? --
  assignees now: []                            <- POSITIVE CONTROL: it ran
  collab direct read of task: HTTP 403         <- NEGATIVE CONTROL: access is gone

-- webhook still delivering? --
WEBHOOK RECEIVED  task_title='post-team-removal secret'
                  task_desc='cleanup ran, webhook did not'

-- link share still redeemable? --
[{"title":"post-team-removal secret","description":"cleanup ran, webhook did not"}]

The two controls are the argument: your own routine executed and removed the assignee rows, and the collaborator's direct read is refused with 403 — and the webhook created before removal still delivers the contents of a task created after it.

On the ProjectUser.Delete path the same thing happens with no cleanup running at all.

One lab accommodation, stated plainly: non-routable outbound IPs were enabled so a loopback sink was reachable. In a default deployment an attacker simply uses a public URL, so this changes nothing about reachability.

Impact

A former collaborator receives task titles and descriptions for the whole project, continuously, after their access has been revoked — including content created after revocation.

The honest counter-argument, which we would rather state than have you find. Both artefacts stay visible and auditable to the owner afterwards: GET /projects/{p}/webhooks still shows…

Record
GHSA-hjx8-qv73-f7cm
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-613, CWE-863
Updated
2026-11-02
OSVGO-2026-6733 No score

Vikunja: Webhooks and link shares survive every revocation path, so a removed collaborator keeps a live feed in code.vikunja.io/api

Vikunja: Webhooks and link shares survive every revocation path, so a removed collaborator keeps a live feed in code.vikunja.io/api

Record
GO-2026-6733
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
code.vikunja.io/api
Go
0.22.0 to 2.6.0 None known
code.vikunja.io/api
Go
0.22.0 and later None known

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-111919 is a high vulnerability (CVSS 7.1) in Go-vikunja Vikunja, published October 9, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.36%, the 29th percentile. No source names a fixed version.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open