CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-28268

Vikunja Password Reset Mechanism Logic Errors Allowing Persistent Account Takeover

Alon Barad
Alon Barad
Software Engineer

Feb 28, 2026·6 min read·48 visits

Executive Summary (TL;DR)

Vikunja versions < 2.1.0 fail to delete password reset tokens after use and fail to clean up expired tokens due to a logic bug in the cron job. This allows valid tokens to be reused indefinitely for account takeover. Fixed in v2.1.0.

A critical authentication bypass vulnerability exists in Vikunja, an open-source task management platform, affecting versions prior to 2.1.0. The vulnerability stems from two concurrent logic errors in the password reset workflow: a failure to invalidate reset tokens upon successful use and a malformed background cleanup process that failed to purge expired tokens. These flaws allow an attacker who obtains a password reset token—via interception, logs, or history—to reuse it indefinitely to reset the target user's password, facilitating persistent account takeover. The issue is addressed in version 2.1.0 by correcting the token deletion logic and fixing the expiration query.

Vulnerability Overview

Vikunja is a self-hosted, open-source task management platform written in Go. Authentication mechanisms in such systems are critical for maintaining tenant isolation and data integrity. CVE-2026-28268 identifies a catastrophic failure in the application's password recovery workflow, specifically within the pkg/user module.

The vulnerability is classified as a business logic error involving incomplete cleanup (CWE-459) and weak password recovery mechanisms (CWE-640). Normally, a password reset token functions as a one-time nonce: once a user successfully resets their password, the token must be invalidated immediately to prevent replay attacks. Additionally, tokens should have a short lifespan enforced by a background process.

In affected versions of Vikunja, neither of these safety mechanisms functioned correctly. The application failed to delete the specific password reset token after use, and the background cleanup job contained an inverted logic operator that preserved expired tokens indefinitely. Consequently, a single leaked token grants an attacker a permanent backdoor into the victim's account, bypassing all subsequent authentication checks.

Root Cause Analysis

The vulnerability is the result of two distinct implementation errors in the Go backend that compounded to create a persistent threat.

1. Incorrect Token Invalidation Target The primary flaw resides in pkg/user/user_password_reset.go. The ResetPassword function is responsible for verifying the token, updating the user's password, and performing cleanup. However, the cleanup call was misconfigured. Instead of requesting the deletion of TokenPasswordReset type tokens, the code instructed the system to delete TokenEmailConfirm tokens. This logic error meant that while the password was successfully changed, the reset token remained active in the database, marked as valid.

2. Inverted Expiration Logic A secondary but equally critical flaw existed in the background cron job responsible for database hygiene, located in pkg/user/token.go. The SQL query intended to delete expired tokens used an inverted comparison operator (> instead of <). Instead of deleting tokens where the expiration date was in the past, the system attempted to delete tokens where the expiration date was in the future. This effectively preserved all old, expired tokens while potentially interfering with valid, newly created tokens. This ensured that even if a token 'expired' logically according to its timestamp, it was never physically removed from the database, allowing the validation logic (which presumably checked existence first) to potentially accept it depending on how strict the read-time expiration check was implemented.

Code Analysis

The remediation of this vulnerability provides a clear view of the logic error. The fix was applied in pkg/user/user_password_reset.go within the ResetPassword function. The code below illustrates the critical difference between the vulnerable and patched states.

Vulnerable Code (Before Patch): In the vulnerable version, the developer inadvertently passed the constant TokenEmailConfirm to the removal function. This constant maps to a different integer value than the password reset token type, leaving the actual reset token untouched in the persistence layer.

// pkg/user/user_password_reset.go
 
// ... password update logic ...
 
// CRITICAL BUG: Removes email confirmation tokens instead of reset tokens
err = removeTokens(s, user, TokenEmailConfirm)
if err != nil {
    return err
}

Patched Code (Version 2.1.0): The fix involves a one-line change to target the correct token type constant (TokenPasswordReset). This ensures that once the ResetPassword function completes, the token used to authorize that request is permanently destroyed.

// pkg/user/user_password_reset.go
 
// ... password update logic ...
 
// FIX: Correctly targets the password reset token type for deletion
err = removeTokens(s, user, TokenPasswordReset)
if err != nil {
    return err
}

By correctly identifying the token type, the system enforces the one-time-use policy required for secure authentication workflows.

Exploitation Scenarios

The exploitation of CVE-2026-28268 is trivial once a token is acquired, as it requires no special tooling or race conditions. The difficulty lies solely in the initial acquisition of the token.

Token Leakage Channels Since the token is part of a URL, it is susceptible to leakage via several standard channels:

  • Browser History: If an attacker has physical access to a victim's machine or synced browser data, they can retrieve the reset URL.
  • Proxy/Server Logs: In corporate environments, full URLs including query parameters are often logged by intermediate proxies or WAFs.
  • Phishing: An attacker could trigger a reset request and deceive the user into forwarding the link (e.g., claiming it's a "security verification" link).

Attack Lifecycle

  1. Acquisition: The attacker obtains the token vikunja.example.com/reset/TOKEN_STRING.
  2. Validation: The attacker sends a POST request to the API endpoint with the token. Because the token was never deleted, the server accepts it.
  3. Takeover: The attacker sets a new password. The victim is locked out.
  4. Persistence: Even if the victim regains control via admin intervention, if the specific vulnerable token is not manually purged from the database, the attacker can re-use the same token immediately to reset the password again, maintaining a persistent hold on the account.

Impact Assessment

The impact of this vulnerability is rated as Critical (CVSS 9.8) due to the complete bypass of authentication controls it affords.

Confidentiality Impact (High): An attacker can access all tasks, projects, and private notes stored within the Vikunja instance. In a business context, this could include proprietary roadmaps, sensitive client data, or internal operational details.

Integrity Impact (High): The attacker has full write access to the user's account. They can modify tasks, delete projects, or inject malicious content into shared workspaces, potentially affecting other users or the organization's workflow.

Availability Impact (High): The attacker can change the password and change the associated email address (if functionality permits), permanently locking the legitimate user out of their account. In a self-hosted instance without active administration, this results in a permanent denial of service for that user identity.

Mitigation & Remediation

The only effective remediation is to upgrade the Vikunja instance to a version that includes the patch.

Immediate Action: Upgrade to Vikunja v2.1.0 or later. This release includes the fix for the removeTokens call and corrects the background cron job logic.

Post-Upgrade Cleanup: Simply upgrading the code prevents future tokens from persisting, but it may not automatically clean up the backlog of existing, valid tokens left behind by the bug. Administrators should perform a database cleanup.

Database Cleanup Command (SQL): Execute a query against the Vikunja database to remove old reset tokens. Ensure you backup the database before running delete operations.

-- Example for PostgreSQL/MySQL
-- Delete password reset tokens (type ID usually 1 or 2, verify in code)
-- that are older than 24 hours.
DELETE FROM user_tokens 
WHERE token_type = 1  -- Assuming 1 is TokenPasswordReset
AND created_at < NOW() - INTERVAL '24 HOURS';

Verification: After patching, administrators should verify the fix by generating a password reset token, using it to change a password, and then inspecting the database to confirm the token row has been removed.

Official Patches

VikunjaCommit fixing the token deletion logic

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Affected Systems

Vikunja (Self-Hosted)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Vikunja
go-vikunja
< 2.1.02.1.0
AttributeDetail
CWE IDCWE-459
Attack VectorNetwork
CVSS Score9.8
Remediation LevelOfficial Fix
Exploit StatusPoc Available
Report ConfidenceConfirmed

MITRE ATT&CK Mapping

T1552Unsecured Credentials
Credential Access
T1078Valid Accounts
Defense Evasion
CWE-459
Incomplete Cleanup

The software does not properly clean up sensitive data, such as a password reset token, after it has been used or has expired.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory describing the token reuse mechanism.

Vulnerability Timeline

Vulnerability introduced in version 0.18.0
2021-09-05
Vulnerability disclosed and patched in version 2.1.0
2026-02-27
CVE-2026-28268 published
2026-02-27

References & Sources

  • [1]GHSA-rfjg-6m84-crj2
  • [2]Vikunja v2.1.0 Release Notes

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•13 minutes ago•GHSA-WQVQ-JVPQ-H66F
5.4

GHSA-WQVQ-JVPQ-H66F: Security Control Bypass in Nodemailer via Transport Serialization

Nodemailer prior to version 8.0.9 contains a security control bypass vulnerability. Transport-level configuration parameters designed to restrict local file system access and remote URL requests are not propagated to all content-resolution execution paths. This failure allows unauthorized local file inclusion and server-side request forgery when the application utilizes specific transports or processing flags.

Alon Barad
Alon Barad
0 views•6 min read
•41 minutes ago•GHSA-268H-HP4C-CRQ3
5.4

GHSA-268h-hp4c-crq3: CRLF Injection via List-* Header Comments in Nodemailer

GHSA-268h-hp4c-crq3 is a Carriage Return Line Feed (CRLF) injection vulnerability in the Nodemailer npm package affecting versions up to and including 8.0.8. The library allows arbitrary email header injection when parsing user-controlled comments within list headers (such as List-Unsubscribe or List-ID). This occurs because list headers bypass standard validation by utilizing an internal 'prepared' flag, causing unsanitized newlines to be emitted directly into the outgoing RFC822 mail stream. This exploit allows remote attackers to inject custom, unauthorized mail headers, disrupting signature checks, bypassing filters, or spoofing parameters.

Alon Barad
Alon Barad
0 views•8 min read
•about 1 hour ago•CVE-2026-48524
3.7

CVE-2026-48524: Remote Cache Eviction and Authentication Denial of Service in PyJWT

A logic flaw in PyJWT's PyJWKClient class allows remote unauthenticated attackers to trigger a complete authentication outage. By transmitting a volume of JWTs containing randomized, non-existent Key ID (kid) values, attackers force synchronous outbound JWKS resolution queries. When these queries fail or time out, a defect in the error cleanup code overwrites the local cache of valid signing keys with None, causing a denial of service.

Alon Barad
Alon Barad
1 views•8 min read
•about 2 hours ago•CVE-2026-49982
8.2

CVE-2026-49982: Path Traversal Bypass via Type Confusion in node-tmp

A high-severity type-confusion path traversal vulnerability (CVE-2026-49982 / GHSA-7c78-jf6q-g5cm) exists in the node-tmp package version 0.2.6. The vulnerability allows remote attackers to bypass path validation checks by passing non-string data types such as Arrays or duck-typed Objects into options like prefix, postfix, or template. Because the library relies on the .includes() method without verifying the input type, standard array checks evaluate differently than string checks. Downstream string coercion subsequently restores the traversal sequence, allowing files and directories to be created outside the designated temporary directory root. This can result in arbitrary file writes and potential local file execution depending on application context.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 4 hours ago•CVE-2026-47347
5.3

CVE-2026-47347: Open Redirect Vulnerability in TYPO3 CMS GeneralUtility::sanitizeLocalUrl

CVE-2026-47347 is an open redirect vulnerability affecting multiple TYPO3 CMS versions. The issue resides in GeneralUtility::sanitizeLocalUrl, where an insufficient blocklist validation implementation fails to prevent browsers from normalizing malformed relative paths into external protocol-relative redirections. Attackers can exploit this to conduct phishing, session hijacking, or credential harvesting campaigns.

Alon Barad
Alon Barad
2 views•7 min read
•about 4 hours ago•CVE-2026-47349
5.3

CVE-2026-47349: Missing Authorization in TYPO3 CMS DataHandler Record Restoration

An authenticated backend user with access to the Recycler module in TYPO3 CMS can bypass write restrictions and restore soft-deleted records on pages or database tables they are not authorized to modify. This vulnerability resides in the core DataHandler class due to missing permission checks during 'undelete' operations.

Alon Barad
Alon Barad
2 views•7 min read