Null captcha — invalid frontend token

Overview

On a feedback page no captcha shown and the error is occured:

null captcha — invalid frontend token: 0x8d40af589c1a9838cf365c3341bd542347bbd4ebbd95255fff5b592f19a12cc33d5ab564d4abff85f533f9e5ce7db5a0, backend report: /captcha/?%c2%18%24%82%47%9e%3f%ee%c2%9e%73%61%ac%eb%87%bc%fe%73%2d%bb%29%74%2c%e5%09%9c%17%cc%08%02%85%4a is fetched via Pheix::Controller::API.captcha: 0xef89f4a06b42d755664c553d2af9ae8d31535b2eef779b9a24c8df7dfbf3b1daa3f33f32f14fb37c410c1c6f1632(0x8d40af589c1a9838cf365c3341bd542347bbd4ebbd95255fff5b592f19a12cc33d5ab564d4abff85f533f9e5ce7db5a0)

Investigation

FastCGI

By default 3 FastCGI workers are up and running on server. This is configured by FcgidMinProcessesPerClass directive:

kostas@ala-archa:~$ ps ax | grep pheix.raku
 703269 ?        Sl    20:41 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
 703386 ?        Sl    21:37 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
 703403 ?        Sl    19:51 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
1117404 pts/2    S+     0:00 grep --color=auto pheix.raku

Each worker runs instance of Pheix dCMS. At metrics implementation I added names to instances, so on dashboard we see:

   

Invalid session token

Fronted token is created on Pheix instance start and is stored at pageobj of controller's %!sharedobj attribute.

Obviously, there are 3 different session tokens cause of 3 independent instances of Pheix (workers) run by fcgi_mod. Apache's fcgi_mod is switching between workers according built-in policy (I guess basically for load balancing reasons). So at some moment (moment of workers switching) request with session token issued by worker X reaches the worker Y and that causes the null captcha — invalid frontend token error.

Fix proposal

  1. Session token is created by backend on page render, best format: 64 bytes hex value from random(64);
  2. Session token stored in local database on creation with created and modified metadata field populated with now() value;
  3. Since session token is created, saved to database and sent to client within the requested page;
  4. Until page is reloaded, frontend will send this session token only, so we can check it in database for existence and expiration.

General question: how can we efficiently update or expire the session?

Update or expire the session

If session token is expired (modified - created > some delta value):

  1. Change token's status to expired;
  2. Generate new token on the fly and return it to frontend as a sessiontoken in API response.
Edited by Konstantin Narkhov