nextcloud / nextcloud/cookbook

CSRF token staleness causes all POST requests to fail after token rotation

Open Beginner friendly
#3,243 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
HTML
Stars
641
Forks
113
Avg merge
21h 31m
Merged PRs (30d)
26

Description

Extracted from #3227 by @eals2019:

Root cause

File: src/js/api-interface.js, line 6

import axios from '@nextcloud/axios';

const instance = axios.create();   // line 6 — ❌

@nextcloud/axios automatically subscribes the default axios instance to Nextcloud's csrf-token-update events, keeping the requesttoken header current across token rotations. However, axios.create() produces a new, independent instance that does not inherit those event subscriptions. The instance receives the correct CSRF token at page load but becomes stale if Nextcloud rotates the token during a long-running session, causing all subsequent POST requests (directory change, reindex, recipe save) to fail with a server-side CSRF validation error.

This can be confirmed in the server log (nextcloud.log):

{
  "method": "POST",
  "url": "/apps/cookbook/webapp/reindex",
  "message": "CSRF check failed"
}

Fix

Subscribe instance to CSRF token updates immediately after creation, mirroring what @nextcloud/axios does internally for its own instance:

import axios from '@nextcloud/axios';
import { onRequestTokenUpdate } from '@nextcloud/auth';  // ✅ add import

const instance = axios.create();

// Keep instance in sync with Nextcloud CSRF token rotations
onRequestTokenUpdate((token) => {           // ✅ add this block
    instance.defaults.headers.requesttoken = token;
});

Alternatively, avoid .create() entirely and use the @nextcloud/axios default export directly, since it already handles token rotation. All interceptors currently added to instance (request/response logging) would need to be moved to the default axios export in that case.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/js/api-interface.js at the axios.create() call and compare it with @nextcloud/axios token-update behavior. Reproduce or inspect the CSRF failure in nextcloud.log, then verify that the instance receives rotated tokens and that POST actions such as reindexing no longer fail.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.