CVE-2022-24851: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: LDAP Account Manager (LAM) is an open source web frontend for managing entries stored in an LDAP directory. The profile editor tool has an edit profile functionality, the parameters on this page are not properly sanitized and hence leads to stored XSS attacks. An authenticated user can store XSS payloads in the profiles, which gets triggered when any other user try to access the edit profile page. The pdf editor tool has an edit pdf profile functionality, the logoFile parameter in it is not properly sanitized and an user can enter relative paths like ../../../../../../../../../../../../../usr/share/icons/hicolor/48x48/apps/gvim.png via tools like burpsuite. Later when a pdf is exported using the edited profile the pdf icon has the image on that path(if image is present). Both issues require an attacker to be able to login to LAM admin interface. The issue is fixed in version 7.9.1.
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: 4.8
Published: 2022-04-15T19:15Z
Repository: https://github.com/LDAPAccountManager/lam
Language: Other
Files changed: lam/HISTORY, lam/lib/html.inc, lam/templates/pdfedit/pdfpage.php
Commit date: 2022-04-11 20:40:13 +0200
Commit message: #170 fixed security issues in profile editor and PDF editor

Diff: diff --git a/lam/HISTORY b/lam/HISTORY
index 0e811fac7..789b2aa09 100644
--- a/lam/HISTORY
+++ b/lam/HISTORY
@@ -1,9 +1,10 @@
 June 2022 8.0
   - Extended user account status and locking options
   - Fixed bugs:
    -> Hidden account is displayed (257)
+   -> Security issues in PDF editor and profile editor
 
 09.03.2022 7.9
   - Tree view:
    -> Support multiple roots (e.g. add "cn=config")
    -> Added function to check password hashes against a given password
diff --git a/lam/lib/html.inc b/lam/lib/html.inc
index 83e78b699..d05bb7c5a 100644
--- a/lam/lib/html.inc
+++ b/lam/lib/html.inc
@@ -556,14 +556,14 @@ class htmlInputField extends htmlElement {
 		if ($this->isAutoTrim()) {
 			$this->cssClasses[] = 'lam-autotrim';
 		}
 		if (isset($values[$this->fieldName])) {
 			if (isObfuscatedText($values[$this->fieldName][0])) {
-				$this->fieldValue = deobfuscateText($values[$this->fieldName][0]);
+				$this->fieldValue = htmlspecialchars(deobfuscateText($values[$this->fieldName][0]));
 			}
 			else {
-				$this->fieldValue = $values[$this->fieldName][0];
+				$this->fieldValue = htmlspecialchars($values[$this->fieldName][0]);
 			}
 		}
 		$validators = array();
 		if ($this->required) {
 			$validators[] = 'required';
diff --git a/lam/templates/pdfedit/pdfpage.php b/lam/templates/pdfedit/pdfpage.php
index 7b5be430b..7d11c44c3 100644
--- a/lam/templates/pdfedit/pdfpage.php
+++ b/lam/templates/pdfedit/pdfpage.php
@@ -11,21 +11,22 @@ use \htmlSelect;
 use \htmlInputField;
 use \htmlSubTitle;
 use \htmlResponsiveInputTextarea;
 use \htmlHiddenInput;
 use \htmlSpacer;
+use LAM\PDF\PdfLogo;
 use LAM\PDF\PdfStructurePersistenceManager;
 use LAM\PDF\PDFTextSection;
 use LAM\PDF\PDFEntrySection;
 use LAM\PDF\PDFStructure;
 use LAM\PDF\PDFSectionEntry;
 use LAMException;
 
 /*
   This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
   Copyright (C) 2003 - 2006  Michael Duergner
-                2007 - 2021  Roland Gruber
+                2007 - 2022  Roland Gruber
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
@@ -130,12 +131,13 @@ if (!isset($_SESSION['currentPDFStructure'])) {
 		metaRefresh('pdfmain.php?loadFailed=1&name=' . $_GET['edit']);
 		exit;
 	}
 }
 
+$logoFiles = $pdfStructurePersistenceManager->getPdfLogos($_SESSION['config']->getName(), true);
 if (!empty($_POST['form_submit'])) {
-	updateBasicSettings($_SESSION['currentPDFStructure']);
+	updateBasicSettings($_SESSION['currentPDFStructure'], $logoFiles);
 	updateSectionTitles($_SESSION['currentPDFStructure']);
 	addSection($_SESSION['currentPDFStructure']);
 	addSectionEntry($_SESSION['currentPDFStructure']);
 	removeItem($_SESSION['currentPDFStructure']);
 	moveUp($_SESSION['currentPDFStructure']);
@@ -226,11 +228,10 @@ else if (isset($_POST['pdfname'])) {
 	$structureName = $_POST['pdfname'];
 }
 // headline
 $headline = $_SESSION['currentPDFStructure']->getTitle();
 // logo
-$logoFiles = $pdfStructurePersistenceManager->getPdfLogos($_SESSION['config']->getName(), true);
 $logos = array(_('No logo') => 'none');
 foreach($logoFiles as $logoFile) {
 	$logos[$logoFile->getName() . ' (' . $logoFile->getWidth() . ' x ' . $logoFile->getHeight() . ")"] = $logoFile->getName();
 }
 $selectedLogo = array('printLogo.jpg');
@@ -514,20 +515,32 @@ function translateFieldIDToName($id, $scope, $availablePDFFields) {
 }
 
 /**
  * Updates basic settings such as logo and head line.
  *
- * @param PDFStructure $structure
+ * @param PDFStructure $structure PDF structure
+ * @param PdfLogo[] $logoFiles logos
  */
-function updateBasicSettings(PDFStructure &$structure) {
+function updateBasicSettings(PDFStructure &$structure, array $logoFiles) {
 	// set headline
 	if (isset($_POST['headline'])) {
 		$structure->setTitle(str_replace('<', '', str_replace('>', '', $_POST['headline'])));
 	}
 	// set logo
 	if (isset($_POST['logoFile'])) {
-		$structure->setLogo($_POST['logoFile']);
+	    $fileName = $_POST['logoFile'];
+	    $found = false;
+	    foreach ($logoFiles as $logoFile) {
+	        if ($logoFile->getName() === $fileName) {
+	            $found = true;
+            }
+        }
+	    if (!$found) {
+	        logNewMessage(LOG_ERR, 'Invalid PDF logo file: ' . $fileName);
+	        return;
+        }
+		$structure->setLogo($fileName);
 	}
 	// set folding marks
 	if (isset($_POST['foldingmarks'])) {
 		$structure->setFoldingMarks($_POST['foldingmarks']);
 	}

Vulnerable code: 				$this->fieldValue = deobfuscateText($values[$this->fieldName][0]);
				$this->fieldValue = $values[$this->fieldName][0];
                2007 - 2021  Roland Gruber
	updateBasicSettings($_SESSION['currentPDFStructure']);
$logoFiles = $pdfStructurePersistenceManager->getPdfLogos($_SESSION['config']->getName(), true);
 * @param PDFStructure $structure
function updateBasicSettings(PDFStructure &$structure) {
		$structure->setLogo($_POST['logoFile']);
Fixed code:    -> Security issues in PDF editor and profile editor
				$this->fieldValue = htmlspecialchars(deobfuscateText($values[$this->fieldName][0]));
				$this->fieldValue = htmlspecialchars($values[$this->fieldName][0]);
use LAM\PDF\PdfLogo;
                2007 - 2022  Roland Gruber
$logoFiles = $pdfStructurePersistenceManager->getPdfLogos($_SESSION['config']->getName(), true);
	updateBasicSettings($_SESSION['currentPDFStructure'], $logoFiles);
 * @param PDFStructure $structure PDF structure
 * @param PdfLogo[] $logoFiles logos
function updateBasicSettings(PDFStructure &$structure, array $logoFiles) {
	    $fileName = $_POST['logoFile'];
	    $found = false;
	    foreach ($logoFiles as $logoFile) {
	        if ($logoFile->getName() === $fileName) {
	            $found = true;
            }
        }
	    if (!$found) {
	        logNewMessage(LOG_ERR, 'Invalid PDF logo file: ' . $fileName);
	        return;
        }
		$structure->setLogo($fileName);