CVE-2022-4408: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site Scripting (XSS) - Stored in GitHub repository thorsten/phpmyfaq prior to 3.1.9.
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: 2022-12-11T15:15Z
Repository: https://github.com/thorsten/phpmyfaq
Language: PHP
Files changed: CHANGELOG.md, phpmyfaq/admin/record.questions.php, phpmyfaq/ajaxservice.php, phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php
Commit date: 2022-11-25 16:31:00 +0100
Commit message: fix: added missing escaping of strings

Diff: diff --git a/CHANGELOG.md b/CHANGELOG.md
index 80344d6f69..a723bde9c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,18 @@
-# phpMyFAQ 3.1.8
+# phpMyFAQ 3.1.9
 
 **Codename "Poseidon"**
 
 ## CHANGELOG
 
 This is a log of major user-visible changes in each phpMyFAQ release.
 
+### phpMyFAQ v3.1.9 - 2022-11-
+
+- fixed multiple security vulnerabilities (Thorsten)
+- fixed minor bugs (Thorsten)
+
 ### phpMyFAQ v3.1.8 - 2022-10-24
 
 - fixed multiple security vulnerabilities (Thorsten)
 - fixed minor bugs (Thorsten)
 
diff --git a/phpmyfaq/admin/record.questions.php b/phpmyfaq/admin/record.questions.php
index 36c9d68cc3..61a4b43524 100644
--- a/phpmyfaq/admin/record.questions.php
+++ b/phpmyfaq/admin/record.questions.php
@@ -17,10 +17,11 @@
 
 use phpMyFAQ\Category;
 use phpMyFAQ\Date;
 use phpMyFAQ\Filter;
 use phpMyFAQ\Question;
+use phpMyFAQ\Strings;
 
 if (!defined('IS_VALID_PHPMYFAQ')) {
     http_response_code(400);
     exit();
 }
@@ -93,11 +94,11 @@ if (!defined('IS_VALID_PHPMYFAQ')) {
                       </a>
                     </td>
                     <td>
                       <strong><?= $category->categoryName[$openQuestion->getCategoryId()]['name'] ?></strong>
                       <br>
-                        <?= $openQuestion->getQuestion() ?>
+                        <?= Strings::htmlentities($openQuestion->getQuestion()) ?>
                     </td>
                     <td>
                       <a href="?action=question&amp;id=<?= $openQuestion->getId() ?>&amp;is_visible=toggle&csrf=<?= $user->getCsrfTokenFromSession() ?>"
                          class="btn btn-info">
                           <?= ('Y' === $openQuestion->isVisible()) ? $PMF_LANG['ad_gen_yes'] : $PMF_LANG['ad_gen_no'] ?>
diff --git a/phpmyfaq/ajaxservice.php b/phpmyfaq/ajaxservice.php
index 6be4d240dc..2d0044b8fe 100644
--- a/phpmyfaq/ajaxservice.php
+++ b/phpmyfaq/ajaxservice.php
@@ -505,11 +505,11 @@ switch ($action) {
 
             $questionData = [
                 'username' => $author,
                 'email' => $email,
                 'category_id' => $ucategory,
-                'question' => $question,
+                'question' => Strings::htmlspecialchars($question),
                 'is_visible' => $visibility
             ];
 
             if (false === (bool)$save) {
                 $cleanQuestion = $stopWords->clean($question);
@@ -569,16 +569,24 @@ switch ($action) {
                     $response .= '</ul>';
 
                     $message = ['result' => $response];
                 } else {
                     $questionHelper = new QuestionHelper($faqConfig, $cat);
-                    $questionHelper->sendSuccessMail($questionData, $categories);
+                    try {
+                        $questionHelper->sendSuccessMail($questionData, $categories);
+                    } catch (Exception $e) {
+                        // @todo Handle exception
+                    }
                     $message = ['success' => $PMF_LANG['msgAskThx4Mail']];
                 }
             } else {
                 $questionHelper = new QuestionHelper($faqConfig, $cat);
-                $questionHelper->sendSuccessMail($questionData, $categories);
+                try {
+                    $questionHelper->sendSuccessMail($questionData, $categories);
+                } catch (Exception $e) {
+                    // @todo Handle exception
+                }
                 $message = ['success' => $PMF_LANG['msgAskThx4Mail']];
             }
         } else {
             $message = ['error' => $PMF_LANG['err_SaveQuestion']];
         }
diff --git a/phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php b/phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php
index 491c77f82c..674a28bdca 100644
--- a/phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php
+++ b/phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php
@@ -17,10 +17,11 @@
 
 namespace phpMyFAQ\Helper;
 
 use phpMyFAQ\Category;
 use phpMyFAQ\Configuration;
+use phpMyFAQ\Core\Exception;
 use phpMyFAQ\Mail;
 use phpMyFAQ\Question;
 use phpMyFAQ\User;
 
 /**
@@ -51,13 +52,14 @@ class QuestionHelper
         $this->translation = $PMF_LANG;
     }
 
     /**
      * @param array $questionData
-     * @param $categories
+     * @param array $categories
+     * @throws Exception
      */
-    public function sendSuccessMail(array $questionData, $categories)
+    public function sendSuccessMail(array $questionData, array $categories): void
     {
         $questionObject = new Question($this->config);
         $questionObject->addQuestion($questionData);
 
         $questionMail = 'User: ' . $questionData['username'] .

Vulnerable code: # phpMyFAQ 3.1.8
                        <?= $openQuestion->getQuestion() ?>
                'question' => $question,
                    $questionHelper->sendSuccessMail($questionData, $categories);
                $questionHelper->sendSuccessMail($questionData, $categories);
     * @param $categories
    public function sendSuccessMail(array $questionData, $categories)
Fixed code: # phpMyFAQ 3.1.9
### phpMyFAQ v3.1.9 - 2022-11-

- fixed multiple security vulnerabilities (Thorsten)
- fixed minor bugs (Thorsten)

use phpMyFAQ\Strings;
                        <?= Strings::htmlentities($openQuestion->getQuestion()) ?>
                'question' => Strings::htmlspecialchars($question),
                    try {
                        $questionHelper->sendSuccessMail($questionData, $categories);
                    } catch (Exception $e) {
                        // @todo Handle exception
                    }
                try {
                    $questionHelper->sendSuccessMail($questionData, $categories);
                } catch (Exception $e) {
                    // @todo Handle exception
                }
use phpMyFAQ\Core\Exception;
     * @param array $categories
     * @throws Exception
    public function sendSuccessMail(array $questionData, array $categories): void