CVE-2020-36636: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability classified as problematic has been found in OpenMRS Admin UI Module up to 1.4.x. Affected is the function sendErrorMessage of the file omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java of the component Account Setup Handler. The manipulation leads to cross site scripting. It is possible to launch the attack remotely. Upgrading to version 1.5.0 is able to address this issue. The name of the patch is 702fbfdac7c4418f23bb5f6452482b4a88020061. It is recommended to upgrade the affected component. VDB-216918 is the identifier assigned to this vulnerability.
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: 6.1
Published: 2022-12-27T23:15Z
Repository: https://github.com/openmrs/openmrs-module-adminui
Language: Java
Files changed: omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java
Commit date: 2020-11-23 13:33:47 +0300
Commit message: RA-1865: Fix possible xss in account setup (#57)


Diff: diff --git a/omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java b/omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java
index 610b379..831c532 100644
--- a/omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java
+++ b/omod/src/main/java/org/openmrs/module/adminui/page/controller/systemadmin/accounts/AccountPageController.java
@@ -93,11 +93,11 @@ public class AccountPageController {
 					@SpringBean("appFrameworkService") AppFrameworkService appFrameworkService)
 	    throws IOException {
 		
 		setModelAttributes(model, account, null, accountService, administrationService, providerManagementService, uu, appFrameworkService);
 		if (account.getPerson().getPersonId() == null) {
-			setJsonFormData(model, account, null);
+			setJsonFormData(model, account, null, uu);
 		}
 	}
 	
 	/**
 	 * @param account
@@ -220,11 +220,11 @@ public class AccountPageController {
 		    providerManagementService, uu, appFrameworkService);
 		
 		sendErrorMessage(errors, model, messageSourceService, request);
 		
 		if (account.getPerson().getPersonId() == null) {
-			setJsonFormData(model, account, otherAccountData);
+			setJsonFormData(model, account, otherAccountData, uu);
 		}
 		
 		return "systemadmin/accounts/account";
 		
 	}
@@ -408,25 +408,25 @@ public class AccountPageController {
 		}
 		errorMessage.append("</ul>");
 		request.getSession().setAttribute(UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, errorMessage.toString());
 	}
 	
-	private void setJsonFormData(PageModel model, Account account, OtherAccountData otherAccountData) throws IOException {
+	private void setJsonFormData(PageModel model, Account account, OtherAccountData otherAccountData, UiUtils uu) throws IOException {
 		
 		ObjectMapper mapper = new ObjectMapper();
 		SimpleObject simplePerson = new SimpleObject();
-		simplePerson.put("familyName", account.getFamilyName());
-		simplePerson.put("givenName", account.getGivenName());
-		simplePerson.put("gender", account.getGender() != null ? account.getGender() : "");
+		simplePerson.put("familyName", uu.encodeHtml(account.getFamilyName()));
+		simplePerson.put("givenName", uu.encodeHtml(account.getGivenName()));
+		simplePerson.put("gender", uu.encodeHtml(account.getGender()) != null ? uu.encodeHtml(account.getGender()) : "");
 		model.addAttribute("personJson", mapper.writeValueAsString(simplePerson));
 		
 		SimpleObject simpleUser = new SimpleObject();
 		SimpleObject simpleProvider = new SimpleObject();
 		if (otherAccountData != null) {
 			if (otherAccountData.getAddUserAccount()) {
 				User u = account.getUserAccounts().get(0);
-				simpleUser.put("username", u.getUsername());
+				simpleUser.put("username", uu.encodeHtml(u.getUsername()));
 				simpleUser.put("privilegeLevel", account.getPrivilegeLevel(u).getUuid());
 				SimpleObject userProperties = new SimpleObject();
 				userProperties
 				        .put(OpenmrsConstants.USER_PROPERTY_CHANGE_PASSWORD, otherAccountData.getForceChangePassword());
 				simpleUser.put("userProperties", userProperties);

Vulnerable code: 			setJsonFormData(model, account, null);
			setJsonFormData(model, account, otherAccountData);
	private void setJsonFormData(PageModel model, Account account, OtherAccountData otherAccountData) throws IOException {
		simplePerson.put("familyName", account.getFamilyName());
		simplePerson.put("givenName", account.getGivenName());
		simplePerson.put("gender", account.getGender() != null ? account.getGender() : "");
				simpleUser.put("username", u.getUsername());
Fixed code: 			setJsonFormData(model, account, null, uu);
			setJsonFormData(model, account, otherAccountData, uu);
	private void setJsonFormData(PageModel model, Account account, OtherAccountData otherAccountData, UiUtils uu) throws IOException {
		simplePerson.put("familyName", uu.encodeHtml(account.getFamilyName()));
		simplePerson.put("givenName", uu.encodeHtml(account.getGivenName()));
		simplePerson.put("gender", uu.encodeHtml(account.getGender()) != null ? uu.encodeHtml(account.getGender()) : "");
				simpleUser.put("username", uu.encodeHtml(u.getUsername()));