Cookie validation has a bug if using monit with subdomain address.
The issue is visible when trying to unmonitor or monitor any task, and when monit doing POST request. I get 403 forbidden page saying Invalid CSRF Token.
First I searched all issues and I thought that I have the issue #495, but finally this is different.
So when monit is accessed via subdomain, and if on main domain there are already many other different cookies set visible also for subdomain page, in some cases cookie validation not working.
When see the problem, I open monit now in private browse mode, where other cookies are not set, and monit working without any problem. So the problem is connected with sent Cookie header, when there is only monit’s cookie no problem, when there are other cookies monit not working and i will describe in which case and how I resolved the issue.
So i have opened the dev tools in Firefox and tried to modify my Cookie: header by removing 1 cookie each time. After many retires I saw that the issue is not connected with any specific cookie but with the cookie header length in general.
Finally I have found, that if my Cookie header length is longer than 1013 characters, monit cookie validation failing…
Please note that the cases where the cookie header length can be longer than 1013 are really frequent. In my specific case my header length is 2450 characters. If on main domain you have a running site with facebook scripts, google analytics scripts, CMS native scripts, Cookie header length get longer then 1013 chars quickly.
So finally I checked the source code of monit and found that for header creation method in src/http/processor.c file, to allocate memory for headers, REQ_STRLEN is used to allocate memory and store headers. In src/http/processor.h file REQ_STRLEN is only 1024. So whats happening is that securitytoken= cookie is not getting copied and so cookie validation is failing…
I have tried to assign 3072 for REQ_STRLEN and issue gone (in my case my cookie header length was 2450).
Errors in systemctl status monit -l
HttpRequest: access denied -- client [127.0.0.1]: no CSRF token in cookie HttpRequest: error -- client [127.0.0.1]: HTTP/1.0 403 Invalid CSRF Token
You can reproduce the issue easily:
1) Open dev tools in browser go to network tab and click on POST request which corresponds to monitor or unmonitor the task
2) Click Edit and resend button so you can change the Cookie header
3) Now prepend any custom nonsense cookie, so your Cookie header will have in general more than 1013 characters (so with Cookie: string and last character we will overflow the 1024 limit) and send the query. You will see the 403 forbidden response.
Bellow are my requests, first one with error and 403 status, second one with OK and 200 status. note that 2 requests differ only with 1 character.
POST Request body string:
Cookie header string:
- Now failed one
Failed POST Request body string: same as above
Failed Cookie header string:
Failed Status: 403