CVE-2017-15732 (published 2017-10-22T18:29Z)

In phpMyFAQ before 2.9.9, there is Cross-Site Request Forgery (CSRF) in admin/news.php.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/thorsten/phpMyFAQ
commit_details: repo_url: https://github.com/thorsten/phpMyFAQ
author: Thorsten Rinne
author_date: 2017-10-03 12:30:39+02:00
msg: Added missing CSRF check
repository: repo_url: https://github.com/thorsten/phpMyFAQ
repo_name: thorsten/phpMyFAQ
description: phpMyFAQ - Open Source FAQ web application for PHP 8.1+ and MySQL, PostgreSQL and other databases
repo_language: PHP
owner: thorsten
file_changes: filename: news.php
change_type: ModificationType.MODIFY
diff: @@ -29,12 +29,18 @@ if (!defined('IS_VALID_PHPMYFAQ')) {
 
 $news = new PMF_News($faqConfig);
 
+$csrfToken = PMF_Filter::filterInput(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING);
+if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) {
+    $csrfCheck = false;
+} else {
+    $csrfCheck = true;
+}
+
 if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews')) {
     ?>
         <header class="row">
             <div class="col-lg-12">
-                <h2 class="page-header"><i aria-hidden="true" class="fa fa-pencil"></i> <?php echo $PMF_LANG['ad_news_add'];
-    ?></h2>
+                <h2 class="page-header"><i aria-hidden="true" class="fa fa-pencil"></i> <?php echo $PMF_LANG['ad_news_add'] ?></h2>
             </div>
         </header>
 
@@ -44,8 +50,7 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
 
                     <div class="form-group">
                         <label class="col-lg-2 control-label" for="newsheader">
-                            <?php echo $PMF_LANG['ad_news_header'];
-    ?>
+                            <?php echo $PMF_LANG['ad_news_header'] ?>
                         </label>
                         <div class="col-lg-4">
                             <input class="form-control" type="text" name="newsheader">
@@ -53,8 +58,7 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="news"><?php echo $PMF_LANG['ad_news_text'];
-    ?>:</label>
+                        <label class="col-lg-2 control-label" for="news"><?php echo $PMF_LANG['ad_news_text'] ?>:</label>
                         <div class="col-lg-4">
                             <noscript>Please enable JavaScript to use the WYSIWYG editor!</noscript>
                             <textarea name="news" rows="5" class="form-control"></textarea>
@@ -62,70 +66,59 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="authorName"><?php echo $PMF_LANG['ad_news_author_name'];
-    ?></label>
+                        <label class="col-lg-2 control-label" for="authorName"><?php echo $PMF_LANG['ad_news_author_name'] ?></label>
                         <div class="col-lg-4">
                             <input class="form-control" type="text" name="authorName" id="authorName"
-                                   value="<?php echo $user->getUserData('display_name');
-    ?>"/>
+                                   value="<?php echo $user->getUserData('display_name') ?>">
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="authorEmail"><?php echo $PMF_LANG['ad_news_author_email'];
-    ?></label>
+                        <label class="col-lg-2 control-label" for="authorEmail"><?php echo $PMF_LANG['ad_news_author_email'] ?></label>
                         <div class="col-lg-4">
                             <input class="form-control" type="email" name="authorEmail" id="authorEmail"
-                                   value="<?php echo $user->getUserData('email');
-    ?>"/>
+                                   value="<?php echo $user->getUserData('email') ?>">
                         </div>
                     </div>
 
                     <div class="form-group">
                         <label class="col-lg-2 control-label" for="active">
-                            <?php echo $PMF_LANG['ad_news_set_active'];
-    ?>:
+                            <?php echo $PMF_LANG['ad_news_set_active'] ?>:
                         </label>
                         <div class="col-lg-4 checkbox">
                             <label>
                                 <input type="checkbox" name="active" id="active" value="y">
-                                <?php echo $PMF_LANG['ad_gen_yes'];
-    ?>
+                                <?php echo $PMF_LANG['ad_gen_yes'] ?>
                             </label>
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="comment"><?php echo $PMF_LANG['ad_news_allowComments'];
-    ?></label>
+                        <label class="col-lg-2 control-label" for="comment"><?php echo $PMF_LANG['ad_news_allowComments'] ?></label>
                         <div class="col-lg-4 checkbox">
                             <label>
                                 <input type="checkbox" name="comment" id="comment" value="y">
-                                <?php echo $PMF_LANG['ad_gen_yes'];
-    ?>
+                                <?php echo $PMF_LANG['ad_gen_yes'] ?>
                             </label>
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="link"><?php echo $PMF_LANG['ad_news_link_url'];
-    ?></label>
+                        <label class="col-lg-2 control-label" for="link"><?php echo $PMF_LANG['ad_news_link_url'] ?></label>
                         <div class="col-lg-4">
                             <input class="form-control" type="url" name="link" id="link" placeholder="http://www.example.com/">
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="linkTitle"><?php echo $PMF_LANG['ad_news_link_title'];
-    ?></label>
+                        <label class="col-lg-2 control-label" for="linkTitle"><?php echo $PMF_LANG['ad_news_link_title'] ?></label>
                         <div class="col-lg-4">
                             <input type="text" name="linkTitle" id="linkTitle" class="form-control">
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" ><?php echo $PMF_LANG['ad_news_link_target'];
-    ?></label>
+                        <label class="col-lg-2 control-label" ><?php echo $PMF_LANG['ad_news_link_target'] ?></label>
                         <div class="col-lg-4 radio">
                             <label>
                                 <input type="radio" name="target" value="blank">
@@ -140,16 +133,13 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
                         </div>
                     </div>
                     <div class="form-group">
-                        <label class="col-lg-2 control-label" for="langTo"><?php echo $PMF_LANG['ad_entry_locale'];
-    ?>:</label>
+                        <label class="col-lg-2 control-label" for="langTo"><?php echo $PMF_LANG['ad_entry_locale'] ?>:</label>
                         <div class="col-lg-4">
-                            <?php echo PMF_Language::selectLanguages($LANGCODE, false, [], 'langTo');
-    ?>
+                            <?php echo PMF_Language::selectLanguages($LANGCODE, false, [], 'langTo') ?>
                         </div>
                     </div>
 
-                    <legend><?php echo $PMF_LANG['ad_news_expiration_window'];
-    ?></legend>
+                    <legend><?php echo $PMF_LANG['ad_news_expiration_window'] ?></legend>
                     <div class="form-group">
                         <label class="col-lg-2 control-label" for="dateStart"><?php echo $PMF_LANG['ad_news_from'];
     ?></label>
@@ -594,7 +584,7 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
             <div class="col-lg-12">
 <?php
     $precheck = PMF_Filter::filterInput(INPUT_POST, 'really', FILTER_SANITIZE_STRING, 'no');
-    $delete_id = PMF_Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT);
+    $deleteId = PMF_Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT);
 
     if ('no' == $precheck) {
         ?>
@@ -602,8 +592,8 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
         ?></div>
     <div class="text-center">
     <form action="?action=deletenews" method="post" accept-charset="utf-8">
-    <input type="hidden" name="id" value="<?php echo $delete_id;
-        ?>">
+    <input type="hidden" name="id" value="<?php echo $deleteId ?>">
+    <input type="hidden" name="csrf" value="<?php echo $user->getCsrfTokenFromSession() ?>">
     <input type="hidden" name="really" value="yes">
         <button class="btn btn-warning" type="submit" name="submit">
             <?php echo $PMF_LANG['ad_news_yesdelete'];
@@ -626,10 +616,12 @@ if ('addnews' == $action && $user->perm->checkRight($user->getUserId(), 'addnews
 <?php
 
     } else {
-        $delete_id = PMF_Filter::filterInput(INPUT_POST, 'id', FILTER_VALIDATE_INT);
-        $news->deleteNews($delete_id);
-        printf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_news_delsuc']);
-        printf('<div class="form-group">&rarr; <a href="?action=news">%s</a></p>', $PMF_LANG['msgNews']);
+        if ($csrfCheck) {
+            $deleteId = PMF_Filter::filterInput(INPUT_POST, 'id', FILTER_VALIDATE_INT);
+            $news->deleteNews($deleteId);
+            printf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_news_delsuc']);
+            printf('<div class="form-group">&rarr; <a href="?action=news">%s</a></p>', $PMF_LANG['msgNews']);
+        }
     }
 } else {
     echo $PMF_LANG['err_NotAuth'];

programming_language: PHP