CVE-2021-4132: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: livehelperchat is vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2021-12-17T13:15Z
Repository: https://github.com/livehelperchat/livehelperchat
Language: PHP
Files changed: lhc_web/design/defaulttheme/tpl/lhuser/edit.tpl.php, lhc_web/design/defaulttheme/tpl/lhuser/new.tpl.php, lhc_web/design/defaulttheme/tpl/lhuser/parts/avatar_build.tpl.php, lhc_web/lib/core/lhuser/lhuservalidator.php
Commit date: 2021-12-17 01:46:47 -0500
Commit message: ng-non-bindable for user account fields

Diff: diff --git a/lhc_web/design/defaulttheme/tpl/lhuser/edit.tpl.php b/lhc_web/design/defaulttheme/tpl/lhuser/edit.tpl.php
index 43ba38f0c9..3f5ae2023b 100644
--- a/lhc_web/design/defaulttheme/tpl/lhuser/edit.tpl.php
+++ b/lhc_web/design/defaulttheme/tpl/lhuser/edit.tpl.php
@@ -45,18 +45,18 @@
 
 	   <div class="explain"><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Do not enter a password unless you want to change it');?></div>
 	   <br />
 
 	   <form action="<?php echo erLhcoreClassDesign::baseurl('user/edit')?>/<?php echo $user->id?>#account" method="post" autocomplete="off" enctype="multipart/form-data">
-	        
+
 	        <?php include(erLhcoreClassDesign::designtpl('lhuser/account/above_new_account_form_multiinclude.tpl.php'));?>
-	        
+
 	        <div class="form-group">
     		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Username');?>*</label>
     		  <input <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" type="text" ng-non-bindable name="Username" value="<?php echo htmlspecialchars($user->username);?>" />
     		</div>
-    		
+
     		<div class="form-group">
         		<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Password');?></label>
         		<input ng-non-bindable autocomplete="new-password" type="password" <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="Password" value="<?php echo htmlspecialchars(isset($user->password_temp_1) ? $user->password_temp_1 : '');?>" />
     		</div>
 
@@ -80,50 +80,50 @@
 
     		<div class="form-group">
         		<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','E-mail');?></label>
         		<input type="text" ng-non-bindable <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="Email" value="<?php echo $user->email;?>"/>
     		</div>
-    		
+
     		<div class="form-group">
 				<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Chat nickname');?></label>
 				<input type="text" ng-non-bindable <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="ChatNickname" value="<?php echo htmlspecialchars($user->chat_nickname);?>" />
 			</div>
-			
+
     		<div class="form-group">
     		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Name');?></label>
     		  <input type="text" ng-non-bindable <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="Name" value="<?php echo htmlspecialchars($user->name);?>"/>
     		</div>
-    		
+
     		<div class="form-group">
     		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Surname');?></label>
     		  <input type="text" ng-non-bindable <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="Surname" value="<?php echo htmlspecialchars($user->surname);?>"/>
     		</div>
-    		
+
     		<div class="form-group">
     		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Job title');?></label>
     		  <input type="text" ng-non-bindable <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> class="form-control" name="JobTitle" value="<?php echo htmlspecialchars($user->job_title);?>"/>
     		</div>
-    			    
+
     		<?php include(erLhcoreClassDesign::designtpl('lhuser/parts/time_zone.tpl.php'));?>
-    		
+
     		<div class="row">
-    		
+
     		  <?php include(erLhcoreClassDesign::designtpl('lhuser/account/part/visibility_content.tpl.php'));?>
-    		  
+
     		  <?php include(erLhcoreClassDesign::designtpl('lhuser/account/part/after_visibility_content.tpl.php'));?>
 
               <?php include(erLhcoreClassDesign::designtpl('lhuser/account/part/hidability.tpl.php'));?>
 
     		  <div class="col-4">
         		  <div class="form-group">
         		      <label title="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','User receives other operators permissions request');?>"><input <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> type="checkbox" value="on" name="ReceivePermissionRequest" <?php echo $user->rec_per_req == 1 ? 'checked="checked"' : '' ?> /> <?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','User receives other operators permissions request')?></label>
         		  </div>
     		  </div>
     		</div>
-    		
+
     		<?php include(erLhcoreClassDesign::designtpl('lhuser/account/part/after_permission.tpl.php'));?>
-    		
+
     		<div class="row form-group">
     			<div class="col-md-6">
     				<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Skype');?></label>
     				<input type="text" <?php if ($can_edit_groups === false) : ?>disabled="disabled"<?php endif;?> ng-non-bindable class="form-control" name="Skype" value="<?php echo htmlspecialchars($user->skype);?>"/>
     			</div>
@@ -193,25 +193,25 @@
             <?php endif; ?>
 
             <hr>
     		<label><input type="checkbox" value="on" name="UserDisabled" <?php echo $user->disabled == 1 ? 'checked="checked"' : '' ?> />&nbsp;<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Disabled')?></label><br>
     		<?php endif; ?>
-    		    		    		
+
     		<?php include(erLhcoreClassDesign::designtpl('lhkernel/csfr_token.tpl.php'));?>
-    		
+
     		<?php include(erLhcoreClassDesign::designtpl('lhuser/account/below_account_edit_multiinclude.tpl.php'));?>
 
     		<div class="btn-group" role="group" aria-label="..." <?php if (empty($groupsRequired)) :?>ng-init="accval.validForm=true"<?php endif?> >
 
                 <?php if (!($can_edit_groups === false)) : ?>
                 <input type="submit" class="btn btn-secondary" ng-disabled="!accval.validForm" name="Save_account" value="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Save');?>"/>
     		    <input type="submit" class="btn btn-secondary" ng-disabled="!accval.validForm" name="Update_account" value="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Update');?>"/>
                 <?php endif; ?>
 
     		    <input type="submit" class="btn btn-secondary" name="Cancel_account" value="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Cancel');?>"/>
-        	</div>	
-	
+        	</div>
+
 	   </form>
 	</div>
 
     <?php if (!(isset($can_edit_groups) && $can_edit_groups === false) && (
             erLhcoreClassUser::instance()->hasAccessTo('lhuser','see_user_assigned_departments') ||
@@ -224,12 +224,12 @@
 	<div role="tabpanel" class="tab-pane <?php if ($tab == 'tab_departments') : ?>active<?php endif;?>" id="departments">
 
 		<?php if (isset($account_updated_departaments) && $account_updated_departaments == 'done') : $msg = erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Account updated'); ?>
 			<?php include(erLhcoreClassDesign::designtpl('lhkernel/alert_success.tpl.php'));?>
 		<?php endif; ?>
-		
-		<?php 
+
+		<?php
 		  $userDepartaments = erLhcoreClassUserDep::getUserDepartamentsIndividual($user->id);
 		  $userDepartamentsRead = erLhcoreClassUserDep::getUserDepartamentsIndividual($user->id, true);
 		  $userDepartamentsGroup = erLhcoreClassModelDepartamentGroupUser::getUserGroupsIds($user->id);
 		  $userDepartamentsGroupRead = erLhcoreClassModelDepartamentGroupUser::getUserGroupsIds($user->id, true);
           $departmentEditParams = [
@@ -269,17 +269,17 @@
                               true
                       )
               );
           }
 		?>
-		
+
 		<form action="<?php echo erLhcoreClassDesign::baseurl('user/edit')?>/<?php echo $user->id?>#departments" method="post" enctype="multipart/form-data">
-		
+
 		    <?php include(erLhcoreClassDesign::designtpl('lhuser/account/departments_assignment.tpl.php'));?>
-		    
+
 		    <input type="submit" class="btn btn-secondary" name="UpdateDepartaments_account" value="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/edit','Update');?>"/>
-		</form> 
+		</form>
     </div>
     <?php endif; ?>
 
     <?php if (!(isset($can_edit_groups) && $can_edit_groups === false)) : ?>
 	<div role="tabpanel" class="tab-pane <?php if ($tab == 'tab_pending') : ?>active<?php endif;?>" id="pending">
@@ -316,11 +316,11 @@
     <?php if (erLhcoreClassUser::instance()->hasAccessTo('lhpermission','see_permissions_users')) : ?>
     <div role="tabpanel" class="tab-pane <?php if ($tab == 'tab_permission') : ?>active<?php endif;?>" id="permission">
         <p><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','In order to change operator permissions you have to edit');?> <a href="<?php echo erLhcoreClassDesign::baseurl('permission/roles')?>"><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','roles');?></a>.</p>
 
         <input type="button" class="btn btn-secondary" name="UpdateSpeech_account" onclick="lhinst.showMyPermissions('<?php echo $user->id?>')" value="<?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Show permissions');?>" />
-		<div id="permissions-summary"></div>		
+		<div id="permissions-summary"></div>
     </div>
 	<?php endif;?>
 
     <?php if (!(isset($can_edit_groups) && $can_edit_groups === false)) : ?>
     <div role="tabpanel" class="tab-pane <?php if ($tab == 'tab_speech') : ?>active<?php endif;?>" id="speech">
@@ -348,7 +348,7 @@
         </form>
     </div>
     <?php endif; ?>
 
 	<?php include(erLhcoreClassDesign::designtpl('lhuser/menu_tabs_content/custom_multiinclude_tab.tpl.php'));?>
-	
+
 </div>
diff --git a/lhc_web/design/defaulttheme/tpl/lhuser/new.tpl.php b/lhc_web/design/defaulttheme/tpl/lhuser/new.tpl.php
index 9296c7f6e7..dc7b9112a0 100644
--- a/lhc_web/design/defaulttheme/tpl/lhuser/new.tpl.php
+++ b/lhc_web/design/defaulttheme/tpl/lhuser/new.tpl.php
@@ -26,45 +26,45 @@
 		  <input class="form-control" type="text" name="Username" value="<?php echo htmlspecialchars($user->username);?>" />
 		</div>
 		
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','E-mail');?></label>
-		  <input type="text" class="form-control" name="Email" value="<?php echo htmlspecialchars($user->email);?>"/>
+		  <input type="text" ng-non-bindable class="form-control" name="Email" value="<?php echo htmlspecialchars($user->email);?>"/>
 		</div>
 					
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Password');?></label>
-		  <input type="password" class="form-control" autocomplete="new-password" name="Password" value="<?php echo htmlspecialchars(isset($user->password_temp_1) ? $user->password_temp_1 : '');?>" />
+		  <input type="password" ng-non-bindable class="form-control" autocomplete="new-password" name="Password" value="<?php echo htmlspecialchars(isset($user->password_temp_1) ? $user->password_temp_1 : '');?>" />
 		</div>
 		
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Repeat the new password');?></label>
-		  <input type="password" class="form-control" autocomplete="new-password" name="Password1" value="<?php echo htmlspecialchars(isset($user->password_temp_2) ? $user->password_temp_2 : '');?>" />
+		  <input type="password" ng-non-bindable class="form-control" autocomplete="new-password" name="Password1" value="<?php echo htmlspecialchars(isset($user->password_temp_2) ? $user->password_temp_2 : '');?>" />
 		</div>
 
         <div class="form-group">
             <label><input type="checkbox" value="on" name="ForceResetPassword" <?php echo isset($_POST['ForceResetPassword']) ? 'checked="checked"' : '' ?> /> <?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Force user to change password on login')?></label>
         </div>
 
 		<div class="form-group">
 			<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Chat nickname');?></label>
-			<input type="text" class="form-control" name="ChatNickname" value="<?php echo htmlspecialchars($user->chat_nickname);?>" />
+			<input type="text" class="form-control" ng-non-bindable name="ChatNickname" value="<?php echo htmlspecialchars($user->chat_nickname);?>" />
 		</div>
 		
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Name');?></label>
-		  <input class="form-control" type="text" name="Name" value="<?php echo htmlspecialchars($user->name);?>" />
+		  <input class="form-control" ng-non-bindable type="text" name="Name" value="<?php echo htmlspecialchars($user->name);?>" />
 		</div>
 		
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/new','Surname');?></label>
-		  <input class="form-control" type="text" name="Surname" value="<?php echo htmlspecialchars($user->surname);?>" />
+		  <input class="form-control" ng-non-bindable type="text" name="Surname" value="<?php echo htmlspecialchars($user->surname);?>" />
 		</div>
 		
 		<div class="form-group">
 		  <label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Job title');?></label>
-		  <input type="text" class="form-control" name="JobTitle" value="<?php echo htmlspecialchars($user->job_title);?>"/>
+		  <input type="text" ng-non-bindable class="form-control" name="JobTitle" value="<?php echo htmlspecialchars($user->job_title);?>"/>
 		</div>
 		
 		<?php include(erLhcoreClassDesign::designtpl('lhuser/parts/time_zone.tpl.php'));?>
 		
 		<div class="row">
@@ -85,15 +85,15 @@
 		<?php include(erLhcoreClassDesign::designtpl('lhuser/account/part/after_permission.tpl.php'));?>
 		
 		<div class="row form-group">
 			<div class="col-md-6">
 				<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','Skype');?></label>
-				<input class="form-control" type="text" name="Skype" value="<?php echo htmlspecialchars($user->skype);?>"/>
+				<input class="form-control" ng-non-bindable maxlength="50" type="text" name="Skype" value="<?php echo htmlspecialchars($user->skype);?>"/>
 			</div>
 			<div class="col-md-6">
 				<label><?php echo erTranslationClassLhTranslation::getInstance()->getTranslation('user/account','XMPP username');?></label>
-				<input class="form-control" type="text" name="XMPPUsername" value="<?php echo htmlspecialchars($user->xmpp_username);?>"/>
+				<input class="form-control" ng-non-bindable type="text" name="XMPPUsername" value="<?php echo htmlspecialchars($user->xmpp_username);?>"/>
 			</div>
 		</div>
 
         <div class="row">
             <div class="col-6">
diff --git a/lhc_web/design/defaulttheme/tpl/lhuser/parts/avatar_build.tpl.php b/lhc_web/design/defaulttheme/tpl/lhuser/parts/avatar_build.tpl.php
index 5f9074b68c..5964ea224e 100644
--- a/lhc_web/design/defaulttheme/tpl/lhuser/parts/avatar_build.tpl.php
+++ b/lhc_web/design/defaulttheme/tpl/lhuser/parts/avatar_build.tpl.php
@@ -1,6 +1,6 @@
-<div class="row">
+<div class="row" ng-non-bindable>
     <?php if (!(isset($can_edit_groups) && $can_edit_groups === false)) : ?>
     <div class="col-9">
         <div class="input-group mb-3">
             <div class="input-group-prepend">
         <span class="input-group-text action-image" onclick="lhc.revealModal({'url':WWW_DIR_JAVASCRIPT+'user/avatarbuilder/'+$('#<?php isset($avatarOptions['field_prefix']) ? print $avatarOptions['field_prefix'] : ''?>id_avatar_string').val() + '?prefix=<?php isset($avatarOptions['field_prefix']) ? print $avatarOptions['field_prefix'] : ''?>'})">
diff --git a/lhc_web/lib/core/lhuser/lhuservalidator.php b/lhc_web/lib/core/lhuser/lhuservalidator.php
index dcbf6284d8..12d8efd138 100644
--- a/lhc_web/lib/core/lhuser/lhuservalidator.php
+++ b/lhc_web/lib/core/lhuser/lhuservalidator.php
@@ -175,11 +175,11 @@ class erLhcoreClassUserValidator {
 		} else {
 			$userData->time_zone = '';
 		}
 		
 		if ( $form->hasValidData( 'Skype' ) && $form->Skype != '') {
-			$userData->skype = $form->Skype;
+			$userData->skype = mb_substr($form->Skype,0,50);
 		} else {
 			$userData->skype = '';
 		}
 		
 		if ( $form->hasValidData( 'XMPPUsername' ) && $form->XMPPUsername != '') {
@@ -913,11 +913,11 @@ class erLhcoreClassUserValidator {
 			}
 		}
 		
 		if ( erLhcoreClassUser::instance()->hasAccessTo('lhuser','changeskypenick') ) {
 			if ( $form->hasValidData( 'Skype' ) && $form->Skype != '' ) {
-				$userData->skype = $form->Skype;
+				$userData->skype = mb_substr($form->Skype,0,50);
 			} else {
 				$userData->skype = '';
 			}
 		}
 		

Vulnerable code: 	        
	        
    		
    		
			
    		
    		
    			    
    		
    		
    		  
    		
    		
    		    		    		
    		
        	</div>	
	
		
		<?php 
		
		
		    
		</form> 
		<div id="permissions-summary"></div>		
	
		  <input type="text" class="form-control" name="Email" value="<?php echo htmlspecialchars($user->email);?>"/>
		  <input type="password" class="form-control" autocomplete="new-password" name="Password" value="<?php echo htmlspecialchars(isset($user->password_temp_1) ? $user->password_temp_1 : '');?>" />
		  <input type="password" class="form-control" autocomplete="new-password" name="Password1" value="<?php echo htmlspecialchars(isset($user->password_temp_2) ? $user->password_temp_2 : '');?>" />
			<input type="text" class="form-control" name="ChatNickname" value="<?php echo htmlspecialchars($user->chat_nickname);?>" />
		  <input class="form-control" type="text" name="Name" value="<?php echo htmlspecialchars($user->name);?>" />
		  <input class="form-control" type="text" name="Surname" value="<?php echo htmlspecialchars($user->surname);?>" />
		  <input type="text" class="form-control" name="JobTitle" value="<?php echo htmlspecialchars($user->job_title);?>"/>
				<input class="form-control" type="text" name="Skype" value="<?php echo htmlspecialchars($user->skype);?>"/>
				<input class="form-control" type="text" name="XMPPUsername" value="<?php echo htmlspecialchars($user->xmpp_username);?>"/>
<div class="row">
			$userData->skype = $form->Skype;
				$userData->skype = $form->Skype;
Fixed code: 














        	</div>


		<?php



		</form>
		<div id="permissions-summary"></div>

		  <input type="text" ng-non-bindable class="form-control" name="Email" value="<?php echo htmlspecialchars($user->email);?>"/>
		  <input type="password" ng-non-bindable class="form-control" autocomplete="new-password" name="Password" value="<?php echo htmlspecialchars(isset($user->password_temp_1) ? $user->password_temp_1 : '');?>" />
		  <input type="password" ng-non-bindable class="form-control" autocomplete="new-password" name="Password1" value="<?php echo htmlspecialchars(isset($user->password_temp_2) ? $user->password_temp_2 : '');?>" />
			<input type="text" class="form-control" ng-non-bindable name="ChatNickname" value="<?php echo htmlspecialchars($user->chat_nickname);?>" />
		  <input class="form-control" ng-non-bindable type="text" name="Name" value="<?php echo htmlspecialchars($user->name);?>" />
		  <input class="form-control" ng-non-bindable type="text" name="Surname" value="<?php echo htmlspecialchars($user->surname);?>" />
		  <input type="text" ng-non-bindable class="form-control" name="JobTitle" value="<?php echo htmlspecialchars($user->job_title);?>"/>
				<input class="form-control" ng-non-bindable maxlength="50" type="text" name="Skype" value="<?php echo htmlspecialchars($user->skype);?>"/>
				<input class="form-control" ng-non-bindable type="text" name="XMPPUsername" value="<?php echo htmlspecialchars($user->xmpp_username);?>"/>
<div class="row" ng-non-bindable>
			$userData->skype = mb_substr($form->Skype,0,50);
				$userData->skype = mb_substr($form->Skype,0,50);