{"id":"CVE-2026-91969","kind":"vulnerability","aliases":["CVE-2026-91969","GHSA-pqf9-h8g4-8gmh","GO-2026-6746"],"related":[],"title":"Vikunja: Unbounded CSV row cardinality permits API process termination in code.vikunja.io/api","description":"Vikunja: Unbounded CSV row cardinality permits API process termination in code.vikunja.io/api.\n\nNOTE: The source advisory for this report contains additional versions that could not be automatically mapped to standard Go module versions.\n\n(If this is causing false-positive reports from vulnerability scanners, please suggest an edit to the report.)\n\nThe additional affected modules and versions are: code.vikunja.io/api from v2.5.0 before v2.6.0.","summary":"Vikunja's authenticated CSV migration endpoint (POST /api/v2/migration/csv/migrate) caps upload bytes but not row count. It parses every row into memory and builds a task object for each. About 2 million one-cell rows (a ~4 MB request) got a 512 MiB API process OOM-killed. Any logged-in user, including a self-registered one if registration is open, can take the API down for everyone. VulnCheck rates it CVSS v4 7.1.","severity":"high","cvss":7.1,"epss":0.00348,"exploited":false,"exploited_at":null,"products":[{"name":"code.vikunja.io/api","fixed":[],"affected":"all versions","ecosystem":"go"},{"name":"code.vikunja.io/api","fixed":["2.6.0"],"affected":">= 2.5.0, < 2.6.0","ecosystem":"go"}],"ecosystems":["go"],"tags":["auth-required","denial-of-service","go","package","self-hosted","vikunja"],"not_affected_if":["auth-required","default-config","managed-hosting"],"how_to_check":"Run 'vikunja version', or check the Docker image tag or the /api/v1/info version field. Versions >= 2.5.0 and < 2.6.0 are affected. The advisory says versions before 2.5.0 were not established as affected. Also check whether registration is enabled (service.enableregistration), since that lets anyone get an account.","fix":"Upgrade Vikunja to v2.6.0 or later. The fix is in PR #3688, which adds configurable CSV import limits. Until you upgrade, restrict who can register or log in, or block POST /api/v2/migration/csv/migrate at the reverse proxy. Set a memory limit and a restart policy on the container.","status":"open","published_at":"2026-09-15T16:17:53+00:00","first_seen_at":"2026-10-23T19:13:08+00:00","triaged_at":"2026-10-23T21:45:53+00:00","updated_at":"2026-10-23T21:46:44+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-10-23T21:45:53Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade code.vikunja.io/api to v2.6.0 or later, since the advisory states v2.5.0 through the version before v2.6.0 are affected.","reach":"internet","impact":"low","summary":"Vikunja's API accepts CSV input with no limit on the number of rows, so a crafted large CSV can make the API process run out of resources and terminate. An attacker who can reach the import endpoint can take the API down.","category":"package","who_cares":["go","vikunja","self-hosted"],"confidence":0.6,"needs_auth":"unknown","worst_case":"Attacker crashes the API process with a crafted CSV upload","analyst_note":"Confirm which endpoint accepts CSV and whether it requires auth, using the GHSA-pqf9-h8g4-8gmh advisory linked from GO-2026-6746.","how_to_check":"unknown","needs_analyst":true,"not_affected_if":["default-config"],"user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"high"},"cost_usd":0.000476,"input_tokens":2957,"output_tokens":360,"severity_before":"high"},"analyst_status":"done","analyst_note":"Confirm which endpoint accepts CSV and whether it requires auth, using the GHSA-pqf9-h8g4-8gmh advisory linked from GO-2026-6746.","search":"'-2026':15A,23A,26A '-6746':24A '-91969':16A,27A '/api':13A,30A,33A,184C '/api.':135C '/api/v2/migration/csv/migrate':54B '2':76B '4':83B '512':88B '7.1':122B '8gmh':21A 'addit':144C,176C 'advisori':139C 'affect':177C 'api':7A,90B,113B,129C 'auth':35B 'auth-requir':34B 'authent':49B 'automat':150C 'build':69B 'byte':57B 'cap':55B 'cardin':5A,127C 'caus':160C 'cell':80B 'code.vikunja.io':12A,29A,32A,134C,183C 'code.vikunja.io/api':11A,28A,31A,182C 'code.vikunja.io/api.':133C 'contain':143C 'could':147C 'count':61B 'csv':3A,50B,125C 'cve':14A,25A 'cvss':120B 'denial':38B 'denial-of-servic':37B 'edit':171C 'endpoint':52B 'everi':64B 'everyon':116B 'fals':162C 'false-posit':161C 'ghsa':18A 'ghsa-pqf9-h8g4-8gmh':17A 'go':22A,41B,154C 'got':86B 'h8g4':20A 'host':45B 'includ':100B 'kill':94B 'log':97B 'logged-in':96B 'map':151C 'mb':84B 'memori':67B 'mib':89B 'migrat':51B 'million':77B 'modul':155C,178C 'note':136C 'object':72B 'one':79B,105B 'one-cel':78B 'oom':93B 'oom-kil':92B 'open':109B 'packag':42B 'pars':63B 'permit':6A,128C 'pleas':168C 'posit':163C 'post':53B 'pqf9':19A 'process':8A,91B,130C 'rate':118B 'regist':104B 'registr':107B 'report':142C,164C,174C 'request':85B 'requir':36B 'row':4A,60B,65B,81B,126C 'scanner':167C 'self':44B,103B 'self-host':43B 'self-regist':102B 'servic':40B 'sourc':138C 'standard':153C 'suggest':169C 'take':111B 'task':71B 'termin':9A,131C 'unbound':2A,124C 'upload':56B 'user':99B 'v2.5.0':186C 'v2.6.0':188C 'v4':121B 'version':145C,156C,180C 'vikunja':1A,46B,47B,123C 'vulncheck':117B 'vulner':166C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-09-15T16:17:53+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/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_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"govuln","external_id":"GO-2026-6746","url":"https://pkg.go.dev/vuln/GO-2026-6746","severity":null,"published_at":"2026-10-19T21:08:26+00:00","modified_at":"2026-10-19T21:08:26+00:00","first_seen_at":"2026-10-23T19:13:08+00:00","fetched_at":"2026-10-23T19:13:08+00:00","note":null},{"source":"epss","external_id":"CVE-2026-91969","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-91969","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-23T19:13:43+00:00","fetched_at":"2026-10-23T19:13:43+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-91969","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-91969","severity":null,"published_at":"2026-09-15T16:17:53+00:00","modified_at":"2026-09-17T20:18:54+00:00","first_seen_at":"2026-10-23T19:35:23+00:00","fetched_at":"2026-10-23T19:35:23+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-91969:142","url":null,"severity":null,"published_at":"2026-10-23T21:46:44+00:00","modified_at":"2026-10-23T21:46:44+00:00","first_seen_at":"2026-10-23T21:46:44+00:00","fetched_at":"2026-10-23T21:46:44+00:00","note":"Read GHSA-pqf9-h8g4-8gmh, VulnCheck, GO-2026-6746, PR #3688. Endpoint POST /api/v2/migration/csv/migrate, requires authentication (any registered user). Fix in v2.6.0 (PR #3688 merged 2026-08-31). Advisory has a self-contained PoC (OOM of 512MiB container with 2M rows); no in-the-wild exploitation reported. Did not search social posts. Release v2.6.0 page not read directly."}],"documents":[{"id":1244,"url":"https://github.com/go-vikunja/vikunja/security/advisories/GHSA-pqf9-h8g4-8gmh","title":"GHSA-pqf9-h8g4-8gmh: Unbounded CSV row cardinality","kind":"advisory","source":"analyst","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null},{"id":1245,"url":"https://github.com/go-vikunja/vikunja/pull/3688","title":"PR #3688 fix(security): harden authorization and resource limits","kind":"release","source":"analyst","text":null,"published_at":null,"relation":"fix","confidence":null,"note":null},{"id":1246,"url":"https://www.vulncheck.com/advisories/vikunja-before-2.6.0-resource-exhaustion-via-csv-migration","title":"VulnCheck: vikunja before 2.6.0 CSV resource exhaustion","kind":"other","source":"analyst","text":null,"published_at":null,"relation":"describes","confidence":null,"note":null},{"id":1247,"url":"https://pkg.go.dev/vuln/GO-2026-6746","title":"GO-2026-6746","kind":"other","source":"analyst","text":null,"published_at":null,"relation":"mentions","confidence":null,"note":null}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}