--- a/nexter-extension/include/classes/third-party/class-gutenberg.php
+++ b/nexter-extension/include/classes/third-party/class-gutenberg.php
@@ -104,6 +104,21 @@
wp_reset_postdata();
}
}
+
+ /*GSPB GreenShift*/
+ if ( function_exists( 'gspb_get_final_css' ) ) {
+ $gspb_css_content = get_post_meta( $post_id, '_gspb_post_css', true );
+ if ( !empty( $gspb_css_content ) ) {
+ $gspb_saved_css_content = gspb_get_final_css( $gspb_css_content );
+ $final_css = $gspb_saved_css_content;
+
+ if ( !empty( $final_css ) ) {
+ wp_register_style( 'greenshift-post-css-' . $post_id, false );
+ wp_enqueue_style( 'greenshift-post-css-' . $post_id );
+ wp_add_inline_style( 'greenshift-post-css-' . $post_id, $final_css );
+ }
+ }
+ }
}
}
--- a/nexter-extension/include/panel-settings/extensions/custom-fields/nexter-ext-smtp-custom-auth.php
+++ b/nexter-extension/include/panel-settings/extensions/custom-fields/nexter-ext-smtp-custom-auth.php
@@ -5,10 +5,35 @@
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
+// Prevent WordPress from setting default From address when SMTP is configured
+add_filter('wp_mail_from', function($from_email) {
+ $options = get_option('nexter_extra_ext_options', []);
+ $smtp = $options['smtp-email']['values'] ?? [];
+
+ // Only override if custom SMTP is configured and enabled
+ if (!empty($options['smtp-email']['switch']) &&
+ !empty($smtp['type']) &&
+ $smtp['type'] === 'custom' &&
+ !empty($smtp['custom']['username']) &&
+ is_email($smtp['custom']['username'])) {
+ // Return the authenticated username to prevent WordPress default
+ return $smtp['custom']['username'];
+ }
+
+ return $from_email;
+}, 999);
+
// Configure WordPress to use SMTP with custom settings
+// Use high priority to ensure our settings override WordPress defaults
add_action('phpmailer_init', function (PHPMailer $phpmailer) {
$options = get_option('nexter_extra_ext_options', []);
+
+ // Only configure SMTP if it's enabled
+ if (empty($options['smtp-email']['switch'])) {
+ return;
+ }
+
$smtp = $options['smtp-email']['values'] ?? [];
$smtp_custom = $smtp['custom'] ?? [];
@@ -25,21 +50,81 @@
$phpmailer->SMTPDebug = 0; // Set to 2 for detailed debug
$phpmailer->Host = sanitize_text_field($smtp_custom['host']);
$phpmailer->Port = intval($smtp_custom['port'] ?? 587);
- $phpmailer->SMTPSecure = (!empty($smtp_custom['encryption']) && $smtp_custom['encryption'] !== 'none') ? $smtp_custom['encryption'] : '';
- $phpmailer->SMTPAutoTLS = !empty($smtp_custom['autoTLS']) && ($smtp_custom['autoTLS'] === true || $smtp_custom['autoTLS'] === 'true');
- $phpmailer->SMTPAuth = !empty($smtp_custom['auth']) && ($smtp_custom['auth'] == true || $smtp_custom['auth'] == 'true');
- $phpmailer->Username = sanitize_text_field($smtp_custom['username']);
- $phpmailer->Password = sanitize_text_field($smtp_custom['password']);
+
+ // Handle encryption - if port is 465, use 'ssl', otherwise use the specified encryption
+ $encryption = !empty($smtp_custom['encryption']) && $smtp_custom['encryption'] !== 'none'
+ ? $smtp_custom['encryption']
+ : '';
+
+ // For port 465, force SSL if encryption is not set
+ if ($phpmailer->Port == 465 && empty($encryption)) {
+ $encryption = 'ssl';
+ }
+
+ $phpmailer->SMTPSecure = $encryption;
+
+ // SMTPAutoTLS should be false when using SSL/TLS, true for STARTTLS
+ if (!empty($encryption) && $encryption === 'ssl') {
+ $phpmailer->SMTPAutoTLS = false; // SSL doesn't need AutoTLS
+ } else {
+ $phpmailer->SMTPAutoTLS = !empty($smtp_custom['autoTLS']) && ($smtp_custom['autoTLS'] === true || $smtp_custom['autoTLS'] === 'true');
+ }
+
+ // Only set auth if enabled
+ $smtp_auth = !empty($smtp_custom['auth']) && ($smtp_custom['auth'] == true || $smtp_custom['auth'] == 'true');
+ $phpmailer->SMTPAuth = $smtp_auth;
+
+ // Only set username/password if auth is enabled
+ if ($smtp_auth) {
+ if (!empty($smtp_custom['username'])) {
+ $phpmailer->Username = sanitize_text_field($smtp_custom['username']);
+ }
+ if (!empty($smtp_custom['password'])) {
+ $phpmailer->Password = sanitize_text_field($smtp_custom['password']);
+ }
+ }
- $from_email = !empty($smtp_custom['from_email']) ? sanitize_email($smtp_custom['from_email']) : '';
+ // Set From email - for providers like Yandex, From must match authenticated username
+ // CRITICAL: Always set From address to match authenticated username when auth is enabled
+ // This prevents WordPress default From address from being used
+
$from_name = !empty($smtp_custom['from_name']) ? sanitize_text_field($smtp_custom['from_name']) : get_bloginfo('name');
-
- if ($from_email && is_email($from_email)) {
- $phpmailer->setFrom($from_email, $from_name);
- } elseif (!empty($smtp_custom['username']) && is_email($smtp_custom['username'])) {
- $phpmailer->setFrom($smtp_custom['username'], $smtp['name'] ?? get_bloginfo('name'));
+
+ // Check if this is Yandex SMTP (requires From to match username)
+ $is_yandex = stripos($phpmailer->Host, 'yandex') !== false;
+
+ // If auth is enabled, From MUST match username (required for Yandex and many other providers)
+ if ($smtp_auth && !empty($smtp_custom['username'])) {
+ // Always use username as From address when auth is enabled
+ // This ensures the From address matches the authenticated user
+ $username_email = is_email($smtp_custom['username'])
+ ? $smtp_custom['username']
+ : sanitize_email($smtp_custom['username']);
+
+ if ($username_email) {
+ // Force set From address - this will override any default WordPress set
+ $phpmailer->setFrom($username_email, $from_name, false);
+ } else {
+ // Fallback: use from_email if username is not a valid email
+ $from_email = !empty($smtp_custom['from_email']) ? sanitize_email($smtp_custom['from_email']) : '';
+ if ($from_email && is_email($from_email)) {
+ $phpmailer->setFrom($from_email, $from_name, false);
+ }
+ }
+ } else {
+ // If auth is not enabled, use from_email if provided
+ $from_email = !empty($smtp_custom['from_email']) ? sanitize_email($smtp_custom['from_email']) : '';
+ if ($from_email && is_email($from_email)) {
+ $phpmailer->setFrom($from_email, $from_name, false);
+ }
}
+
+ // Set CharSet and encoding
+ $phpmailer->CharSet = 'UTF-8';
+ $phpmailer->Encoding = 'base64';
+
} catch (Exception $e) {
error_log('SMTP Configuration Error: ' . $e->getMessage());
+ // Don't throw - let wp_mail handle the error
}
-});
No newline at end of file
+}, 999); // High priority to override WordPress defaults
No newline at end of file
--- a/nexter-extension/include/panel-settings/extensions/nexter-ext-post-duplicator.php
+++ b/nexter-extension/include/panel-settings/extensions/nexter-ext-post-duplicator.php
@@ -43,12 +43,8 @@
// Get post type
$post_type = get_post_type_object( $post->post_type );
- /* translators: %s: singular name */
- $label = sprintf( __( 'Duplicate %s', 'nexter-extension' ), $post_type->labels->singular_name );
-
// Create and Return Link
- return '<a class="nxt-post-duplicate" href="" data-postid="'.esc_attr( $post->ID ).'">'.wp_kses_post( $label ).'</a><div class="nxt-dp-post-modal"><div class="nxt-post-modal-inner"><div class="nxt-post-dp-input-wrap"><input class="nxt-dp-post-input" type="number" min="1" value="1"/><span class="nxt-dp-post-total-text">: '.wp_kses_post($post_type->labels->singular_name).'(s)</span></div><a class="nxt-dp-post-btn" href="">'.esc_html__('Duplicate','nexter-extension').'</a></div></div>';
-
+ return '<a class="nxt-post-duplicate" href="" data-postid="'.esc_attr( $post->ID ).'">'. esc_html__( 'Duplicate', 'nexter-extension' ).'</a><div class="nxt-dp-post-modal"><div class="nxt-post-modal-inner"><div class="nxt-post-dp-input-wrap"><input class="nxt-dp-post-input" type="number" min="1" value="1"/><span class="nxt-dp-post-total-text">: '.wp_kses_post($post_type->labels->singular_name).'(s)</span></div><a class="nxt-dp-post-btn" href="">'.esc_html__('Duplicate','nexter-extension').'</a></div></div>';
}
}
}
--- a/nexter-extension/include/panel-settings/extensions/nexter-ext-replace-url.php
+++ b/nexter-extension/include/panel-settings/extensions/nexter-ext-replace-url.php
@@ -1,7 +1,28 @@
<?php
if( !function_exists('nxt_replace_url')){
function nxt_replace_url() {
+ // Security: Require authentication
+ if ( ! is_user_logged_in() ) {
+ wp_send_json_error(
+ array(
+ 'success' => false,
+ 'message' => __( 'Authentication required.', 'nexter-extension' ),
+ )
+ );
+ }
+
check_ajax_referer( 'nexter_admin_nonce', 'nexter_nonce' );
+
+ // Security: Require administrator role
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error(
+ array(
+ 'success' => false,
+ 'message' => __( 'Insufficient permissions.', 'nexter-extension' ),
+ )
+ );
+ }
+
$user = wp_get_current_user();
$allowed_roles = array( 'administrator' );
if ( !empty($user) && isset($user->roles) && array_intersect( $allowed_roles, $user->roles ) ) {
@@ -55,12 +76,34 @@
}
}
add_action( 'wp_ajax_nxt_replace_url', 'nxt_replace_url' );
- add_action('wp_ajax_nopriv_nxt_replace_url', 'nxt_replace_url' );
+ // Removed unauthenticated access to prevent security vulnerability
+ // add_action('wp_ajax_nopriv_nxt_replace_url', 'nxt_replace_url' );
}
if( !function_exists('nxt_replace_confirm_url')){
function nxt_replace_confirm_url() {
+ // Security: Require authentication
+ if ( ! is_user_logged_in() ) {
+ wp_send_json_error(
+ array(
+ 'success' => false,
+ 'message' => __( 'Authentication required.', 'nexter-extension' ),
+ )
+ );
+ }
+
check_ajax_referer( 'nexter_admin_nonce', 'nexter_nonce' );
+
+ // Security: Require administrator role
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error(
+ array(
+ 'success' => false,
+ 'message' => __( 'Insufficient permissions.', 'nexter-extension' ),
+ )
+ );
+ }
+
$user = wp_get_current_user();
$allowed_roles = array( 'administrator' );
if ( !empty($user) && isset($user->roles) && array_intersect( $allowed_roles, $user->roles ) ) {
@@ -105,7 +148,8 @@
}
}
add_action( 'wp_ajax_nxt_replace_confirm_url', 'nxt_replace_confirm_url' );
- add_action('wp_ajax_nopriv_nxt_replace_confirm_url', 'nxt_replace_confirm_url' );
+ // Removed unauthenticated access to prevent security vulnerability
+ // add_action('wp_ajax_nopriv_nxt_replace_confirm_url', 'nxt_replace_confirm_url' );
}
if( !function_exists('nxt_get_columns')){
@@ -143,13 +187,30 @@
if( !function_exists('nxt_unserialize_replace')){
function nxt_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $case = false ) {
+ // Security: Prevent PHP object injection by using a safer unserialize approach
+ // Only unserialize data that we control (from database, not user input)
+
if ( is_string( $data ) && !is_serialized_string( $data ) && is_serialized( $data )) {
- $unserialized;
+ $unserialized = false;
if ( ! is_serialized( $data ) ) {
$unserialized = false;
}else{
- $serialized_string = trim( $data );
- $unserialized = @unserialize( $serialized_string );
+ $serialized_string = trim( $data );
+
+ // Security: Use allowed_classes parameter to prevent arbitrary class instantiation
+ // This ensures that only arrays and primitives are deserialized, preventing PHP Object Injection attacks
+ if ( version_compare( PHP_VERSION, '7.0.0', '>=' ) ) {
+ // Secure version - PHP 7.0+
+ $unserialized = @unserialize( $serialized_string, array( 'allowed_classes' => false ) );
+ } else {
+ // For PHP 5.6, check for object notation before unserializing
+ // Reject any serialized data containing objects to prevent PHP object injection
+ if ( preg_match( '/O:d+:"/', $serialized_string ) ) {
+ // Contains object - reject for security to prevent PHP object injection
+ return $data;
+ }
+ $unserialized = @unserialize( $serialized_string );
+ }
}
if ( $unserialized !== false ) {
$data = nxt_unserialize_replace( $from, $to, $unserialized, true, $case );
@@ -163,6 +224,7 @@
$data = $_temp;
unset( $_temp );
}elseif ( is_object( $data ) ) {
+ // Security: Prevent unserialization of potentially dangerous objects
if ('__PHP_Incomplete_Class' !== get_class($data)) {
$_temp = $data;
$props = get_object_vars( $data );
@@ -174,13 +236,27 @@
unset( $_temp );
}
}elseif ( is_serialized_string( $data ) ) {
- $unserialized;
+ $unserialized = false;
if ( ! is_serialized( $data ) ) {
$unserialized = false;
}else{
- $serialized_string = trim( $data );
- $unserialized = @unserialize( $serialized_string );
+ $serialized_string = trim( $data );
+
+ // Security: Use allowed_classes parameter to prevent arbitrary class instantiation
+ // This ensures that only arrays and primitives are deserialized, preventing PHP Object Injection attacks
+ if ( version_compare( PHP_VERSION, '7.0.0', '>=' ) ) {
+ // Secure version - PHP 7.0+
+ $unserialized = @unserialize( $serialized_string, array( 'allowed_classes' => false ) );
+ } else {
+ // For PHP 5.6, check for object notation before unserializing
+ // Reject any serialized data containing objects to prevent PHP object injection
+ if ( preg_match( '/O:d+:"/', $serialized_string ) ) {
+ // Contains object - reject for security to prevent PHP object injection
+ return $data;
+ }
+ $unserialized = @unserialize( $serialized_string );
+ }
}
if ( $unserialized !== false ) {
--- a/nexter-extension/include/panel-settings/extensions/nexter-ext-smtp-email.php
+++ b/nexter-extension/include/panel-settings/extensions/nexter-ext-smtp-email.php
@@ -254,14 +254,67 @@
if( empty( $to ) ){
wp_send_json_error(__('Please Enter a valid Email ID to send the test mail.', 'nexter-extension'));
}
- $subject = __('Gmail SMTP Test Email', 'nexter-extension');
+
+ // Check SMTP configuration
+ $options = get_option('nexter_extra_ext_options', []);
+
+ // Check if SMTP is enabled
+ if (empty($options['smtp-email']['switch'])) {
+ wp_send_json_error(__('SMTP is not enabled. Please enable SMTP first.', 'nexter-extension'));
+ }
+
+ $smtp = $options['smtp-email']['values'] ?? [];
+
+ if (empty($smtp['type'])) {
+ wp_send_json_error(__('SMTP is not configured. Please configure SMTP settings first.', 'nexter-extension'));
+ }
+
+ // For custom SMTP, verify connection was successful
+ if ($smtp['type'] === 'custom') {
+ $smtp_custom = $smtp['custom'] ?? [];
+ if (empty($smtp_custom['connect']) || $smtp_custom['connect'] !== true) {
+ wp_send_json_error(__('SMTP connection not verified. Please test the connection first.', 'nexter-extension'));
+ }
+ }
+
+ $subject = $smtp['type'] === 'custom'
+ ? __('Custom SMTP Test Email', 'nexter-extension')
+ : __('Gmail SMTP Test Email', 'nexter-extension');
$body = '<b>This is a test email sent via using SMTP.</b>';
$headers = ['Content-Type: text/html; charset=UTF-8'];
+
+ // Capture error message - use closure to capture by reference
+ $error_message = '';
+ $error_capture = function($wp_error) use (&$error_message) {
+ $error_message = $wp_error->get_error_message();
+ error_log('SMTP Test Email Error (wp_mail_failed): ' . $error_message);
+ };
+
+ // Enable error capture before sending
+ add_action('wp_mail_failed', $error_capture, 10, 1);
+
+ // Let WordPress create PHPMailer instance and apply phpmailer_init hook
+ // Don't interfere with the global $phpmailer instance
$result = wp_mail($to, $subject, $body, $headers);
+
+ // Get PHPMailer error after wp_mail execution
+ global $phpmailer;
+ if (empty($error_message) && is_object($phpmailer) && !empty($phpmailer->ErrorInfo)) {
+ $error_message = $phpmailer->ErrorInfo;
+ error_log('SMTP Test Email Error (PHPMailer): ' . $error_message);
+ }
+
+ // Remove the error capture hook
+ remove_action('wp_mail_failed', $error_capture);
+
if ($result === true) {
wp_send_json_success(__('Test email sent successfully!', 'nexter-extension'));
} else {
- wp_send_json_error(__('Failed to send test email: ', 'nexter-extension') . $result);
+ // Provide detailed error message
+ if (empty($error_message)) {
+ $error_message = __('Unknown error occurred while sending email. Please check your SMTP settings and server logs.', 'nexter-extension');
+ }
+ wp_send_json_error(__('Failed to send test email: ', 'nexter-extension') . $error_message);
}
}
--- a/nexter-extension/nexter-extension.php
+++ b/nexter-extension/nexter-extension.php
@@ -3,7 +3,7 @@
* Plugin Name: Nexter Extension
* Plugin URI: https://nexterwp.com
* Description: Extension for Nexter Theme to unlock all FREE features. Keep this active to use access its all features
- * Version: 4.4.6
+ * Version: 4.4.7
* Author: POSIMYTH
* Author URI: https://posimyth.com
* Text Domain: nexter-extension
@@ -26,7 +26,7 @@
define( 'NEXTER_EXT_DIR', plugin_dir_path( NEXTER_EXT_FILE ) );
define( 'NEXTER_EXT_URL', plugins_url( '/', NEXTER_EXT_FILE ) );
define( 'NEXTER_EXT_CPT', 'nxt_builder' );
-define( 'NEXTER_EXT_VER', '4.4.6' );
+define( 'NEXTER_EXT_VER', '4.4.7' );
if(!defined('NXT_BUILD_POST')){
define( 'NXT_BUILD_POST', 'nxt_builder' );