Skip to main content
Vulnerability Database/CVE-2026-111922

CVE-2026-111922: Vikunja Auth Bypass Vulnerability

CVE-2026-111922 is an authentication bypass flaw in Vikunja that allows attackers to hijack user sessions through permissive CORS settings. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-111922 Overview

CVE-2026-111922 affects Vikunja, an open-source task management application, in versions from 2.2.0 before 2.7.0. The vulnerability stems from a permissive Cross-Origin Resource Sharing (CORS) configuration that trusts every localhost and 127.0.0.1 origin on any port with credentials. This trust persists even when service.publicurl is explicitly configured. An attacker who controls any page served from a localhost port can issue a credentialed request to the token refresh endpoint. The response leaks the bearer JSON Web Token (JWT), allowing full account takeover of the logged-in user. The flaw is tracked as a misconfigured access control weakness [CWE-942].

Critical Impact

Attackers controlling any localhost-origin page can steal bearer JWTs via the token refresh endpoint and hijack authenticated Vikunja sessions.

Affected Products

  • Vikunja 2.2.0 through 2.6.x
  • Self-hosted Vikunja deployments with default CORS behavior
  • Vikunja instances where service.publicurl is set but localhost origins remain trusted

Discovery Timeline

  • 2026-10-17 - CVE-2026-111922 published to the National Vulnerability Database
  • 2026-10-19 - Last updated in NVD database

Technical Details for CVE-2026-111922

Vulnerability Analysis

Vikunja's HTTP layer applies a CORS allow-list that unconditionally approves any origin matching http://localhost:* or http://127.0.0.1:*. The server also returns Access-Control-Allow-Credentials: true for these origins. This combination violates the browser's default same-origin protections for authenticated requests. The impact is account takeover because the token refresh endpoint returns a fresh bearer JWT in the response body. Any JavaScript running on a trusted localhost origin can read that response and extract the token.

Local web services are common on developer workstations and end-user machines. Examples include development servers, IDE helpers, media servers, and desktop applications that bind an HTTP listener. An attacker who can place content on any such service, or who runs a malicious port-bound tool, inherits the trust granted to localhost by Vikunja.

Root Cause

The root cause is an overly broad allow-list in the CORS middleware. The configuration treats loopback origins as inherently trusted and ignores the operator-provided service.publicurl. Credentialed cross-origin requests are therefore permitted from any port, bypassing the isolation that publicurl is intended to enforce.

Attack Vector

Exploitation requires the victim to visit or interact with attacker-controlled content hosted on a localhost port while authenticated to a vulnerable Vikunja instance. The attacker's page issues a fetch call to the Vikunja token refresh endpoint with credentials: 'include'. Because the CORS policy accepts the origin and allows credentials, the browser forwards the Vikunja session cookie. The server returns a new JWT, which the attacker's script reads from the response and exfiltrates. The attacker then replays the JWT to act as the victim.

For technical details, see the GitHub Security Advisory GHSA-m687-p538-r5hp and the VulnCheck Advisory for Vikunja CORS Policy.

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-111922

Indicators of Compromise

  • Requests to the Vikunja token refresh endpoint carrying an Origin header of http://localhost:<port> or http://127.0.0.1:<port> that does not match the configured service.publicurl.
  • Successful 200 OK responses from the refresh endpoint followed by immediate use of the issued JWT from a different IP address or user agent.
  • Unexpected OPTIONS preflight requests to Vikunja API routes originating from loopback-bound browsers.

Detection Strategies

  • Enable verbose access logging on the Vikunja reverse proxy and alert on Origin headers that do not match the production hostname.
  • Correlate JWT issuance events with subsequent authenticated API calls to identify tokens used from new network locations within a short window.
  • Review browser developer-tool traces or endpoint network telemetry for cross-origin fetch calls to Vikunja from non-Vikunja applications.

Monitoring Recommendations

  • Centralize Vikunja and reverse-proxy logs in a security data lake and build detections for anomalous Origin values on /api/v1/auth/* routes.
  • Track per-user JWT issuance rates and alert on bursts that may indicate automated token theft.
  • Monitor developer workstations for unauthorized local HTTP listeners that could serve as pivot origins.

How to Mitigate CVE-2026-111922

Immediate Actions Required

  • Upgrade Vikunja to version 2.7.0 or later on all self-hosted instances.
  • Invalidate existing sessions and force reauthentication after upgrading to retire any JWTs that may have been exposed.
  • Audit reverse-proxy and application logs for prior requests with loopback Origin headers that do not match service.publicurl.

Patch Information

The maintainers resolved the issue in Vikunja 2.7.0 by tightening the CORS allow-list so that only the origin configured in service.publicurl is permitted for credentialed requests. Review the GitHub Security Advisory GHSA-m687-p538-r5hp for the fix commit and release notes.

Workarounds

  • Place Vikunja behind a reverse proxy, such as nginx or Caddy, that strips or validates the Origin header and rejects requests whose origin does not match the deployed public URL.
  • Restrict network access to the Vikunja listener so that only trusted hostnames can reach the API, limiting exposure from local attacker-controlled origins.
  • Instruct users to log out of Vikunja when running untrusted local development tools until the instance is upgraded.
bash
# Example nginx snippet to enforce an allowed Origin before proxying to Vikunja
map $http_origin $allowed_origin {
    default                       "";
    "https://vikunja.example.com" $http_origin;
}

server {
    listen 443 ssl http2;
    server_name vikunja.example.com;

    location / {
        if ($http_origin != "" ) {
            set $test "origin";
        }
        if ($allowed_origin = "") {
            return 403;
        }
        proxy_set_header Host $host;
        proxy_set_header Origin $allowed_origin;
        proxy_pass http://127.0.0.1:3456;
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.