GHSA-m687-p538-r5hp: Permissive Localhost CORS Policy Leads to Account Takeover in Vikunja

Vulnerability ID: GHSA-M687-P538-R5HP
CVSS Score: 7.2
Published: 2026-10-09

Vikunja versions 2.2.0 through 2.6.0 contain a Cross-Origin Resource Sharing (CORS) misconfiguration flaw in code.vikunja.io/api. Default configurations permit wildcard origins for localhost (http://127.0.0.1:* and http://localhost:*) with credentialed requests (Access-Control-Allow-Credentials: true). Because configuring a public service URL appends to this default list rather than overriding it, production environments inadvertently trust all local origins. A local page or application on a user's machine can execute a credentialed cross-origin request to the token refresh endpoint, extract the returned JWT access token, and achieve complete account takeover.

TL;DR

A CORS misconfiguration in Vikunja appends configured public URLs to default localhost wildcard origins instead of replacing them. Paired with credentialed CORS and an unauthenticated token refresh endpoint, a script running on any local port can fetch a valid bearer JWT for an authenticated user.

⚠️ Exploit Status: POC

Technical Details

  • CWE ID: CWE-942
  • CVSS Score: 7.2 (High)
  • CVSS Vector: CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
  • Vulnerability Type: Permissive Cross-Domain Security Policy
  • Affected Package: code.vikunja.io/api
  • Exploit Status: Proof of Concept Available
  • CISA KEV Status: Not Listed

Affected Systems

  • Vikunja API (code.vikunja.io/api) versions >= 2.2.0, <= 2.6.0
  • code.vikunja.io/api: >= 2.2.0, <= 2.6.0 (Fixed in: post-2.6.0)

Exploit Details

  • GitHub Security Advisory: Proof of Concept code demonstrating fetch execution from localhost to retrieve bearer access tokens via token refresh endpoint.

Mitigation Strategies

  • Upgrade code.vikunja.io/api to patched post-2.6.0 versions where explicit CORS origin definitions overwrite default localhost wildcard settings.
  • Configure reverse proxies to drop or deny HTTP requests carrying localhost or 127.0.0.1 Origin headers bound for production API endpoints.
  • Avoid enabling credentialed CORS (Access-Control-Allow-Credentials) in conjunction with dynamic origin matching or origin wildcards.

Remediation Steps:

  1. Identify all running Vikunja instances and check current version (>= 2.2.0, <= 2.6.0).
  2. Update the Vikunja binary or container image to a fixed release post version 2.6.0.
  3. Review cors.origins in config.yml to confirm no wildcard localhost entries are explicitly present.
  4. If immediate upgrade cannot be performed, apply request filtering at the reverse proxy layer to reject origin headers matching http://localhost:* or http://127.0.0.1:*.

References

Read the full report for GHSA-M687-P538-R5HP on our website for more details including interactive diagrams and full exploit analysis.