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

snipe-it 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/snipe/snipe-it
commit_details: repo_url: https://github.com/snipe/snipe-it
author: snipe
author_date: 2021-11-05 10:53:48-07:00
msg: Turn cusotm fields required/optional/remove into POST requests

Signed-off-by: snipe <snipe@snipe.net>
repository: repo_url: https://github.com/snipe/snipe-it
repo_name: snipe/snipe-it
description: A free open source IT asset/license management system
repo_language: PHP
owner: snipe
file_changes: filename: view.blade.php
change_type: ModificationType.MODIFY
diff: @@ -57,21 +57,28 @@
               <td>{{$field->element}}</td>
               <td>{{ $field->field_encrypted=='1' ?  trans('general.yes') : trans('general.no') }}</td>
                 <td>
+                  
                     @if ($field->pivot->required)
-                        <a href="{{ route('fields.optional', [$custom_fieldset->id, $field->id]) }}">
-                            <i class="fa fa-check text-success" aria-hidden="true"></i>
-                            <span class="sr-only">Required - click to make optional</span>
-                        </a>
+                    <form method="post" action="{{ route('fields.optional', [$custom_fieldset->id, $field->id]) }}">
+                      @csrf 
+                      <button type="submit" class="btn btn-link"><i class="fa fa-check text-success" aria-hidden="true"></i></button>
+                      </form>
+
                     @else
-                        <a href="{{ route('fields.required', [$custom_fieldset->id, $field->id]) }}">
-                            <i class="fa fa-times text-danger" aria-hidden="true"></i>
-                            <span class="sr-only">Optional - click to make required</span>
-                        </a>
+
+                      <form method="post" action="{{ route('fields.required', [$custom_fieldset->id, $field->id]) }}">
+                      @csrf 
+                      <button type="submit" class="btn btn-link"><i class="fa fa-times text-danger" aria-hidden="true"></i></button>
+                      </form>
                     @endif
+                    
                 </td>
               <td>
                 @can('update', $custom_fieldset)
-                <a href="{{ route('fields.disassociate', [$field, $custom_fieldset->id]) }}" class="btn btn-sm btn-danger">Remove</a>
+                <form method="post" action="{{ route('fields.disassociate', [$field, $custom_fieldset->id]) }}">
+                  @csrf 
+                  <button type="submit" class="btn btn-sm btn-danger">Remove</button>
+                </form>
                 @endcan
               </td>
             </tr>

programming_language: PHP
filename: fields.php
change_type: ModificationType.MODIFY
diff: @@ -7,17 +7,17 @@
 
 Route::group([ 'prefix' => 'fields','middleware' => ['auth'] ], function () {
 
-    Route::get('required/{fieldset_id}/{field_id}',
+    Route::post('required/{fieldset_id}/{field_id}',
         ['uses' => 'CustomFieldsetsController@makeFieldRequired',
             'as' => 'fields.required']
     );
 
-    Route::get('optional/{fieldset_id}/{field_id}',
+    Route::post('optional/{fieldset_id}/{field_id}',
         ['uses' => 'CustomFieldsetsController@makeFieldOptional',
             'as' => 'fields.optional']
     );
 
-    Route::get('{field_id}/fieldset/{fieldset_id}/disassociate',
+    Route::post('{field_id}/fieldset/{fieldset_id}/disassociate',
         ['uses' => 'CustomFieldsController@deleteFieldFromFieldset',
         'as' => 'fields.disassociate']
     );

programming_language: PHP