CVE-2023-0306: 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.10.
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-01-15T22:15Z
Repository: https://github.com/thorsten/phpmyfaq
Language: PHP
Files changed: phpmyfaq/admin/record.edit.php, phpmyfaq/admin/record.show.php, phpmyfaq/src/phpMyFAQ/Faq.php, phpmyfaq/src/phpMyFAQ/Tags.php
Commit date: 2023-01-09 12:21:31 +0100
Commit message: fix: added missing conversion to HTML entities

Diff: diff --git a/phpmyfaq/admin/record.edit.php b/phpmyfaq/admin/record.edit.php
index 5133a5f2c0..2589fe02bd 100644
--- a/phpmyfaq/admin/record.edit.php
+++ b/phpmyfaq/admin/record.edit.php
@@ -650,11 +650,11 @@ if (
                                                         $date->format(date('Y-m-d H:i', $entry['date'])),
                                                         $entryUser->getUserData('display_name')
                                                     );
                                                     ?>
                                                     <br>
-                                                    <?= $entry['changelog'] ?>
+                                                    <?= Strings::htmlentities($entry['changelog']) ?>
                                                 </li>
                                             <?php } ?>
                                         </ul>
                                     </div>
                                 </div>
diff --git a/phpmyfaq/admin/record.show.php b/phpmyfaq/admin/record.show.php
index a540aed302..6c2be6196f 100644
--- a/phpmyfaq/admin/record.show.php
+++ b/phpmyfaq/admin/record.show.php
@@ -26,10 +26,11 @@ use phpMyFAQ\Filter;
 use phpMyFAQ\Helper\CategoryHelper;
 use phpMyFAQ\Helper\FaqHelper;
 use phpMyFAQ\Language;
 use phpMyFAQ\LinkVerifier;
 use phpMyFAQ\Search\SearchFactory;
+use phpMyFAQ\Strings;
 use phpMyFAQ\Visits;
 
 if (!defined('IS_VALID_PHPMYFAQ')) {
     http_response_code(400);
     exit();
@@ -454,12 +455,13 @@ if ($user->perm->hasPermission($user->getUserId(), 'edit_faq') || $user->perm->h
                         <?= $record['solution_id'] ?>
                         </a>
                       </td>
                       <td>
                         <a href="?action=editentry&id=<?= $record['id'] ?>&lang=<?= $record['lang'] ?>"
-                           title="<?= $PMF_LANG['ad_user_edit'] ?> '<?= str_replace('"', '´', $record['title']) ?>'">
-                        <?= $record['title'] ?>
+                           title="<?= $PMF_LANG['ad_user_edit'] ?> '
+                           <?= str_replace('"', '´', Strings::htmlentities($record['title'])) ?>'">
+                        <?= Strings::htmlentities($record['title']) ?>
                         </a>
             <?php
             if (isset($numCommentsByFaq[$record['id']])) {
                 printf(
                     '<br><a class="badge badge-primary" href="?action=comments#record_id_%d">%d %s</a>',
diff --git a/phpmyfaq/src/phpMyFAQ/Faq.php b/phpmyfaq/src/phpMyFAQ/Faq.php
index 9de64aef5f..d7260cbeb4 100755
--- a/phpmyfaq/src/phpMyFAQ/Faq.php
+++ b/phpmyfaq/src/phpMyFAQ/Faq.php
@@ -2008,12 +2008,12 @@ class Faq
         $output = [];
 
         if (count($result) > 0) {
             foreach ($result as $row) {
                 $output['url'][] = Strings::htmlentities($row['url']);
-                $output['title'][] = Utils::makeShorterText($row['question'], 8);
-                $output['preview'][] = $row['question'];
+                $output['title'][] = Strings::htmlentities(Utils::makeShorterText($row['question'], 8));
+                $output['preview'][] = Strings::htmlentities($row['question']);
                 $output['date'][] = $date->format($row['date']);
             }
         } else {
             $output['error'] = $this->translation['err_noArticles'];
         }
diff --git a/phpmyfaq/src/phpMyFAQ/Tags.php b/phpmyfaq/src/phpMyFAQ/Tags.php
index f33e2583c8..64370e61fe 100644
--- a/phpmyfaq/src/phpMyFAQ/Tags.php
+++ b/phpmyfaq/src/phpMyFAQ/Tags.php
@@ -366,11 +366,11 @@ class Tags
 
         foreach ($tagList as $tagId => $tagName) {
             $totFaqByTag = count($this->getFaqsByTagName($tagName));
             if ($totFaqByTag > 0) {
                 $tags[$tagName]['id'] = $tagId;
-                $tags[$tagName]['name'] = $tagName;
+                $tags[$tagName]['name'] = Strings::htmlentities($tagName);
                 $tags[$tagName]['count'] = $totFaqByTag;
             }
         }
 
         $html = '';
@@ -481,11 +481,11 @@ class Tags
             $tagName = $this->getTagNameById($tagId);
             $html .= sprintf(
                 '<a class="btn btn-primary m-1" href="?action=search&tagging_id=%d">%s ' .
                 '<span class="badge badge-info">%d</span></a>',
                 $tagId,
-                $tagName,
+                Strings::htmlentities($tagName),
                 $tagFreq
             );
         }
 
         return $html;

Vulnerable code:                                                     <?= $entry['changelog'] ?>
                           title="<?= $PMF_LANG['ad_user_edit'] ?> '<?= str_replace('"', '´', $record['title']) ?>'">
                        <?= $record['title'] ?>
                $output['title'][] = Utils::makeShorterText($row['question'], 8);
                $output['preview'][] = $row['question'];
                $tags[$tagName]['name'] = $tagName;
                $tagName,
Fixed code:                                                     <?= Strings::htmlentities($entry['changelog']) ?>
use phpMyFAQ\Strings;
                           title="<?= $PMF_LANG['ad_user_edit'] ?> '
                           <?= str_replace('"', '´', Strings::htmlentities($record['title'])) ?>'">
                        <?= Strings::htmlentities($record['title']) ?>
                $output['title'][] = Strings::htmlentities(Utils::makeShorterText($row['question'], 8));
                $output['preview'][] = Strings::htmlentities($row['question']);
                $tags[$tagName]['name'] = Strings::htmlentities($tagName);
                Strings::htmlentities($tagName),