CVE-2021-27885: Cross-Site Request Forgery (CSRF) (CWE-352)
value: usersettings.php in e107 through 2.3.0 lacks a certain e_TOKEN protection mechanism.
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: 2021-03-02T19:15Z
Repository: https://github.com/e107inc/e107
Language: PHP
Files changed: usersettings.php
Commit date: 2021-03-01 16:41:09 -0800
Commit message: e_TOKEN added.

Diff: diff --git a/usersettings.php b/usersettings.php
index f10d09f67d..23c741005d 100644
--- a/usersettings.php
+++ b/usersettings.php
@@ -19,11 +19,14 @@ Notes:
 Uses $udata initially, later curVal to hold current user data
 Admin log events:
 USET_01 - admin changed user data
 */
 
-
+if(!empty($_POST) && !isset($_POST['e-token']))
+{
+	$_POST['e-token'] = '';
+}
 require_once ('class2.php');
 
 // TODO - Remove all the adminEdit stuff. 
 
 define("US_DEBUG",FALSE);
@@ -1030,10 +1033,11 @@ class usersettings_front // Begin Usersettings rewrite.
 				$text .= "
 				<input type='hidden' name='updated_data' value='{$updated_data}' />
 				<input type='hidden' name='updated_key' value='{$validation_key}' />
 				<input type='hidden' name='updated_extended' value='{$updated_extended}' />
 				<input type='hidden' name='extended_key' value='{$extended_key}' />
+				<input type='hidden' name='e-token' value='".defset('e_TOKEN')."' />
 				</td></tr>
 				<tr><td>&nbsp;</td></tr>
 				<tr><td style='text-align:center'>
 				".e107::getForm()->button('SaveValidatedInfo',1, 'submit', LAN_ENTER)."
 				</td></tr>
@@ -1083,12 +1087,10 @@ class usersettings_front // Begin Usersettings rewrite.
 
 		$target = e107::getUrl()->create('user/myprofile/edit',array('id'=>USERID));
 
 		$text = '<form method="post" action="'.$target.'" id="dataform" class="usersettings-form form-horizontal"  enctype="multipart/form-data" autocomplete="off">';
 
-		//$text = (is_numeric($_uid) ? $rs->form_open("post", e_SELF."?".e_QUERY, "dataform", "", " class='form-horizontal' role='form' enctype='multipart/form-data'") : $rs->form_open("post", e_SELF, "dataform", "", " class='form-horizontal' role='form' enctype='multipart/form-data'"));
-
 		if (e_QUERY == "update")
 		{
 			$text .= "<div class='fborder' style='text-align:center'><br />".str_replace("*", "<span class='required'>*</span>", LAN_USET_9)."<br />".LAN_USET_10."<br /><br /></div>";
 		}
 
@@ -1100,21 +1102,19 @@ class usersettings_front // Begin Usersettings rewrite.
 
 		$text .= $tp->parseTemplate($USERSETTINGS_EDIT, true, $this->sc); //ParseSC must be set to true so that custom plugin -shortcodes can be utilized.
 
 
 		$text .= "<div><input type='hidden' name='_uid' value='{$uuid}' /></div>
+				<input type='hidden' name='e-token' value='".defset('e_TOKEN')."' />
 		</form>
 		";
 
 		$caption = (isset($USERSETTINGS_EDIT_CAPTION)) ? $USERSETTINGS_EDIT_CAPTION : LAN_USET_39; // 'Update User Settings'
 
 		$ns->tablerender($caption, $text);
 
 
-
-
-
 	}
 
 
 
 

Vulnerable code: 
		//$text = (is_numeric($_uid) ? $rs->form_open("post", e_SELF."?".e_QUERY, "dataform", "", " class='form-horizontal' role='form' enctype='multipart/form-data'") : $rs->form_open("post", e_SELF, "dataform", "", " class='form-horizontal' role='form' enctype='multipart/form-data'"));




Fixed code: if(!empty($_POST) && !isset($_POST['e-token']))
{
	$_POST['e-token'] = '';
}
				<input type='hidden' name='e-token' value='".defset('e_TOKEN')."' />
				<input type='hidden' name='e-token' value='".defset('e_TOKEN')."' />