Skip to content

[Bug] invalid CSRF token when importing .md/text files #43

Description

@calvin-1

Version

v1.1.3 PWA

Where

Server: Docker, accessed via PWA in Brave 1.93.138 (Chromium: 151.0.7922.173) behind Nginx Proxy Manager (HTTPS, wildcard cert)

What I expected

Uploading a .md recipe file via Recipes → Import from File should parse and import the recipe, since the docs state this endpoint accepts .md, .pdf, .rtf, .txt, and photos.

What actually happened

Every attempt fails immediately with {"error":"Invalid CSRF token"}, before any parsing happens. Reproduced consistently, including in a fresh incognito window (rules out stale service worker / cached bundle). Checked DevTools Application → Cookies for cooktrace with "show filtered out request cookies" enabled: no CSRF cookie is present, set, or rejected, only the ct_token auth cookie exists. The server's own Access-Control-Allow-Headers response header lists X-CSRF-Token as expected, but no request in the session (page load, settings, recipes, categories, cookbooks) ever receives a Set-Cookie for a CSRF token to send back. Login/session otherwise works fine; only this endpoint is affected.

Steps to reproduce

  1. Log in to CookTrace normally at a domain served over HTTPS via reverse proxy (NPM in my case)
  2. Go to Recipes → Import from File
  3. Select any .md file and submit
  4. Request to POST /api/recipes/extract-and-parse returns 403 with {"error":"Invalid CSRF token"}

Logs

from: docker logs cooktrace --tail 200
[2026-08-25T11:17:40.073Z] [WARN ] GET /history → 401 (0ms)
[2026-08-25T11:17:40.088Z] [INFO ] GET /status → 200 (1ms)
[2026-08-25T11:17:40.092Z] [INFO ] GET /me → 200 (1ms)
[2026-08-25T11:17:40.148Z] [WARN ] GET / → 401 (1ms)
[2026-08-25T11:17:40.154Z] [WARN ] GET / → 401 (1ms)
[2026-08-25T11:17:40.155Z] [WARN ] GET /categories → 401 (0ms)
[2026-08-25T11:17:40.157Z] [WARN ] GET / → 401 (0ms)
[2026-08-25T11:17:40.158Z] [WARN ] GET /shared-with-me → 401 (0ms)
[2026-08-25T11:17:40.159Z] [WARN ] GET /shared-with-me → 401 (1ms)
[2026-08-25T11:17:40.719Z] [INFO ] GET /status → 200 (0ms)
[2026-08-25T11:17:40.733Z] [WARN ] GET /env-locks → 401 (1ms)
[2026-08-25T11:17:40.734Z] [INFO ] GET /icons/logo.png → 304 (3ms)
[2026-08-25T11:17:48.015Z] [INFO ] POST /login → 200 (244ms)
[2026-08-25T11:17:48.037Z] [INFO ] GET /status → 200 (1ms)
[2026-08-25T11:17:48.041Z] [INFO ] GET /me → 200 (1ms)
[2026-08-25T11:17:48.055Z] [WARN ] GET /history → 401 (1ms)
[2026-08-25T11:17:48.369Z] [WARN ] GET / → 401 (1ms)
[2026-08-25T11:17:48.437Z] [WARN ] GET / → 401 (1ms)
[2026-08-25T11:17:48.439Z] [WARN ] GET /categories → 401 (1ms)
[2026-08-25T11:17:48.439Z] [WARN ] GET / → 401 (0ms)
[2026-08-25T11:17:48.440Z] [WARN ] GET /shared-with-me → 401 (0ms)
[2026-08-25T11:17:48.440Z] [WARN ] GET /shared-with-me → 401 (0ms)
[2026-08-25T11:17:48.441Z] [WARN ] GET / → 401 (0ms)
[2026-08-25T11:17:48.463Z] [INFO ] GET /status → 200 (1ms)
[2026-08-25T11:17:53.572Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:17:53.577Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:18:14.622Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:18:44.806Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:19:14.802Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:19:17.234Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:19:20.052Z] [INFO ] GET / → 304 (1ms)
[2026-08-25T11:19:20.424Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:19:20.613Z] [INFO ] GET /history → 200 (1ms)
[2026-08-25T11:19:20.616Z] [INFO ] GET /status → 200 (0ms)
[2026-08-25T11:19:20.618Z] [INFO ] GET /me → 200 (1ms)
[2026-08-25T11:19:20.676Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:19:20.695Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:19:20.696Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:19:20.698Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:19:20.699Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:19:20.700Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:19:21.328Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:19:21.364Z] [INFO ] GET /env-locks → 200 (2ms)
[2026-08-25T11:19:23.137Z] [INFO ] GET /sw.js → 200 (2ms)
[2026-08-25T11:19:40.714Z] [INFO ] POST /scrape → 201 (1656ms)
[2026-08-25T11:19:40.889Z] [INFO ] GET /2/cooks → 200 (1ms)
[2026-08-25T11:19:40.891Z] [INFO ] GET /2 → 200 (1ms)
[2026-08-25T11:19:40.922Z] [INFO ] GET / → 200 (3ms)
[2026-08-25T11:19:41.009Z] [INFO ] GET /2/comments → 200 (2ms)
[2026-08-25T11:19:51.370Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:20:21.370Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:20:31.827Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:20:31.829Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:20:31.830Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:20:31.831Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:20:31.833Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:20:31.837Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:20:51.375Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:21:21.817Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:21:51.889Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:22:21.796Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:23:34.865Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:24:25.602Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:24:25.608Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:24:51.369Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:25:21.368Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:25:22.004Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:25:22.009Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:25:25.281Z] [INFO ] GET /categories → 200 (1ms)
[2026-08-25T11:25:51.365Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:26:21.396Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:26:51.364Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:27:21.816Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:27:51.796Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:28:34.835Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:29:34.839Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:30:34.829Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:34.852Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:35.594Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:31:41.950Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:41.952Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:41.957Z] [INFO ] GET /categories → 200 (1ms)
[2026-08-25T11:31:41.958Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:31:41.960Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:31:41.961Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:31:51.369Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:31:51.591Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:51.593Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:51.594Z] [INFO ] GET /stats → 200 (1ms)
[2026-08-25T11:31:51.596Z] [INFO ] GET /heatmap → 200 (1ms)
[2026-08-25T11:31:53.988Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:31:53.990Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:53.991Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:31:57.073Z] [INFO ] GET / → 200 (2ms)
[2026-08-25T11:31:57.075Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:31:57.076Z] [INFO ] GET /stats → 200 (1ms)
[2026-08-25T11:31:57.077Z] [INFO ] GET /heatmap → 200 (0ms)
[2026-08-25T11:31:58.609Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:04.869Z] [INFO ] GET / → 200 (2ms)
[2026-08-25T11:32:11.395Z] [INFO ] GET /1/cooks → 200 (0ms)
[2026-08-25T11:32:11.397Z] [INFO ] GET /1 → 200 (1ms)
[2026-08-25T11:32:11.429Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:11.501Z] [INFO ] GET /1/comments → 200 (1ms)
[2026-08-25T11:32:15.569Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:32:15.571Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:15.573Z] [INFO ] GET /categories → 200 (1ms)
[2026-08-25T11:32:15.574Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:32:15.575Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:32:15.576Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:32:21.081Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:21.083Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:21.085Z] [INFO ] GET /stats → 200 (0ms)
[2026-08-25T11:32:21.087Z] [INFO ] GET /heatmap → 200 (0ms)
[2026-08-25T11:32:21.370Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:23.519Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:24.224Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:32:25.527Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:32:51.801Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:33:21.800Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:34:51.975Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:34:52.083Z] [INFO ] GET /history → 200 (0ms)
[2026-08-25T11:34:52.085Z] [INFO ] GET /status → 200 (1ms)
[2026-08-25T11:34:52.087Z] [INFO ] GET /me → 200 (0ms)
[2026-08-25T11:34:52.089Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:34:52.098Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:34:52.102Z] [INFO ] GET /stats → 200 (1ms)
[2026-08-25T11:34:52.104Z] [INFO ] GET /heatmap → 200 (1ms)
[2026-08-25T11:34:52.548Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:34:52.863Z] [INFO ] GET /env-locks → 200 (1ms)
[2026-08-25T11:34:54.799Z] [INFO ] GET /sw.js → 200 (1ms)
[2026-08-25T11:35:02.611Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:35:10.112Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:35:10.114Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:35:10.116Z] [INFO ] GET /categories → 200 (1ms)
[2026-08-25T11:35:10.117Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:35:10.119Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:35:10.120Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:35:22.912Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:35:52.864Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:36:22.863Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:36:52.863Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:36:54.971Z] [INFO ] POST /import → 201 (6ms)
[2026-08-25T11:36:55.203Z] [INFO ] GET /3/cooks → 200 (1ms)
[2026-08-25T11:36:55.204Z] [INFO ] GET /3 → 200 (0ms)
[2026-08-25T11:36:55.249Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:36:55.287Z] [INFO ] GET /3/comments → 200 (0ms)
[2026-08-25T11:37:04.068Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:37:04.070Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:37:04.072Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:37:04.074Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:37:04.075Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:37:04.076Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:37:07.716Z] [INFO ] DELETE /3 → 200 (0ms)
[2026-08-25T11:37:22.910Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:37:42.568Z] [INFO ] GET / → 304 (1ms)
[2026-08-25T11:37:52.870Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:38:19.144Z] [INFO ] GET /icons/icon-192.png → 200 (1ms)
[2026-08-25T11:38:19.213Z] [INFO ] GET /icons/icon-512.png → 200 (3ms)
[2026-08-25T11:38:22.866Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:38:52.865Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:39:22.272Z] [INFO ] GET /assets/Toggle-D-R_LJkR.js → 200 (1ms)
[2026-08-25T11:39:22.274Z] [INFO ] GET /assets/Toggle-uRYsW9hf.css → 200 (0ms)
[2026-08-25T11:39:22.284Z] [INFO ] GET /assets/Spinner-DFSMOH8b.js → 200 (1ms)
[2026-08-25T11:39:22.287Z] [INFO ] GET /assets/validation-i69_P1Bk.js → 200 (2ms)
[2026-08-25T11:39:22.287Z] [INFO ] GET /assets/Spinner-D-OEcS1r.css → 200 (1ms)
[2026-08-25T11:39:22.316Z] [INFO ] GET /assets/Settings-CFMsQR-P.js → 200 (50ms)
[2026-08-25T11:39:22.316Z] [INFO ] GET /assets/Settings-BdeOL4wa.css → 200 (34ms)
[2026-08-25T11:39:22.429Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:39:22.862Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:39:24.325Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:39:34.602Z] [INFO ] PUT / → 200 (1ms)
[2026-08-25T11:39:34.603Z] [INFO ] PUT / → 200 (0ms)
[2026-08-25T11:39:38.368Z] [INFO ] PUT / → 200 (1ms)
[2026-08-25T11:39:42.833Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:39:42.842Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:39:42.843Z] [INFO ] GET /categories → 200 (0ms)
[2026-08-25T11:39:42.844Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:39:42.863Z] [INFO ] GET /shared-with-me → 200 (1ms)
[2026-08-25T11:39:42.864Z] [INFO ] GET /shared-with-me → 200 (0ms)
[2026-08-25T11:39:52.864Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:40:22.868Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:40:52.866Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:41:22.867Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:41:52.865Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:42:22.935Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:42:52.864Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:43:23.800Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:43:53.806Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:44:34.811Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:44:35.958Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:44:52.866Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:45:22.866Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:45:52.867Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:46:23.805Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:46:44.774Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:46:53.798Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:47:23.796Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:48:20.823Z] [INFO ] GET / → 200 (0ms)
[2026-08-25T11:48:20.829Z] [INFO ] GET / → 200 (1ms)
[2026-08-25T11:48:22.865Z] [INFO ] GET / → 200 (0ms)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions