FeedWordPress - Version 2022.0123

Version Description

  • IMPORTANT SECURITY FIX: This version includes an important fix for a security vulnerability reported to me through WPScan and WordPress support channels.

    Vulnerability CVE-2021-25055 allowed for an XSS (Cross-Site Scripting) attack using a specially crafted URL for a page within the FeedWordPress admin interface. (To be exploited, an existing user with login credentials that allow them to access the FeedWordPress dashboard would have to follow the malicious URL and log in.) This vulnerability has been corrected in the current version; to protect your site's security PLEASE BE SURE TO UPGRADE AS SOON AS POSSIBLE to version 2022.0123 or later, via the WordPress Plugin Repository or via Github.

  • BUG FIXES: Fixes a number of small possible bugs when creating new syndicated posts under unusual conditions -- a sanity check is built in to avoid infinite loops in case of certain unexpected error outcomes when creating new users; some more possible sources of PHP 8 "Countable" warnings are eliminated, etc.

Download this release

Release Info

Developer radgeek
Plugin Icon wp plugin FeedWordPress
Version 2022.0123
Comparing to
See all releases

Code changes from version 2021.0713 to 2022.0123

feedwordpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
- Version: 2021.0713
7
  Author: C. Johnson
8
  Author URI: https://feedwordpress.radgeek.com/contact/
9
  License: GPL
@@ -11,7 +11,7 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2021.0713
15
  */
16
 
17
  # This plugin uses code derived from:
@@ -30,7 +30,7 @@ License: GPL
30
  ## CONSTANTS & DEFAULTS ############################################################
31
  ####################################################################################
32
 
33
- define ('FEEDWORDPRESS_VERSION', '2021.0713');
34
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact');
35
 
36
  if (!defined('FEEDWORDPRESS_BLEG')) :
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2022.0123
7
  Author: C. Johnson
8
  Author URI: https://feedwordpress.radgeek.com/contact/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2022.0123
15
  */
16
 
17
  # This plugin uses code derived from:
30
  ## CONSTANTS & DEFAULTS ############################################################
31
  ####################################################################################
32
 
33
+ define ('FEEDWORDPRESS_VERSION', '2022.0123');
34
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact');
35
 
36
  if (!defined('FEEDWORDPRESS_BLEG')) :
feedwordpresssyndicationpage.class.php CHANGED
@@ -57,13 +57,14 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
57
  $defaultVisibility = 'N';
58
  endif;
59
 
 
60
  $visibility = (
61
  isset($_REQUEST['visibility'])
62
- ? $_REQUEST['visibility']
63
  : $defaultVisibility
64
  );
65
 
66
- return $visibility;
67
  } /* FeedWordPressSyndicationPage::visibility_toggle() */
68
 
69
  function show_inactive () {
@@ -475,6 +476,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
475
  endif;
476
 
477
  // Hey ho, let's go...
 
478
  ?>
479
  <div style="float: left; background: #F5F5F5; padding-top: 5px; padding-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_url(plugins_url( "feedwordpress.png", __FILE__ ) ); ?>" alt="" /></a></div>
480
 
@@ -527,7 +529,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
527
  </form>
528
  <?php endif; ?>
529
 
530
- <form id="syndicated-links" action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
531
  <div class="container"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
532
  <label for="add-uri">Add:
533
  <input type="text" name="lookup" id="add-uri" placeholder="Source URL"
@@ -551,14 +553,15 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
551
 
552
  $visibility = $this->visibility_toggle();
553
  $showInactive = $this->show_inactive();
554
-
555
  $hrefPrefix = $this->form_action();
 
556
  ?>
557
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
558
  <div class="tablenav">
559
 
560
  <div id="add-multiple-uri" class="hide-if-js">
561
- <form action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
562
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
563
  <h4>Add Multiple Sources</h4>
564
  <div>Enter one feed or website URL per line. If a URL links to a website which provides multiple feeds, FeedWordPress will use the first one listed.</div>
@@ -577,7 +580,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
577
  a URL for the OPML document, or by uploading a copy from your
578
  computer.</p>
579
 
580
- <form enctype="multipart/form-data" action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
581
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?><input type="hidden" name="MAX_FILE_SIZE" value="100000" /></div>
582
  <div style="clear: both"><label for="opml-lookup" style="float: left; width: 8.0em; margin-top: 5px;">From URL:</label> <input type="text" id="opml-lookup" name="opml_lookup" value="OPML document" /></div>
583
  <div style="clear: both"><label for="opml-upload" style="float: left; width: 8.0em; margin-top: 5px;">From file:</label> <input type="file" id="opml-upload" name="opml_upload" /></div>
@@ -590,7 +593,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
590
  </div> <!-- id="upload-opml" -->
591
 
592
  <div id="add-single-uri" class="alignright">
593
- <form id="syndicated-links" action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
594
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
595
  <ul class="subsubsub">
596
  <li><label for="add-uri">New source:</label>
@@ -618,7 +621,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
618
 
619
  </div> <!-- class="tablenav" -->
620
 
621
- <form id="syndicated-links" action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
622
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
623
 
624
  <?php if ($showInactive) : ?>
57
  $defaultVisibility = 'N';
58
  endif;
59
 
60
+ // this may be output into HTML, and it should really only ever be Y or N...
61
  $visibility = (
62
  isset($_REQUEST['visibility'])
63
+ ? preg_replace('/[^YyNn]+/', '', strip_tags($_REQUEST['visibility']))
64
  : $defaultVisibility
65
  );
66
 
67
+ return (strlen($visibility) > 0 ? $visibility : $defaultVisibility);
68
  } /* FeedWordPressSyndicationPage::visibility_toggle() */
69
 
70
  function show_inactive () {
476
  endif;
477
 
478
  // Hey ho, let's go...
479
+ $syndicatedLinks_formAction = esc_url( sprintf('%s&amp;visibility=%s', $hrefPrefix, urlencode($visibility)) );
480
  ?>
481
  <div style="float: left; background: #F5F5F5; padding-top: 5px; padding-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_url(plugins_url( "feedwordpress.png", __FILE__ ) ); ?>" alt="" /></a></div>
482
 
529
  </form>
530
  <?php endif; ?>
531
 
532
+ <form id="syndicated-links" action="<?php print $syndicatedLinks_formAction; ?>" method="post">
533
  <div class="container"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
534
  <label for="add-uri">Add:
535
  <input type="text" name="lookup" id="add-uri" placeholder="Source URL"
553
 
554
  $visibility = $this->visibility_toggle();
555
  $showInactive = $this->show_inactive();
556
+
557
  $hrefPrefix = $this->form_action();
558
+ $formHref = esc_url( sprintf( '%s&amp;visibility=%s', $hrefPrefix, urlencode($visibility) ) );
559
  ?>
560
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
561
  <div class="tablenav">
562
 
563
  <div id="add-multiple-uri" class="hide-if-js">
564
+ <form action="<?php print $formHref; ?>" method="post">
565
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
566
  <h4>Add Multiple Sources</h4>
567
  <div>Enter one feed or website URL per line. If a URL links to a website which provides multiple feeds, FeedWordPress will use the first one listed.</div>
580
  a URL for the OPML document, or by uploading a copy from your
581
  computer.</p>
582
 
583
+ <form enctype="multipart/form-data" action="<?php print $formHref; ?>" method="post">
584
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?><input type="hidden" name="MAX_FILE_SIZE" value="100000" /></div>
585
  <div style="clear: both"><label for="opml-lookup" style="float: left; width: 8.0em; margin-top: 5px;">From URL:</label> <input type="text" id="opml-lookup" name="opml_lookup" value="OPML document" /></div>
586
  <div style="clear: both"><label for="opml-upload" style="float: left; width: 8.0em; margin-top: 5px;">From file:</label> <input type="file" id="opml-upload" name="opml_upload" /></div>
593
  </div> <!-- id="upload-opml" -->
594
 
595
  <div id="add-single-uri" class="alignright">
596
+ <form id="syndicated-links" action="<?php print $formHref; ?>" method="post">
597
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
598
  <ul class="subsubsub">
599
  <li><label for="add-uri">New source:</label>
621
 
622
  </div> <!-- class="tablenav" -->
623
 
624
+ <form id="syndicated-links" action="<?php print $formHref; ?>" method="post">
625
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
626
 
627
  <?php if ($showInactive) : ?>
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: C. Johnson
3
  Donate link: http://feedwordpress.radgeek.com/donate/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 4.5
6
- Tested up to: 5.7.2
7
- Stable tag: 2021.0713
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -65,6 +65,14 @@ FeedWordPress has many options which can be accessed through the WordPress Dashb
65
 
66
  == Changelog ==
67
 
 
 
 
 
 
 
 
 
68
  = 2021.0713 =
69
 
70
  * WORDPRESS 5.6, 5.7.x COMPATIBILITY FIXES. This release introduces fixes to annoying or worse warnings resulting from
@@ -165,7 +173,7 @@ FeedWordPress has many options which can be accessed through the WordPress Dashb
165
 
166
  The first is a common problem across several plugins due to an ambiguity in the WordPress documentation and a change in the behavior of WordPress's built-in add_query_arg() and remove_query_arg() functions which could, under certain low-probability conditions, allow for potential XSS attack vectors. This fixes issue # 39 reported at <https://github.com/radgeek/feedwordpress/issues/39> Thanks to github.com/quassy
167
 
168
- The second is a security vulnerability fixes a security vulnerability that was reported to me privately (thanks to Adrián M. F.) which, under other low-probability conditions, could allow for SQL insertion attacks by a malicious user with access to login credentials, which would compromise data security.
169
 
170
  It is *IMPORTANT* and worth your while to upgrade FeedWordPress as soon as possible in order to eliminate these vulnerabilities. If you have any questions or if there is something blocking you from making the upgrade which you need my help with, don't hesitate to get in touch.
171
 
3
  Donate link: http://feedwordpress.radgeek.com/donate/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 4.5
6
+ Tested up to: 5.9
7
+ Stable tag: 2022.0123
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
65
 
66
  == Changelog ==
67
 
68
+ = 2022.0123 =
69
+
70
+ * IMPORTANT SECURITY FIX: This version includes an important fix for a security vulnerability reported to me through WPScan and WordPress support channels.
71
+
72
+ Vulnerability CVE-2021-25055 allowed for an XSS (Cross-Site Scripting) attack using a specially crafted URL for a page within the FeedWordPress admin interface. (To be exploited, an existing user with login credentials that allow them to access the FeedWordPress dashboard would have to follow the malicious URL and log in.) This vulnerability has been corrected in the current version; to protect your site's security PLEASE BE SURE TO UPGRADE AS SOON AS POSSIBLE to version 2022.0123 or later, via the WordPress Plugin Repository or via Github.
73
+
74
+ * BUG FIXES: Fixes a number of small possible bugs when creating new syndicated posts under unusual conditions -- a sanity check is built in to avoid infinite loops in case of certain unexpected error outcomes when creating new users; some more possible sources of PHP 8 "Countable" warnings are eliminated, etc.
75
+
76
  = 2021.0713 =
77
 
78
  * WORDPRESS 5.6, 5.7.x COMPATIBILITY FIXES. This release introduces fixes to annoying or worse warnings resulting from
173
 
174
  The first is a common problem across several plugins due to an ambiguity in the WordPress documentation and a change in the behavior of WordPress's built-in add_query_arg() and remove_query_arg() functions which could, under certain low-probability conditions, allow for potential XSS attack vectors. This fixes issue # 39 reported at <https://github.com/radgeek/feedwordpress/issues/39> Thanks to github.com/quassy
175
 
176
+ The second fixes a security vulnerability that was reported to me privately (thanks to Adrián M. F.) which, under other low-probability conditions, could allow for SQL insertion attacks by a malicious user with access to login credentials, which would compromise data security.
177
 
178
  It is *IMPORTANT* and worth your while to upgrade FeedWordPress as soon as possible in order to eliminate these vulnerabilities. If you have any questions or if there is something blocking you from making the upgrade which you need my help with, don't hesitate to get in touch.
179
 
syndicatedpost.class.php CHANGED
@@ -698,7 +698,7 @@ class SyndicatedPost {
698
  else :
699
  $link = $this->permalink();
700
  if (is_null($link)) : $link = $this->link->uri(); endif;
701
- $guid .= '://'.md5($link.'/'.$this->item['title']);
702
  endif;
703
  endif;
704
  return $guid;
@@ -1331,8 +1331,8 @@ class SyndicatedPost {
1331
  if ($updated) : // Ignore if the post is frozen
1332
  $frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
1333
  if (!$frozen) :
1334
- $frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID);
1335
- $frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
1336
 
1337
  if ($frozen) :
1338
  $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT '.$updatedReason;
@@ -2339,6 +2339,7 @@ EOM;
2339
 
2340
  #-- loop. Keep trying to add the user until you get it
2341
  #-- right. Or until PHP crashes, I guess.
 
2342
  do {
2343
  $id = wp_insert_user($userdata);
2344
  if (is_wp_error($id)) :
@@ -2346,9 +2347,15 @@ EOM;
2346
  switch ($codes) :
2347
  case 'empty_user_login' :
2348
  case 'existing_user_login' :
 
2349
  // Add a random disambiguator
2350
  $userdata['user_login'] .= substr(md5(uniqid(microtime())), 0, 6);
2351
  break;
 
 
 
 
 
2352
  case 'user_nicename_too_long' :
2353
  // Add a limited 50 characters user_nicename based on user_login
2354
  $userdata['user_nicename'] = mb_substr( $userdata['user_login'], 0, 50 );
@@ -2363,8 +2370,21 @@ EOM;
2363
  // Reassemble
2364
  $userdata['user_email'] = $parts[0].'@'.$parts[1];
2365
  break;
 
 
 
 
 
 
 
 
 
 
 
 
2366
  endswitch;
2367
  endif;
 
2368
  } while (is_wp_error($id));
2369
 
2370
  // $id should now contain the numeric ID of a newly minted
@@ -2372,8 +2392,12 @@ EOM;
2372
  // by FeedWordPress in the usermeta table, as per the
2373
  // suggestion of @boonebgorges, in case we need to process,
2374
  // winnow, filter, or merge syndicated author accounts, &c.
2375
- add_user_meta($id, 'feedwordpress_generated', 1);
2376
-
 
 
 
 
2377
  elseif (is_numeric($unfamiliar_author) and get_userdata((int) $unfamiliar_author)) :
2378
  $id = (int) $unfamiliar_author;
2379
  elseif ($unfamiliar_author === 'default') :
698
  else :
699
  $link = $this->permalink();
700
  if (is_null($link)) : $link = $this->link->uri(); endif;
701
+ $guid .= '://'.md5($link.'/'.$this->title());
702
  endif;
703
  endif;
704
  return $guid;
1331
  if ($updated) : // Ignore if the post is frozen
1332
  $frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
1333
  if (!$frozen) :
1334
+ $frozen_value = get_post_meta($old_post->ID, '_syndication_freeze_updates', /*single=*/ true);
1335
+ $frozen = (!is_null($frozen_value) and ('yes' == $frozen_value));
1336
 
1337
  if ($frozen) :
1338
  $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT '.$updatedReason;
2339
 
2340
  #-- loop. Keep trying to add the user until you get it
2341
  #-- right. Or until PHP crashes, I guess.
2342
+ $insanity = 0;
2343
  do {
2344
  $id = wp_insert_user($userdata);
2345
  if (is_wp_error($id)) :
2347
  switch ($codes) :
2348
  case 'empty_user_login' :
2349
  case 'existing_user_login' :
2350
+ case 'invalid_username' :
2351
  // Add a random disambiguator
2352
  $userdata['user_login'] .= substr(md5(uniqid(microtime())), 0, 6);
2353
  break;
2354
+ case 'user_login_too_long' :
2355
+ // Limit length to 53 characters; if we end up needing a random disambiguator,
2356
+ // we should still have space to add it.
2357
+ $userdata['user_login'] = mb_substr( $userdata['user_login'], 0, 53 );
2358
+ break;
2359
  case 'user_nicename_too_long' :
2360
  // Add a limited 50 characters user_nicename based on user_login
2361
  $userdata['user_nicename'] = mb_substr( $userdata['user_login'], 0, 50 );
2370
  // Reassemble
2371
  $userdata['user_email'] = $parts[0].'@'.$parts[1];
2372
  break;
2373
+ default :
2374
+ if ( $insanity > 10 ) :
2375
+ // Try some settings that are unlikely to cause complaint...
2376
+ $url = parse_url($hostUrl);
2377
+
2378
+ $userdata['user_login'] = substr(md5(uniqid(microtime())), 0, 6);
2379
+ $userdata['user_nicename'] = $userdata['user_login'];
2380
+ $userdata['user_email'] = 'noreply@' . $url['host'];
2381
+ elseif ( $insanity > 50 ) :
2382
+ // Stop doing the same thing and expecting a different result
2383
+ break;
2384
+ endif;
2385
  endswitch;
2386
  endif;
2387
+ $insanity = $insanity + 1;
2388
  } while (is_wp_error($id));
2389
 
2390
  // $id should now contain the numeric ID of a newly minted
2392
  // by FeedWordPress in the usermeta table, as per the
2393
  // suggestion of @boonebgorges, in case we need to process,
2394
  // winnow, filter, or merge syndicated author accounts, &c.
2395
+ if (!is_wp_error($id)) :
2396
+ add_user_meta($id, 'feedwordpress_generated', 1);
2397
+ else :
2398
+ $id = null;
2399
+ endif;
2400
+
2401
  elseif (is_numeric($unfamiliar_author) and get_userdata((int) $unfamiliar_author)) :
2402
  $id = (int) $unfamiliar_author;
2403
  elseif ($unfamiliar_author === 'default') :