CVE-2021-3932 (published 2021-11-13T09:15Z)

twill is vulnerable to Cross-Site Request Forgery (CSRF)

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:P/A:N)
CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
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.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/area17/twill
commit_details: repo_url: https://github.com/area17/twill
author: Patrick Boivin
author_date: 2021-11-05 16:54:16-04:00
msg: Use POST action for logout links
repository: repo_url: https://github.com/area17/twill
repo_name: area17/twill
description: Twill is an open source CMS toolkit for Laravel that helps developers rapidly create a custom admin console that is intuitive, powerful and flexible. Chat with us on Discord at https://discord.gg/cnWk7EFv8R.
repo_language: PHP
owner: area17
file_changes: filename: logoutButton.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,16 @@
+// POST logout action
+
+const logoutButton = function () {
+  const logoutForm = document.querySelector('[data-logout-form]')
+
+  if (!logoutForm) return
+
+  document.body.addEventListener('click', e => {
+    if (e.target.hasAttribute('data-logout-btn')) {
+      e.preventDefault()
+      logoutForm.submit()
+    }
+  })
+}
+
+export default logoutButton

programming_language: JavaScript
filename: main.js
change_type: ModificationType.MODIFY
diff: @@ -4,12 +4,14 @@ import 'styles/app.scss'
 import Vue from 'vue'
 import navToggle from '@/behaviors/navToggle'
 import showEnvLine from '@/behaviors/showEnvLine'
+import logoutButton from '@/behaviors/logoutButton'
 import search from '@/main-search'
 import merge from 'lodash/merge'
 
 const A17Init = function () {
   navToggle()
   showEnvLine()
+  logoutButton()
 }
 
 // User header dropdown

programming_language: JavaScript
filename: auth.php
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@ use Illuminate\Support\Facades\Route;
 if (config('twill.enabled.users-management')) {
     Route::get('login', 'LoginController@showLoginForm')->name('login.form');
     Route::post('login', 'LoginController@login')->name('login');
-    Route::get('logout', 'LoginController@logout')->name('logout');
+    Route::post('logout', 'LoginController@logout')->name('logout');
 
     Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.reset.link');
     Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.reset.email');

programming_language: PHP
filename: main.blade.php
change_type: ModificationType.MODIFY
diff: @@ -71,6 +71,11 @@
                 @include('twill::partials.footer')
             </section>
         </div>
+
+        <form class="visually-hidden" method="POST" action="{{ route('admin.logout') }}" data-logout-form>
+            @csrf
+        </form>
+
         <script>
             window['{{ config('twill.js_namespace') }}'] = {};
             window['{{ config('twill.js_namespace') }}'].version = '{{ config('twill.version') }}';

programming_language: PHP
filename: _overlay_navigation.blade.php
change_type: ModificationType.MODIFY
diff: @@ -22,7 +22,7 @@
                     @if(isset($currentUser))
                         <a href="{{ route('admin.users.index') }}">{{ twillTrans('twill::lang.nav.cms-users') }}</a><br />
                         <a href="{{ route('admin.users.edit', $currentUser->id) }}">{{ twillTrans('twill::lang.nav.settings') }}</a><br />
-                        <a href="{{ route('admin.logout') }}">{{ twillTrans('twill::lang.nav.logout') }}</a>
+                        <a href="#" data-logout-btn>{{ twillTrans('twill::lang.nav.logout') }}</a>
                     @endif
                 </div>
             </div>

programming_language: PHP
filename: _user.blade.php
change_type: ModificationType.MODIFY
diff: @@ -14,7 +14,7 @@
                 <a href="{{ route('admin.users.index') }}">{{ twillTrans('twill::lang.nav.cms-users') }}</a>
             @endcan
             <a href="{{ route('admin.users.edit', $currentUser->id) }}">{{ twillTrans('twill::lang.nav.settings') }}</a>
-            <a href="{{ route('admin.logout') }}">{{ twillTrans('twill::lang.nav.logout') }}</a>
+            <a href="#" data-logout-btn>{{ twillTrans('twill::lang.nav.logout') }}</a>
         </div>
     </a17-dropdown>
 @endif

programming_language: CoffeeScript