CVE-2017-10680: Cross-Site Request Forgery (CSRF) (CWE-352)
value: Cross-site request forgery (CSRF) vulnerability in Piwigo through 2.9.1 allows remote attackers to hijack the authentication of users for requests to change a private album to public via a crafted request.
CWE 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.
CVSS v3 base score: 8.8
Published: 2017-06-29T21:29Z
Repository: https://github.com/Piwigo/Piwigo
Language: PHP
Files changed: admin/cat_options.php, admin/permalinks.php, admin/themes/default/template/cat_options.tpl, admin/themes/default/template/permalinks.tpl
Commit date: 2017-06-28 23:44:26 +0200
Commit message: adding pwg_token on permalink & cat_options

and therefor solving issue:721

Diff: diff --git a/admin/cat_options.php b/admin/cat_options.php
index 41d5cd732b..042adfe960 100644
--- a/admin/cat_options.php
+++ b/admin/cat_options.php
@@ -36,17 +36,16 @@ check_status(ACCESS_ADMINISTRATOR);
 
 // +-----------------------------------------------------------------------+
 // |                       modification registration                       |
 // +-----------------------------------------------------------------------+
 
-// print '<pre>';
-// print_r($_POST);
-// print '</pre>';
+
 if (isset($_POST['falsify'])
     and isset($_POST['cat_true'])
     and count($_POST['cat_true']) > 0)
 {
+  check_pwg_token();
   switch ($_GET['section'])
   {
     case 'comments' :
     {
       $query = '
@@ -244,10 +243,11 @@ SELECT DISTINCT id,name,uppercats,global_rank
     break;
   }
 }
 display_select_cat_wrapper($query_true,array(),'category_option_true');
 display_select_cat_wrapper($query_false,array(),'category_option_false');
+$template->assign('PWG_TOKEN',get_pwg_token());
 
 // +-----------------------------------------------------------------------+
 // |                           sending html code                           |
 // +-----------------------------------------------------------------------+
 
diff --git a/admin/permalinks.php b/admin/permalinks.php
index e09a2130b5..d39faf9b5e 100644
--- a/admin/permalinks.php
+++ b/admin/permalinks.php
@@ -83,19 +83,21 @@ if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
 include_once(PHPWG_ROOT_PATH.'admin/include/functions_permalinks.php');
 
 $selected_cat = array();
 if ( isset($_POST['set_permalink']) and $_POST['cat_id']>0 )
 {
+  check_pwg_token();
   $permalink = $_POST['permalink'];
   if ( empty($permalink) )
     delete_cat_permalink($_POST['cat_id'], isset($_POST['save']) );
   else
     set_cat_permalink($_POST['cat_id'], $permalink, isset($_POST['save']) );
   $selected_cat = array( $_POST['cat_id'] );
 }
 elseif ( isset($_GET['delete_permanent']) )
 {
+  check_pwg_token();
   $query = '
 DELETE FROM '.OLD_PERMALINKS_TABLE.'
   WHERE permalink=\''.$_GET['delete_permanent'].'\'
   LIMIT 1';
   $result = pwg_query($query);
@@ -123,10 +125,11 @@ SELECT
   uppercats, global_rank
 FROM '.CATEGORIES_TABLE;
 
 display_select_cat_wrapper( $query, $selected_cat, 'categories', false );
 
+$pwg_token = get_pwg_token();
 
 // --- generate display of active permalinks -----------------------------------
 $sort_by = parse_sort_variables(
     array('id', 'name', 'permalink'), 'name',
     'psf',
@@ -176,14 +179,18 @@ while ( $row = pwg_db_fetch_assoc($result) )
 {
   $row['name'] = get_cat_display_name_cache($row['cat_id']);
   $row['U_DELETE'] =
       add_url_params(
         $url_del_base,
-        array( 'delete_permanent'=> $row['permalink'] )
+        array('delete_permanent'=> $row['permalink'],'pwg_token'=>$pwg_token)
       );
   $deleted_permalinks[] = $row;
 }
-$template->assign('deleted_permalinks', $deleted_permalinks);
-$template->assign('U_HELP', get_root_url().'admin/popuphelp.php?page=permalinks');
+
+$template->assign(array(
+  'PWG_TOKEN' => $pwg_token,
+  'U_HELP' => get_root_url().'admin/popuphelp.php?page=permalinks',
+  'deleted_permalinks' => $deleted_permalinks,
+  ));
 
 $template->assign_var_from_handle('ADMIN_CONTENT', 'permalinks');
 ?>
diff --git a/admin/themes/default/template/cat_options.tpl b/admin/themes/default/template/cat_options.tpl
index 9c25c1ef0f..ef66cbe13a 100644
--- a/admin/themes/default/template/cat_options.tpl
+++ b/admin/themes/default/template/cat_options.tpl
@@ -5,7 +5,8 @@
 <form method="post" action="{$F_ACTION}" id="cat_options">
   <fieldset>
     <legend>{$L_SECTION}</legend>
     {$DOUBLE_SELECT}
   </fieldset>
+<input type="hidden" name="pwg_token" value="{$PWG_TOKEN}">
 </form>
 
diff --git a/admin/themes/default/template/permalinks.tpl b/admin/themes/default/template/permalinks.tpl
index 15857e3ea5..6480489497 100644
--- a/admin/themes/default/template/permalinks.tpl
+++ b/admin/themes/default/template/permalinks.tpl
@@ -57,10 +57,11 @@ form fieldset p.actionButtons {margin-bottom:0}
   <p class="actionButtons">
     <input type="submit" class="submit" name="set_permalink" value="{'Submit'|@translate}">
     <a href="#" id="addPermalinkClose">{'Cancel'|@translate}</a>
   </p>
 </fieldset>
+<input type="hidden" name="pwg_token" value="{$PWG_TOKEN}">
 </form>
 
 <fieldset>
   <legend>{'Permalinks'|@translate}</legend>
 <table class="table2" style="margin:0">

Vulnerable code: // print '<pre>';
// print_r($_POST);
// print '</pre>';
        array( 'delete_permanent'=> $row['permalink'] )
$template->assign('deleted_permalinks', $deleted_permalinks);
$template->assign('U_HELP', get_root_url().'admin/popuphelp.php?page=permalinks');
Fixed code: 
  check_pwg_token();
$template->assign('PWG_TOKEN',get_pwg_token());
  check_pwg_token();
  check_pwg_token();
$pwg_token = get_pwg_token();
        array('delete_permanent'=> $row['permalink'],'pwg_token'=>$pwg_token)

$template->assign(array(
  'PWG_TOKEN' => $pwg_token,
  'U_HELP' => get_root_url().'admin/popuphelp.php?page=permalinks',
  'deleted_permalinks' => $deleted_permalinks,
  ));
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN}">
<input type="hidden" name="pwg_token" value="{$PWG_TOKEN}">