CVE-2018-17104: Cross-Site Request Forgery (CSRF) (CWE-352)
value: An issue was discovered in Microweber 1.0.7. There is a CSRF attack (against the admin user) that can add an administrative account via api/save_user.
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: 2018-09-16T21:29Z
Repository: https://github.com/microweber/microweber
Language: PHP
Files changed: src/Microweber/Providers/UserManager.php, userfiles/modules/users/edit_user.php, userfiles/modules/users/profile/confirm_edit.php
Commit date: 2018-08-31 19:07:21 +0300
Commit message: fix of issue #484

editing user now requires csrf token

Diff: diff --git a/src/Microweber/Providers/UserManager.php b/src/Microweber/Providers/UserManager.php
index 93225ffc..12db014d 100644
--- a/src/Microweber/Providers/UserManager.php
+++ b/src/Microweber/Providers/UserManager.php
@@ -644,10 +644,11 @@ class UserManager
                 }
             }
         }
 
         if (defined('MW_API_CALL')) {
+
             if (isset($params['is_admin']) and $this->is_admin() == false) {
                 unset($params['is_admin']);
             }
             if (isset($params['is_verified']) and $this->is_admin() == false) {
                 unset($params['is_verified']);
@@ -899,10 +900,25 @@ class UserManager
                     unset($params['is_admin']);
                 }
             }
         }
         if ($force == false) {
+
+            if (isset($params['id'])) {
+                $validate_token = mw()->user_manager->csrf_validate($params);
+
+                if ($validate_token == false) {
+
+                    return array(
+                        'error' => _e('Confirm edit of profile', true),
+                        'form_data_required' => 'token',
+                        'form_data_module' => 'users/profile/confirm_edit'
+                    );
+
+                }
+            }
+
             if (isset($params['id']) and $params['id'] != 0) {
                 $adm = $this->is_admin();
                 if ($adm == false) {
                     $is_logged = user_id();
                     if ($is_logged == false or $is_logged == 0) {
@@ -921,10 +937,13 @@ class UserManager
                         $is_logged = user_id();
                         if (intval($params['id']) != 0 and $is_logged != $params['id']) {
                             return array('error' => 'You must be logged save your settings');
                         }
                     } else {
+
+
+
                         if (!isset($params['id'])) {
                             $params['id'] = $this->id();
                         }
                     }
                 }
diff --git a/userfiles/modules/users/edit_user.php b/userfiles/modules/users/edit_user.php
index f181af17..df7bf106 100644
--- a/userfiles/modules/users/edit_user.php
+++ b/userfiles/modules/users/edit_user.php
@@ -184,11 +184,12 @@ if (isset($data[0]) == false) {
                 <span>
     <?php _e("Add new user"); ?>
     </span>
             <?php endif; ?>
         </div>
-        <input type="hidden" class="mw-ui-field" name="id" value="<?php print $data['id']; ?>">
+        <input type="hidden"   name="id" value="<?php print $data['id']; ?>">
+        <input type="hidden"   name="token" value="<?php print csrf_token() ?>"  autocomplete="off">
         <div>
             <table btos="0" cellpadding="0" cellspacing="0" class="mw-ui-table mw-ui-table-basic mw-admin-user-tab-content" width="100%">
                 <col width="150px"/>
                 <tr>
                     <td><label class="mw-ui-label">
diff --git a/userfiles/modules/users/profile/confirm_edit.php b/userfiles/modules/users/profile/confirm_edit.php
new file mode 100644
index 00000000..57df260f
--- /dev/null
+++ b/userfiles/modules/users/profile/confirm_edit.php
@@ -0,0 +1,11 @@
+<div class="row" style="margin-top: 20px;margin-bottom: 20px;">
+    <div class="col-xs-12">
+        <div class="form-group">
+            <h5><?php _e('Confirm edit of profile'); ?></h5>
+            <label class="mw-ui-check">
+                <input type="checkbox" name="token" value="<?php print csrf_token() ?>" autocomplete="off"/> &nbsp;
+                <span><?php _e('Confirm'); ?></span>
+            </label>
+        </div>
+    </div>
+</div>
\ No newline at end of file

Vulnerable code:         <input type="hidden" class="mw-ui-field" name="id" value="<?php print $data['id']; ?>">
Fixed code: 

            if (isset($params['id'])) {
                $validate_token = mw()->user_manager->csrf_validate($params);

                if ($validate_token == false) {

                    return array(
                        'error' => _e('Confirm edit of profile', true),
                        'form_data_required' => 'token',
                        'form_data_module' => 'users/profile/confirm_edit'
                    );

                }
            }




        <input type="hidden"   name="id" value="<?php print $data['id']; ?>">
        <input type="hidden"   name="token" value="<?php print csrf_token() ?>"  autocomplete="off">
<div class="row" style="margin-top: 20px;margin-bottom: 20px;">
    <div class="col-xs-12">
        <div class="form-group">
            <h5><?php _e('Confirm edit of profile'); ?></h5>
            <label class="mw-ui-check">
                <input type="checkbox" name="token" value="<?php print csrf_token() ?>" autocomplete="off"/> &nbsp;
                <span><?php _e('Confirm'); ?></span>
            </label>
        </div>
    </div>
</div>