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.
Release Info
Developer | radgeek |
Plugin | FeedWordPress |
Version | 2022.0123 |
Comparing to | |
See all releases |
Code changes from version 2021.0713 to 2022.0123
- feedwordpress.php +3 -3
- feedwordpresssyndicationpage.class.php +11 -8
- readme.txt +11 -3
- syndicatedpost.class.php +29 -5
@@ -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:
|
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
|
15 |
*/
|
16 |
|
17 |
# This plugin uses code derived from:
|
@@ -30,7 +30,7 @@ License: GPL
|
|
30 |
## CONSTANTS & DEFAULTS ############################################################
|
31 |
####################################################################################
|
32 |
|
33 |
-
define ('FEEDWORDPRESS_VERSION', '
|
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')) :
|
@@ -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 $
|
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 $
|
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 $
|
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 $
|
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 $
|
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&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&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) : ?>
|
@@ -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 |
-
Stable tag:
|
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
|
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 |
|
@@ -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->
|
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 |
-
$
|
1335 |
-
$frozen = (
|
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 |
-
|
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') :
|