CVE-2023-5687: Cross-Site Request Forgery (CSRF) (CWE-352)
value: Cross-Site Request Forgery (CSRF) in GitHub repository mosparo/mosparo prior to 1.0.3.
CWE description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
CVSS v3 base score: 8.8
Published: 2023-10-20T17:15Z
Repository: https://github.com/mosparo/mosparo
Language: Other
Files changed: config/packages/security.yaml, templates/base.html.twig, templates/security/login.html.twig
Commit date: 2023-10-14 10:43:07 +0200
Commit message: Security: Added the CSRF token to the logout URL
As reported by @qqliunian2001 on huntr.dev, it is possible to force the logout of a user. This is because we did not set up any protection against direct access to the logout route.

With this fix, we use the CSRF option from Symfony to protect the logout functionality. If no CSRF token is provided, the logout will not work.

Diff: diff --git a/config/packages/security.yaml b/config/packages/security.yaml
index cc37c29..3f91759 100644
--- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -49,10 +49,12 @@ security:
                 login_path: security_login
                 check_path: security_login
                 default_target_path: project_list
             logout:
                 path: security_logout
+                csrf_parameter: token
+                csrf_token_generator: security.csrf.token_manager
             two_factor:
                 auth_form_path: 2fa_login
                 check_path: 2fa_login_check
 
             login_throttling:
diff --git a/templates/base.html.twig b/templates/base.html.twig
index 08498e6..dd442a6 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -70,11 +70,11 @@
                                 <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
                                     <a href="{{ path('account_overview') }}" class="dropdown-item">
                                         <i class="ti ti-adjustments"></i>
                                         {{ 'account.title'|trans }}
                                     </a>
-                                    <a href="{{ path('security_logout') }}" class="dropdown-item">
+                                    <a href="{{ path('security_logout', {'token' : csrf_token('logout')}) }}" class="dropdown-item">
                                         <i class="ti ti-logout"></i>
                                         {{ 'security.logout.title'|trans }}
                                     </a>
                                 </div>
                             </div>
diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig
index 94f8bfe..3237c93 100644
--- a/templates/security/login.html.twig
+++ b/templates/security/login.html.twig
@@ -34,11 +34,11 @@
             {% endif %}
         {% endblock %}
 
         {% if app.user %}
             <div class="alert alert-info">
-                {{ 'security.login.youAreLoggedIn'|trans({'%username%': app.user.username}, 'mosparo') }}. <a href="{{ path('security_logout') }}">{{ 'security.logout.title'|trans }}</a>
+                {{ 'security.login.youAreLoggedIn'|trans({'%username%': app.user.username}, 'mosparo') }} <a href="{{ path('security_logout', {'token' : csrf_token('logout')}) }}">{{ 'security.logout.title'|trans }}</a>
             </div>
         {% endif %}
 
         <div class="mb-3">
             <label class="form-label required" for="field-email">{{ 'security.login.emailLabel'|trans }}</label>

Vulnerable code:                                     <a href="{{ path('security_logout') }}" class="dropdown-item">
                {{ 'security.login.youAreLoggedIn'|trans({'%username%': app.user.username}, 'mosparo') }}. <a href="{{ path('security_logout') }}">{{ 'security.logout.title'|trans }}</a>
Fixed code:                 csrf_parameter: token
                csrf_token_generator: security.csrf.token_manager
                                    <a href="{{ path('security_logout', {'token' : csrf_token('logout')}) }}" class="dropdown-item">
                {{ 'security.login.youAreLoggedIn'|trans({'%username%': app.user.username}, 'mosparo') }} <a href="{{ path('security_logout', {'token' : csrf_token('logout')}) }}">{{ 'security.logout.title'|trans }}</a>