CVE-2023-0787: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site Scripting (XSS) - Generic in GitHub repository thorsten/phpmyfaq prior to 3.1.11.


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: 2023-02-12T14:15Z
Repository: https://github.com/thorsten/phpmyfaq
Language: PHP
Files changed: phpmyfaq/src/phpMyFAQ/Faq.php
Commit date: 2023-01-25 08:55:46 +0100
Commit message: fix: added missing conversion to HTML entities

Diff: diff --git a/phpmyfaq/src/phpMyFAQ/Faq.php b/phpmyfaq/src/phpMyFAQ/Faq.php
index d7260cbeb4..34c76297ee 100755
--- a/phpmyfaq/src/phpMyFAQ/Faq.php
+++ b/phpmyfaq/src/phpMyFAQ/Faq.php
@@ -2448,19 +2448,11 @@ class Faq
 
         $date = new Date($this->config);
         $mail = new Mail($this->config);
 
         $query = sprintf(
-            "
-            SELECT
-                COUNT(id) AS num
-            FROM
-                %sfaqquestions
-            WHERE
-                lang = '%s'
-            AND
-                is_visible != 'Y'",
+            "SELECT COUNT(id) AS num FROM %sfaqquestions WHERE lang = '%s' AND is_visible != 'Y'",
             Database::getTablePrefix(),
             $this->config->getLanguage()->getLanguage()
         );
 
         $result = $this->config->getDb()->query($query);
@@ -2476,21 +2468,11 @@ class Faq
         } else {
             $extraout = '';
         }
 
         $query = sprintf(
-            "
-            SELECT
-                *
-            FROM
-                %sfaqquestions
-            WHERE
-                lang = '%s'
-            AND
-                is_visible = 'Y'
-            ORDER BY
-                created ASC",
+            "SELECT * FROM %sfaqquestions WHERE lang = '%s' AND is_visible = 'Y' ORDER BY created ASC",
             Database::getTablePrefix(),
             $this->config->getLanguage()->getLanguage()
         );
 
         $result = $this->config->getDb()->query($query);
@@ -2501,18 +2483,18 @@ class Faq
                 $output .= '<tr class="openquestions">';
                 $output .= sprintf(
                     '<td><small>%s</small><br><a href="mailto:%s">%s</a></td>',
                     $date->format(Date::createIsoDate($row->created)),
                     $mail->safeEmail($row->email),
-                    $row->username
+                    Strings::htmlentities($row->username)
                 );
                 $output .= sprintf(
                     '<td><strong>%s:</strong><br>%s</td>',
                     isset($category->categoryName[$row->category_id]['name']) ?
                         $category->categoryName[$row->category_id]['name'] :
                         '',
-                    strip_tags($row->question)
+                    Strings::htmlentities($row->question)
                 );
                 if ($this->config->get('records.enableCloseQuestion') && $row->answer_id) {
                     $output .= sprintf(
                         '<td><a id="PMF_openQuestionAnswered" href="?%saction=faq&amp;cat=%d&amp;id=%d">%s</a></td>',
                         $sids,

Vulnerable code:             "
            SELECT
                COUNT(id) AS num
            FROM
                %sfaqquestions
            WHERE
                lang = '%s'
            AND
                is_visible != 'Y'",
            "
            SELECT
                *
            FROM
                %sfaqquestions
            WHERE
                lang = '%s'
            AND
                is_visible = 'Y'
            ORDER BY
                created ASC",
                    $row->username
                    strip_tags($row->question)
Fixed code:             "SELECT COUNT(id) AS num FROM %sfaqquestions WHERE lang = '%s' AND is_visible != 'Y'",
            "SELECT * FROM %sfaqquestions WHERE lang = '%s' AND is_visible = 'Y' ORDER BY created ASC",
                    Strings::htmlentities($row->username)
                    Strings::htmlentities($row->question)