cppcms
cppcms copied to clipboard
Strengthen CSRF validation.
While doing CSRF validation, CppCMS is using "_csrf" value from the session. The "_csrf" value itself is generated in session_interface::save member function for new sessions. Validation will succeed if "_csrf" session value is empty or "_csrf" session value equals to "_csrf" POST data (or header value).
In normal situations, this works as expected because the form must be rendered before it is submitted. In the first GET request, session is initialized and "_csrf" value is set. In the subsequent requests, the _csrf value will exist in the session; thus validation will be in place.
Now, let's consider this situation:
- Attacker gets all information about the form by inspecting HTML code.
- Then post form data with cURL without any session cookie values and hidden "_csrf" variable and header. In this case, CppCMS will consider these requests as new session. But since "_csrf" value in the session is not generated until the response is written back; CSRF validation will succeed silently.
Maybe, we should change validate_csrf_token's logic as:
- if session[_csrf] empty, then return false.
- if token is empty, then return false.
- if session[_csrf] == token, return true; otherwise return false. After this change, if the session is new and it's POST method and form::load is called; CSRF validation will throw an exception (as expected).
Thank you.
the point is that if there is no cookie than there is no log-in/log-in session and thus the request isn't CSRF since it does not bring any credentials with it.
By design - no session - no CSRF validation since there is no forgery without session.
But isn't it supposed to protect POST request even if there is no cookie, no log-in?
With the current form, if attacker knows the structure of the form, then can POST directly with cURL and validation will be no-op. My opinion is that framework should give 403 error and force client to make a GET request at first.
If I know the session content/cookie I can create perfect request even with the CURL.
Why we add csrf. To prevent unintended POST for users that are logged in and have session. You need to protect your forms when somebody unauthorized tries to POST something and he does not have permission (this is why session exists)