CVE-2023-1754: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Improper Neutralization of Input During Web Page Generation in GitHub repository thorsten/phpmyfaq prior to 3.1.12.
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.7
Published: 2023-03-31T01:15Z
Repository: https://github.com/thorsten/phpmyfaq
Language: PHP
Files changed: phpmyfaq/admin/group.php
Commit date: 2023-03-10 07:13:21 +0100
Commit message: fix: added missing conversion to HTML entities, removed obsolete code

Diff: diff --git a/phpmyfaq/admin/group.php b/phpmyfaq/admin/group.php
index df01845b88..d7e948ea5a 100644
--- a/phpmyfaq/admin/group.php
+++ b/phpmyfaq/admin/group.php
@@ -16,10 +16,11 @@
  * @link https://www.phpmyfaq.de
  * @since 2005-12-15
  */
 
 use phpMyFAQ\Filter;
+use phpMyFAQ\Strings;
 use phpMyFAQ\User;
 use phpMyFAQ\User\CurrentUser;
 
 if (!defined('IS_VALID_PHPMYFAQ')) {
     http_response_code(400);
@@ -169,11 +170,11 @@ if ($groupAction == 'delete_confirm' && $user->perm->hasPermission($user->getUse
         ?>
       <header class="row">
         <div class="col-lg-12">
           <h2 class="page-header">
             <i aria-hidden="true" class="fa fa-users fa-fw"></i>
-              <?= $PMF_LANG['ad_group_deleteGroup'] ?> "<?= $groupData['name'] ?>"
+              <?= $PMF_LANG['ad_group_deleteGroup'] ?> "<?= Strings::htmlentities($groupData['name']) ?>"
           </h2>
         </div>
       </header>
 
       <div class="row">
@@ -224,21 +225,21 @@ if ($groupAction == 'delete' && $user->perm->hasPermission($user->getUserId(), '
 
 if ($groupAction == 'addsave' && $user->perm->hasPermission($user->getUserId(), 'addgroup')) {
     $user = new User($faqConfig);
     $message = '';
     $messages = [];
-    $groupName = Filter::filterInput(INPUT_POST, 'group_name', FILTER_UNSAFE_RAW, '');
-    $groupDescription = Filter::filterInput(INPUT_POST, 'group_description', FILTER_UNSAFE_RAW, '');
+    $groupName = Filter::filterInput(INPUT_POST, 'group_name', FILTER_SANITIZE_SPECIAL_CHARS, '');
+    $groupDescription = Filter::filterInput(INPUT_POST, 'group_description', FILTER_SANITIZE_SPECIAL_CHARS, '');
     $groupAutoJoin = Filter::filterInput(INPUT_POST, 'group_auto_join', FILTER_UNSAFE_RAW, '');
     $csrfOkay = true;
     $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_UNSAFE_RAW);
 
     if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) {
         $csrfOkay = false;
     }
     // check group name
-    if ($groupName == '') {
+    if ($groupName === '') {
         $messages[] = $PMF_LANG['ad_group_error_noName'];
     }
     // ok, let's go
     if (count($messages) == 0 && $csrfOkay) {
         // create group
@@ -334,64 +335,10 @@ if ($groupAction == 'add' && $user->perm->hasPermission($user->getUserId(), 'add
     </div>
   </div>
     <?php
 }
 
-// Import LDAP groups
-/*
-if ('import-ldap-groups' === $groupAction && $user->perm->hasPermission($user->getUserId(), 'addgroup')) {
-    $user = new CurrentUser($faqConfig);
-    $message = '';
-    $messages = [];
-
-    // Temporary data
-    $groupName = 'LDAP Group';
-    $groupDescription = 'This is a LDAP group import demo';
-    $groupAutoJoin = false;
-
-    $csrfOkay = true;
-    $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_UNSAFE_RAW);
-
-    if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) {
-        $csrfOkay = false;
-    }
-
-    // check group name
-    if ($groupName == '') {
-        $messages[] = $PMF_LANG['ad_group_error_noName'];
-    }
-
-    // ok, let's go
-    if (count($messages) == 0 && $csrfOkay) {
-        // create group
-        $groupData = [
-            'name' => $groupName,
-            'description' => $groupDescription,
-            'auto_join' => $groupAutoJoin,
-        ];
-
-        if ($user->perm->addGroup($groupData) <= 0) {
-            $messages[] = $PMF_LANG['ad_adus_dberr'];
-        }
-    }
-
-    // no errors, show list
-    if (count($messages) == 0) {
-        $groupAction = $defaultGroupAction;
-        $message = sprintf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_group_suc']);
-        // display error messages and show form again
-    } else {
-        $groupAction = 'import-ldap-groups';
-        $message = '<p class="alert alert-danger">';
-        foreach ($messages as $err) {
-            $message .= $err . '<br>';
-        }
-        $message .= '</p>';
-    }
-}
-*/
-
 // show list of users
 if ('list' === $groupAction) {
     ?>
   <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
     <h1 class="h2">
@@ -414,24 +361,10 @@ if ('list' === $groupAction) {
 
   <div class="row">
 
     <div class="col-lg-4" id="group_list">
 
-      <!--
-      <div class="card mb-4">
-        <div class="card-header py-3">
-          <form id="group-import-ldap-groups" method="post"
-                name="group-import-ldap-groups" action="?action=group&amp;group_action=import-ldap-groups">
-            <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>">
-            <button class="btn btn-success" type="submit">
-              Import LDAP groups
-            </button>
-          </form>
-        </div>
-      </div>
-      -->
-
       <div class="card mb-4">
         <form id="group_select" name="group_select" action="?action=group&amp;group_action=delete_confirm"
               method="post">
           <h5 class="card-header py-3">
             <i aria-hidden="true" class="fa fa-users"></i> <?= $PMF_LANG['ad_groups'] ?>

Vulnerable code:               <?= $PMF_LANG['ad_group_deleteGroup'] ?> "<?= $groupData['name'] ?>"
    $groupName = Filter::filterInput(INPUT_POST, 'group_name', FILTER_UNSAFE_RAW, '');
    $groupDescription = Filter::filterInput(INPUT_POST, 'group_description', FILTER_UNSAFE_RAW, '');
    if ($groupName == '') {
// Import LDAP groups
/*
if ('import-ldap-groups' === $groupAction && $user->perm->hasPermission($user->getUserId(), 'addgroup')) {
    $user = new CurrentUser($faqConfig);
    $message = '';
    $messages = [];

    // Temporary data
    $groupName = 'LDAP Group';
    $groupDescription = 'This is a LDAP group import demo';
    $groupAutoJoin = false;

    $csrfOkay = true;
    $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_UNSAFE_RAW);

    if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) {
        $csrfOkay = false;
    }

    // check group name
    if ($groupName == '') {
        $messages[] = $PMF_LANG['ad_group_error_noName'];
    }

    // ok, let's go
    if (count($messages) == 0 && $csrfOkay) {
        // create group
        $groupData = [
            'name' => $groupName,
            'description' => $groupDescription,
            'auto_join' => $groupAutoJoin,
        ];

        if ($user->perm->addGroup($groupData) <= 0) {
            $messages[] = $PMF_LANG['ad_adus_dberr'];
        }
    }

    // no errors, show list
    if (count($messages) == 0) {
        $groupAction = $defaultGroupAction;
        $message = sprintf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_group_suc']);
        // display error messages and show form again
    } else {
        $groupAction = 'import-ldap-groups';
        $message = '<p class="alert alert-danger">';
        foreach ($messages as $err) {
            $message .= $err . '<br>';
        }
        $message .= '</p>';
    }
}
*/

      <!--
      <div class="card mb-4">
        <div class="card-header py-3">
          <form id="group-import-ldap-groups" method="post"
                name="group-import-ldap-groups" action="?action=group&amp;group_action=import-ldap-groups">
            <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>">
            <button class="btn btn-success" type="submit">
              Import LDAP groups
            </button>
          </form>
        </div>
      </div>
      -->

Fixed code: use phpMyFAQ\Strings;
              <?= $PMF_LANG['ad_group_deleteGroup'] ?> "<?= Strings::htmlentities($groupData['name']) ?>"
    $groupName = Filter::filterInput(INPUT_POST, 'group_name', FILTER_SANITIZE_SPECIAL_CHARS, '');
    $groupDescription = Filter::filterInput(INPUT_POST, 'group_description', FILTER_SANITIZE_SPECIAL_CHARS, '');
    if ($groupName === '') {