CVE-2023-0313 (PHP, published 2023-01-15T22:15Z)
Description: value: Cross-site Scripting (XSS) - Stored in GitHub repository thorsten/phpmyfaq prior to 3.1.10.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
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.
Repository: https://github.com/thorsten/phpmyfaq
Files changed:
phpmyfaq/admin/category.main.php
phpmyfaq/admin/news.php
phpmyfaq/faq.php
phpmyfaq/index.php
phpmyfaq/news.php
phpmyfaq/src/Bootstrap.php
phpmyfaq/src/phpMyFAQ/Category.php
phpmyfaq/src/phpMyFAQ/Database/DatabaseHelper.php
phpmyfaq/src/phpMyFAQ/Helper/CategoryHelper.php
phpmyfaq/src/phpMyFAQ/Helper/FaqHelper.php
phpmyfaq/src/phpMyFAQ/Helper/QuestionHelper.php
phpmyfaq/src/phpMyFAQ/Helper/TagsHelper.php
phpmyfaq/src/phpMyFAQ/News.php
phpmyfaq/src/phpMyFAQ/Utils.php
phpmyfaq/startpage.php
Commit message: fix: added missing conversion to HTML entities


Vulnerable code:
                    'name' => Filter::filterInput(INPUT_POST, 'name', FILTER_UNSAFE_RAW),
                    'description' => Filter::filterInput(INPUT_POST, 'description', FILTER_UNSAFE_RAW),
 * @package phpMyFAQ
 * @author Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author Matteo Scaramuccia <matteo@phpmyfaq.de>
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link https://www.phpmyfaq.de
 * @since 2003-02-23
use phpMyFAQ\News;
                        <label class="col-3 col-form-label" for="authorName"><?= $PMF_LANG['ad_news_author_name'] ?></label>
                        <label class="col-3 col-form-label" for="authorEmail"><?= $PMF_LANG['ad_news_author_email'] ?></label>
                        <label class="col-3 col-form-label" for="comment"><?= $PMF_LANG['ad_news_allowComments'] ?></label>
                            <input class="form-control" type="text" name="link" id="link" placeholder="http://www.example.com/">
                        <label class="col-3 col-form-label" for="linkTitle"><?= $PMF_LANG['ad_news_link_title'] ?></label>
                        <td><?= $newsItem['header'] ?></td>
                                   value="<?= $newsData['header'] ?? '' ?>">
                        <label class="col-3 col-form-label" for="authorName"><?= $PMF_LANG['ad_news_author_name'] ?></label>
                            <input type="text" name="authorName" value="<?= $newsData['authorName'] ?>" class="form-control">
                            <input type="email" name="authorEmail" value="<?= $newsData['authorEmail'] ?>" class="form-control">
                            <input type="text" id="link" name="link" value="<?= $newsData['link'] ?>" class="form-control">
                            <input type="text" id="linkTitle" name="linkTitle" value="<?= $newsData['linkTitle'] ?>"
                            class="form-control">
    $header = Filter::filterInput(INPUT_POST, 'newsheader', FILTER_UNSAFE_RAW);
    $link = Filter::filterInput(INPUT_POST, 'link', FILTER_UNSAFE_RAW);
    $linkTitle = Filter::filterInput(INPUT_POST, 'linkTitle', FILTER_UNSAFE_RAW);
 * @package phpMyFAQ
 * @author Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author Lars Tiedemann <larstiedemann@yahoo.de>
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link https://www.phpmyfaq.de
 * @since 2002-08-27
        'question' => $question,
    'metaPublisher' => $faqConfig->get('main.metaPublisher'),
 * @package phpMyFAQ
 * @author Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author Matteo Scaramuccia <matteo@scaramuccia.com>
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link https://www.phpmyfaq.de
 * @since 2006-07-23
        $news['link'],
        $news['linkTitle']
        'writeHeader' => $newsHeader,
        'mainPageContent' => $newsContent,
        'writeAuthor' => ($news['active'] && (!$expired)) ? $PMF_LANG['msgAuthor'] . ': ' . $news['authorName'] : '',
const DEBUG = false;
        $oLink->itemTitle = $categoryName;
        $oLink->text = $categoryName;
                $categoryName
                $oLink->itemTitle = $category;
                $oLink->tooltip = $description[$key];
    private $config;
                $oLink->itemTitle = $categoryName;
                $oLink->text = $categoryName;
                $oLink->tooltip = $description;
                    $cat['name']
            $categories .= $indent . $cat['name'] . "</option>\n";
                '<p class="card-text">' . $category['description'] . '</p>' .
            $oLink->itemTitle = $categoryName;
            $oLink->text = $categoryName;
            $oLink->tooltip = $description;
     * @param Faq $faq
     * @param string $language
    public function createOverview(Category $category, Faq $faq, $language = ''): string
     * @param  $faqId
     * @param  $faqLang
    private $config;
    private $category;
    private $translation;
 * @package    phpMyFAQ\Helper
 * @subpackage TagsHelper
    private $taggingIds;
        $taggingIds = str_replace($tagId, '', $this->getTaggingIds());
            $tagName
            $tagName
    public function getTaggingIds()
    public function setTaggingIds(array $taggingIds)
            $tagName,
    public function getNews($showArchive = false, $active = true): string
                $oLink->itemTitle = $item['header'];
                $item['header']
            $data['header'],
            $data['content'],
            $data['authorName'],
            $data['link'],
            $data['linkTitle'],
            $data['header'],
            $data['content'],
            $data['authorName'],
            $data['link'],
            $data['linkTitle'],
            $ret = '<code>' . $string . "</code><br>\n";
                $ret .= ': <code>' . $string . "</code><br>\n";

Fixed code:
                    'name' => Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS),
                    'description' => Filter::filterInput(INPUT_POST, 'description', FILTER_SANITIZE_SPECIAL_CHARS),
 * @package   phpMyFAQ
 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author    Matteo Scaramuccia <matteo@phpmyfaq.de>
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link      https://www.phpmyfaq.de
 * @since     2003-02-23
use phpMyFAQ\News;use phpMyFAQ\Strings;
                        <label class="col-3 col-form-label" for="authorName">
                        <?= $PMF_LANG['ad_news_author_name'] ?>
                        </label>
                        <label class="col-3 col-form-label" for="authorEmail">
                        <?= $PMF_LANG['ad_news_author_email'] ?>
                        </label>
                        <label class="col-3 col-form-label" for="comment">
                        <?= $PMF_LANG['ad_news_allowComments'] ?>
                        </label>
                            <input class="form-control" type="text" name="link" id="link"
                            placeholder="http://www.example.com/">
                        <label class="col-3 col-form-label" for="linkTitle">
                        <?= $PMF_LANG['ad_news_link_title'] ?>
                        </label>
                        <td><?= Strings::htmlentities($newsItem['header']) ?></td>
                                   value="<?= Strings::htmlentities($newsData['header']) ?? '' ?>">
                        <label class="col-3 col-form-label" for="authorName">
                        <?= $PMF_LANG['ad_news_author_name'] ?>
                        </label>
                            <input type="text" name="authorName" class="form-control"
                                value="<?= Strings::htmlentities($newsData['authorName']) ?>">
                            <input type="email" name="authorEmail" class="form-control"
                                value="<?= Strings::htmlentities($newsData['authorEmail']) ?>">
                            <input type="text" id="link" name="link"
                            value="<?= Strings::htmlentities($newsData['link']) ?>" class="form-control">
                            <input type="text" id="linkTitle" name="linkTitle"
                            value="<?= Strings::htmlentities($newsData['linkTitle']) ?>" class="form-control">
    $header = Filter::filterInput(INPUT_POST, 'newsheader', FILTER_SANITIZE_SPECIAL_CHARS);
    $link = Filter::filterInput(INPUT_POST, 'link', FILTER_SANITIZE_SPECIAL_CHARS);
    $linkTitle = Filter::filterInput(INPUT_POST, 'linkTitle', FILTER_SANITIZE_SPECIAL_CHARS);
 * @package   phpMyFAQ
 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author    Lars Tiedemann <larstiedemann@yahoo.de>
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link      https://www.phpmyfaq.de
 * @since     2002-08-27
        'question' => Strings::htmlentities($question),
    'metaPublisher' => Strings::htmlspecialchars($faqConfig->get('main.metaPublisher')),
 * @package   phpMyFAQ
 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
 * @author    Matteo Scaramuccia <matteo@scaramuccia.com>
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link      https://www.phpmyfaq.de
 * @since     2006-07-23
use phpMyFAQ\Strings;
        Strings::htmlentities($news['link']),
        Strings::htmlentities($news['linkTitle'])
        'writeHeader' => Strings::htmlentities($newsHeader),
        'mainPageContent' => Strings::htmlentities($newsContent),
        'writeAuthor' => ($news['active'] && (!$expired)) ? $PMF_LANG['msgAuthor'] . ': ' . Strings::htmlentities($news['authorName']) : '',
const DEBUG = true;
        $oLink->itemTitle = Strings::htmlentities($categoryName);
        $oLink->text = Strings::htmlentities($categoryName);
                Strings::htmlentities($categoryName)
                $oLink->itemTitle = Strings::htmlentities($category);
                $oLink->tooltip = Strings::htmlentities($description[$key]);
    private Configuration $config;
                $oLink->itemTitle = Strings::htmlentities($categoryName);
                $oLink->text = Strings::htmlentities($categoryName);
                $oLink->tooltip = !is_null($description) ?? Strings::htmlentities($description);
                    Strings::htmlentities($cat['name'])
            $categories .= $indent . Strings::htmlentities($cat['name']) . "</option>\n";
                '<p class="card-text">' . Strings::htmlentities($category['description']) . '</p>' .
            $oLink->itemTitle = Strings::htmlentities($categoryName);
            $oLink->text = Strings::htmlentities($categoryName);
            $oLink->tooltip = !is_null($description) ?? Strings::htmlentities($description);
     * @param Faq      $faq
     * @param string   $language
    public function createOverview(Category $category, Faq $faq, string $language = ''): string
     * @param int    $faqId
     * @param string $faqLang
    private Configuration $config;
    private Category $category;
    private array $translation;
 * @package    phpMyFAQ
use phpMyFAQ\Strings;
    private array $taggingIds;
        $taggingIds = str_replace((string) $tagId, '', $this->getTaggingIds());
            Strings::htmlentities($tagName)
            Strings::htmlentities($tagName)
    public function getTaggingIds(): array
    public function setTaggingIds(array $taggingIds): void
            Strings::htmlentities($tagName),
    public function getNews(bool $showArchive = false, bool $active = true): string
                $oLink->itemTitle = Strings::htmlentities($item['header']);
                Strings::htmlentities($item['header'])
            $this->config->getDb()->escape($data['header']),
            $this->config->getDb()->escape($data['content']),
            $this->config->getDb()->escape($data['authorName']),
            $this->config->getDb()->escape($data['link']),
            $this->config->getDb()->escape($data['linkTitle']),
            $this->config->getDb()->escape($data['header']),
            $this->config->getDb()->escape($data['content']),
            $this->config->getDb()->escape($data['authorName']),
            $this->config->getDb()->escape($data['link']),
            $this->config->getDb()->escape($data['linkTitle']),
            $ret = '<code>' . Strings::htmlentities($string) . "</code><br>\n";
                $ret .= ': <code>' . Strings::htmlentities($string) . "</code><br>\n";
    $archived = false;