CVE-2022-22111 (published 2022-01-05T15:15Z)

In DayByDay CRM, version 2.2.0 is vulnerable to missing authorization. Any application user in the application who has update user permission enabled is able to change the password of other users, including the administrator’s. This allows the attacker to gain access to the highest privileged user in the application.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/Bottelet/DaybydayCRM
commit_details: repo_url: https://github.com/Bottelet/DaybydayCRM
author: Casper Bottelet
author_date: 2021-06-25 20:38:06+02:00
msg: ensure only admin and owner can change role, and password, unless it is yourself
repository: repo_url: https://github.com/Bottelet/DaybydayCRM
repo_name: Bottelet/DaybydayCRM
description: DaybydayCRM an open-source CRM, to help you keep track of your daily workflow.
repo_language: PHP
owner: Bottelet
file_changes: filename: UsersController.php
change_type: ModificationType.MODIFY
diff: @@ -40,6 +40,10 @@ class UsersController extends Controller
 
     public function calendarUsers()
     {
+        if (!auth()->user()->can('absence-view')) {
+            session()->flash('flash_message_warning', __('You do not have permission to view this page'));
+            return redirect()->back();
+        }
         return User::with(['department', 'absences' =>  function ($q) {
             return $q->whereBetween('start_at', [today()->subWeeks(2)->startOfDay(), today()->addWeeks(4)->endOfDay()])
                       ->orWhereBetween('end_at', [today()->subWeeks(2)->startOfDay(), today()->addWeeks(4)->endOfDay()]);
@@ -244,6 +248,12 @@ class UsersController extends Controller
         $password = bcrypt($request->password);
         $role = $request->roles;
         $department = $request->departments;
+
+        if( !auth()->user()->canChangePasswordOn($user) ) {
+            unset($request['password']);
+        }
+
+
         if ($request->hasFile('image_path')) {
             $companyname = Setting::first()->external_id;
             $file =  $request->file('image_path');
@@ -273,7 +283,9 @@ class UsersController extends Controller
         if ($role && $role->name == Role::OWNER_ROLE && $owners->count() <= 1) {
             Session()->flash('flash_message_warning', __('Not able to change owner role, please choose a new owner first'));
         } else {
-            $user->roles()->sync([$request->roles]);
+            if(auth()->user()->canChangeRole() ) {
+                $user->roles()->sync([$request->roles]);
+            }
         }
         $user->department()->sync([$department]);
 

programming_language: PHP
filename: User.php
change_type: ModificationType.MODIFY
diff: @@ -98,6 +98,19 @@ class User extends Authenticatable
         return $this->hasMany(Token::class, 'user_id', 'id');
     }
 
+    public function canChangePasswordOn(User $user)
+    {
+        if($this->id === $user->id || ( $this->roles->first()->name == Role::OWNER_ROLE || $this->roles->first()->name == Role::ADMIN_ROLE)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public function canChangeRole()
+    {
+        return $this->roles->first()->name == Role::OWNER_ROLE || $this->roles->first()->name == Role::ADMIN_ROLE;
+    }
 
 
     public function isOnline()

programming_language: PHP
filename: form.blade.php
change_type: ModificationType.MODIFY
diff: @@ -61,10 +61,11 @@
 <div class="col-sm-12">
     <hr>
 </div>
-
+@if(isset($user) && auth()->user()->canChangePasswordOn($user))
 <div class="col-sm-3">
     <label for="name" class="base-input-label">@lang('Security')</label>
 </div>
+
 <div class="col-sm-9">
     <div class="form-group col-sm-8">
         <label for="password" class="control-label thin-weight">@lang('Password')</label>
@@ -75,6 +76,7 @@
         <input type="password" name="password_confirmation" class="form-control" value="">
     </div>
 </div>
+@endif
 <div class="col-sm-12">
     <hr>
 </div>
@@ -82,6 +84,7 @@
     <label for="name" class="base-input-label">@lang('Access')</label>
 </div>
 <div class="col-sm-9">
+@if(isset($user) && auth()->user()->canChangeRole())
     <div class="form-group col-sm-8">
         <label for="roles" class="control-label thin-weight">@lang('Assign role')</label>
         <select name="roles" id="" class="form-control">
@@ -90,6 +93,7 @@
         @endforeach
         </select>
     </div>
+@endif
     <div class="form-group col-sm-8">
         <label for="departments" class="control-label thin-weight">@lang('Assign department')</label>
         <select name="departments" id="" class="form-control">

programming_language: PHP