maxlath / wikibase-edit

a lib to edit Wikibase from NodeJS
67 stars 25 forks source link

"Invalid CSRF token" even after renewal #43

Open tuukka opened 4 years ago

tuukka commented 4 years ago

I use wikibase-edit with password authentication in a NodeJS service. At first everything works fine, but after the CSRF token expires, edits stop working. In the logs, I can see the token renewal operation but after that, Mediawiki still responds "Invalid CSRF token" even for the new token. A restart of the NodeJS service helps until the token expires again.

I see that the cookies don't change after the token renewal - could that be a bug in wikibase-edit or wikibase-token?

maxlath commented 4 years ago

which version of wikibase-edit are you using? do you know how much time it takes to the token to expire? I can't find it in the documentation

maxlath commented 4 years ago

also, is that part of an intensive edit batch? @jum-s and I have witnessed comparable errors when running a lot of edits

tuukka commented 4 years ago

Sorry, it's complicated. I have been using version 3.0.3.

In my case, all edits start to cause this error after it appears the first time. I have seen it happen in less than 2 hours but I'm not sure how long it can take. However, it seems I have been able to patch around this by not using the login cookies but the cookies from the token renewal request (when they appear - they always don't!)

In your case, do only some of the edits fail? I think there may be race conditions in the code regarding token renewal: If there are multiple requests in progress while the token expires, doesn't that cause multiple competing renewals which are not in sync with the subsequent retries and new requests?

tuukka commented 4 years ago

To continue about the potential race condition: The fix would be to stop all requests and retries after first error, make one token renewal and only then proceed with the requests and retries with the new token.

maxlath commented 4 years ago

(after some more digging, our case was a bit extreme: we were sending 8000+ parallel POST requests, no wonder the server wasn't keeping up ^^')

could you share the code that experiences this error?

tuukka commented 4 years ago

It's a simple NodeJS web service that calls wikibase-edit based on the HTTP requests that it receives. The parameter object specifies the item whose label will be set to the parameter name.

const axios = require('axios');
const wdk = require('wikibase-sdk');

const config = {
  credentials: {
    username: '***',
    password: '***'
  },
  verbose: true,
  wikibaseInstance: 'https://wiki.***.***/w/api.php',
}

const wbEdit = require('wikibase-edit')(config);

const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/', async (req, res) => {
    const labelResult = await wbEdit.entity.edit({
      id: req.body.object,
      labels: {
        en: req.body.name,
      },
    });
    console.log(labelResult);
    res.header("Access-Control-Allow-Origin", "*");
    res.send(labelResult);
    return;
});
app.listen(3001, () => console.log('server started on port 3001'));
MikaMaracuja commented 4 years ago

I have the same error. How did you solve it @tuukka?

maxlath commented 4 years ago

there was quite a lot of changes to the auth code since this issue was open, any chance this issue magically disappeared in the latest version? :D

haansn08 commented 4 years ago

Same error on wikibase-edit@4.5.1

maxlath commented 4 years ago

@haansn08 could you the error logs? how long did it work before it stopped working? which Wikibase are you working with?

haansn08 commented 4 years ago
Error: invalid csrf token
    at Object.new (*******/node_modules/wikibase-edit/lib/error.js:3:17)
    at parseTokens (*******/node_modules/wikibase-edit/lib/request/get_final_token.js:42:21)
    at *******/node_modules/wikibase-edit/lib/request/get_final_token.js:31:10
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async module.exports (*******/node_modules/wikibase-edit/lib/claim/move.js:70:17)
    at async *******/move.js:43:9
[context] {"loginCookies":"ss0-wikidatawikiSession=vpck*********; wikidatawikiSession=vpck*********; wikidatawikiUserID=28*****; wikidatawikiUserName=Haansn08; centralauth_Token=ac43*******; centralauth_Session=b6a7*******","body":{"batchcomplete":"","query":{"tokens":{"csrftoken":"+\\"}}}} {
  statusCode: 400,
  context: {
    loginCookies: 'ss0-wikidatawikiSession=vpck*********; wikidatawikiSession=vpck*********; wikidatawikiUserID=28*****; wikidatawikiUserName=Haansn08; centralauth_Token=ac43*******; centralauth_Session=b6a7*******',
    body: { batchcomplete: '', query: [Object] }
  }
}

It still worked on 2020-07-12. I'm using the instance https://www.wikidata.org.

maxlath commented 4 years ago

This patch 6abb7d1 might fix the problem (published in v4.5.2). Alternatively, I would recommend that you use Owner-only OAuth tokens, which should not have this issue