Changeset 3435609
- Timestamp:
- 01/09/2026 03:25:18 AM (3 months ago)
- Location:
- awesome-support/trunk
- Files:
-
- 11 edited
-
awesome-support.php (modified) (2 diffs)
-
includes/admin/metaboxes/details.php (modified) (1 diff)
-
includes/admin/views/about-tab-change-log.php (modified) (1 diff)
-
includes/file-uploader/class-file-uploader.php (modified) (3 diffs)
-
includes/functions-actions.php (modified) (3 diffs)
-
includes/functions-templating.php (modified) (1 diff)
-
includes/functions-user.php (modified) (1 diff)
-
includes/gdpr-integration/gdpr-user-profile.php (modified) (1 diff)
-
includes/rest-api/assets/admin/js/admin.js (modified) (1 diff)
-
includes/rest-api/includes/API/Passwords.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
awesome-support/trunk/awesome-support.php
r3393401 r3435609 11 11 * Plugin URI: https://getawesomesupport.com 12 12 * Description: Awesome Support is a great ticketing system that will help you improve your customer satisfaction by providing a unique customer support experience. 13 * Version: 6.3. 613 * Version: 6.3.7 14 14 * Author: Awesome Support Team 15 15 * Author URI: https://getawesomesupport.com … … 253 253 */ 254 254 private function setup_constants() { 255 define( 'WPAS_VERSION', '6.3. 6' );255 define( 'WPAS_VERSION', '6.3.7' ); 256 256 define( 'WPAS_DB_VERSION', '1' ); 257 257 define( 'WPAS_URL', trailingslashit( plugin_dir_url( __FILE__ ) ) ); -
awesome-support/trunk/includes/admin/metaboxes/details.php
r3166333 r3435609 52 52 wpas_cf_display_status( '', $post->ID ); 53 53 ?> 54 <?php else: ?> 55 <span><?php _x( 'Creating...', 'Ticket creation', 'awesome-support' ); ?></span>54 <?php else: ?> 55 <span><?php echo _x( 'Creating...', 'Ticket creation', 'awesome-support' ); ?></span> 56 56 <?php endif; ?> 57 57 </div> -
awesome-support/trunk/includes/admin/views/about-tab-change-log.php
r3393401 r3435609 2 2 3 3 <div class="changelog"> 4 5 <div class="row"> 6 <div> 7 <div class="about-body"> 8 <h1>What's New In 6.3.7</h1> 9 <h3>6.3.7 Revised plugin deactivation process with feedback.</h3> 10 <ul> 11 <li>Update default fallback rules for the .htaccess file in the ticket folder.</li> 12 <li>Fix Missing Authorization to Unauthenticated Role Demotion.</li> 13 <li>Fix vulnerable issue of Unauthenticated Sensitive Information Disclosure.</li> 14 </ul> 15 </div> 16 </div> 17 </div> 4 18 5 19 <div class="row"> -
awesome-support/trunk/includes/file-uploader/class-file-uploader.php
r3393401 r3435609 136 136 137 137 add_action( 'wpas_after_close_ticket', array( $this, 'wpas_maybe_delete_attachments_after_close_ticket' ), 11, 3 ); 138 139 // One-time fix for .htaccess files containing 'Deny from all' 140 add_action( 'admin_init', array( $this, 'fix_htaccess_files_once' ), 10 ); 138 141 139 142 } … … 861 864 $filename = $dir . '/.htaccess'; 862 865 863 // Default fallback rules 864 $filecontents = wpas_get_option( 'htaccess_contents_for_attachment_folders', '' ); 866 $filecontents = wpas_get_option( 'htaccess_contents_for_attachment_folders', 'Options -Indexes' ) ; 865 867 if ( empty( $filecontents ) ) { 866 $filecontents = "Options -Indexes\n"; 867 $filecontents .= "<FilesMatch \".*\">\n"; 868 $filecontents .= "Deny from all\n"; 869 $filecontents .= "</FilesMatch>\n"; 868 $filecontents = 'Options -Indexes' ; 870 869 } 871 870 … … 919 918 } 920 919 920 } 921 922 /** 923 * One-time fix for .htaccess files containing 'Deny from all' 924 * 925 * This function runs once to fix all .htaccess files containing 'Deny from all' 926 * in the attachment folders of all existing tickets. 927 * It replaces the content with the content defined in the options. 928 * 929 * @since 1.0.0 930 * @return void 931 */ 932 public function fix_htaccess_files_once() { 933 934 // Check if the fix has already been performed 935 $fix_done = get_option( 'wpas_htaccess_deny_all_fixed', false ); 936 937 if ( $fix_done ) { 938 return; 939 } 940 941 global $wp_filesystem; 942 943 // Initialize the filesystem 944 if ( empty( $wp_filesystem ) ) { 945 require_once( ABSPATH . '/wp-admin/includes/file.php' ); 946 WP_Filesystem(); 947 } 948 949 // Get the correct content for .htaccess files 950 $filecontents = wpas_get_option( 'htaccess_contents_for_attachment_folders', 'Options -Indexes' ); 951 if ( empty( $filecontents ) ) { 952 $filecontents = 'Options -Indexes'; 953 } 954 955 // Get all tickets 956 $tickets = get_posts( array( 957 'post_type' => 'ticket', 958 'post_status' => 'any', 959 'posts_per_page' => -1, 960 'fields' => 'ids', 961 ) ); 962 963 $upload_dir = wp_upload_dir(); 964 $base_dir = $upload_dir['basedir']; 965 $fixed_count = 0; 966 967 // Loop through all tickets 968 foreach ( $tickets as $ticket_id ) { 969 970 // Calculate the attachment folder name (same method as in set_upload_dir) 971 $ticket_id_encode = md5( $ticket_id . NONCE_SALT ); 972 $ticket_dir = $base_dir . '/awesome-support/ticket_' . $ticket_id_encode; 973 $htaccess_file = $ticket_dir . '/.htaccess'; 974 975 // Check if the .htaccess file exists 976 if ( file_exists( $htaccess_file ) ) { 977 978 // Read the current content 979 $current_content = $wp_filesystem->get_contents( $htaccess_file ); 980 981 // Check if the file contains 'Deny from all' (case insensitive) 982 if ( $current_content !== false && stripos( $current_content, 'Deny from all' ) !== false ) { 983 984 // Replace the content with the new content 985 $result = $wp_filesystem->put_contents( $htaccess_file, $filecontents, FS_CHMOD_FILE ); 986 987 if ( $result !== false ) { 988 $fixed_count++; 989 wpas_write_log( 'file-uploader', '.htaccess file fixed for ticket #' . $ticket_id . ' (' . $htaccess_file . ')' ); 990 } else { 991 wpas_write_log( 'file-uploader', 'Unable to fix .htaccess file for ticket #' . $ticket_id . ' (' . $htaccess_file . ')' ); 992 } 993 } 994 } 995 } 996 997 // Mark the fix as completed 998 update_option( 'wpas_htaccess_deny_all_fixed', true ); 921 999 } 922 1000 -
awesome-support/trunk/includes/functions-actions.php
r3250497 r3435609 26 26 27 27 $nonce = false; 28 29 if ( isset( $_POST['wpas-do-nonce'] ) ) { 30 $nonce = sanitize_text_field( wp_unslash( $_POST['wpas-do-nonce'] ) ); 31 } elseif ( isset( $_GET['wpas-do-nonce'] ) ) { 32 $nonce = sanitize_text_field( wp_unslash( $_GET['wpas-do-nonce'] ) ); 28 $action = ''; 29 if ( isset( $_POST['wpas-do-nonce'] ) ) { 30 $nonce = sanitize_text_field( wp_unslash( $_POST['wpas-do-nonce'] ) ); 31 $action = isset( $_POST['wpas-do'] ) ? sanitize_text_field( wp_unslash( $_POST['wpas-do'] ) ) : ''; 32 } elseif ( isset( $_GET['wpas-do-nonce'] ) ) { 33 $nonce = sanitize_text_field( wp_unslash( $_GET['wpas-do-nonce'] ) ); 34 $action = isset( $_GET['wpas-do'] ) ? sanitize_text_field( wp_unslash( $_GET['wpas-do'] ) ) : ''; 33 35 } 34 36 35 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'trigger_custom_action' ) ) { 36 return; 37 // FIX: Use action-specific nonce verification 38 if ( ! $nonce || ! $action || ! wp_verify_nonce( $nonce, 'wpas_do_' . $action ) ) { 39 return; 40 } 41 42 if ( isset( $_POST['wpas-do'] ) ) { 43 do_action( 'wpas_do_' . $action, $_POST ); 37 44 } 38 45 39 if ( isset( $_POST['wpas-do'] ) ) { 40 $wpas_do = sanitize_text_field( wp_unslash( $_POST['wpas-do'] ) ); 41 do_action( 'wpas_do_' . $wpas_do, $_POST ); 42 } 43 44 if ( isset( $_GET['wpas-do'] ) ) { 45 $wpas_do = sanitize_text_field( wp_unslash( $_GET['wpas-do'] ) ); 46 do_action( 'wpas_do_' . $wpas_do, $_GET ); 46 if ( isset( $_GET['wpas-do'] ) ) { 47 do_action( 'wpas_do_' . $action, $_GET ); 47 48 } 48 49 … … 64 65 $field = sprintf( '<input type="hidden" name="%1$s" value="%2$s">', 'wpas-do', $action ); 65 66 66 $field .= wp_nonce_field( ' trigger_custom_action', 'wpas-do-nonce', true, false );67 $field .= wp_nonce_field( 'wpas_do_' . $action, 'wpas-do-nonce', true, false ); 67 68 68 69 $field = str_replace( 'id="wpas-do-nonce"' , 'id="wpas-do-nonce-' . $action . '"' , $field ); … … 100 101 101 102 $args['wpas-do'] = $action; 102 $args['wpas-do-nonce'] = wp_create_nonce( ' trigger_custom_action');103 $args['wpas-do-nonce'] = wp_create_nonce( 'wpas_do_' . $action ); 103 104 $url = esc_url( add_query_arg( $args, $url ) ); 104 105 -
awesome-support/trunk/includes/functions-templating.php
r3250497 r3435609 1683 1683 // Add filter to `the_title` hook. 1684 1684 add_filter( 'the_title', 'wpas_single_ticket_title', 10, 1 ); 1685 1686 /** 1687 * Alter document title for single ticket to prevent information disclosure. 1688 * 1689 * This function prevents the ticket title from being leaked in the HTML page title 1690 * for unauthenticated users or users who don't have permission to view the ticket. 1691 * 1692 * @since 6.0.0 1693 * 1694 * @param array $title_parts The document title parts 1695 * 1696 * @return array Modified title parts 1697 */ 1698 function wpas_single_ticket_document_title( $title_parts = array() ) { 1699 1700 global $post; 1701 1702 $slug = 'ticket'; 1703 1704 /* Don't touch the admin */ 1705 if ( is_admin() ) { 1706 return $title_parts; 1707 } 1708 1709 /* Only apply this on the ticket single. */ 1710 if ( ! $post || $slug !== $post->post_type ) { 1711 return $title_parts; 1712 } 1713 1714 /* Only apply this on the main query. */ 1715 if ( ! is_main_query() ) { 1716 return $title_parts; 1717 } 1718 1719 /* Check if the current user can view the ticket */ 1720 $can_view = wpas_can_view_ticket( $post->ID ); 1721 1722 /* Check if the ticket is public (wpas_pbtk_flag) - only allow public access if the Public Tickets add-on is active */ 1723 if ( class_exists( 'AS_Publictickets_Loader' ) && 'public' === get_post_meta( $post->ID, '_wpas_pbtk_flag', true ) ) { 1724 $can_view = true; 1725 } 1726 1727 if ( ! $can_view ) { 1728 /* Replace the ticket title with a generic title to prevent information disclosure */ 1729 if ( isset( $title_parts['title'] ) ) { 1730 $title_parts['title'] = __( 'No tickets found.', 'awesome-support' ); 1731 } 1732 } 1733 1734 return $title_parts; 1735 1736 } 1737 // Add filter to `document_title_parts` hook (WordPress 4.4+). 1738 add_filter( 'document_title_parts', 'wpas_single_ticket_document_title', 10, 1 ); -
awesome-support/trunk/includes/functions-user.php
r3366007 r3435609 1684 1684 if( $user_id ) { 1685 1685 1686 // FIX: Add capability check 1687 if ( ! current_user_can( 'edit_users' ) ) { 1688 wp_die( __( 'You do not have permission to activate users.', 'awesome-support' ), 403 ); 1689 } 1690 1691 // FIX: Verify current user can edit the target user 1692 if ( ! current_user_can( 'edit_user', $user_id ) ) { 1693 wp_die( __( 'You do not have permission to edit this user.', 'awesome-support' ), 403 ); 1694 } 1695 1686 1696 $role = wpas_get_option( 'moderated_activated_user_role' ); 1687 1697 -
awesome-support/trunk/includes/gdpr-integration/gdpr-user-profile.php
r3366007 r3435609 587 587 if ( $wp_filesystem->is_writable($dir) ) { 588 588 589 $filename = $dir . '/.htaccess'; 590 591 $filecontents = "Options -Indexes\n"; 592 $filecontents .= "<FilesMatch \".*\">\n"; 593 $filecontents .= "Deny from all\n"; 594 $filecontents .= "</FilesMatch>\n"; 589 $filecontents = 'Options -Indexes'; 595 590 596 591 if ( ! file_exists( $filename ) ) { -
awesome-support/trunk/includes/rest-api/assets/admin/js/admin.js
r3250497 r3435609 30 30 } 31 31 } ).done( function( response ) { 32 if ( response. PHP_AUTH_USER === testBasicAuthUser && response.PHP_AUTH_PW === testBasicAuthPassword ) {32 if ( response.BASIC_AUTH_USER === testBasicAuthUser && response.BASIC_AUTH_PW === testBasicAuthPassword ) { 33 33 // Save the success in SessionStorage or the like, so we don't do it on every page load? 34 34 } else { -
awesome-support/trunk/includes/rest-api/includes/API/Passwords.php
r3292798 r3435609 65 65 ), 66 66 'schema' => array( $this, 'get_public_item_schema' ), 67 ) ); 67 ) ); 68 68 69 69 register_rest_route( $this->namespace, '/users/(?P<user_id>[\d]+)/' . $this->rest_base . '/(?P<slug>[\da-fA-F]{12})', array( … … 89 89 90 90 // Some hosts that run PHP in FastCGI mode won't be given the Authentication header. 91 // SECURITY FIX: CVE-2025-53340 - Restrict access to administrators only 91 92 register_rest_route( $this->namespace, '/test-basic-authorization-header/', array( 92 93 array( 93 94 'methods' => WP_REST_Server::READABLE . ', ' . WP_REST_Server::CREATABLE, 94 95 'callback' => array( $this, 'test_basic_authorization_header' ), 95 'permission_callback' => '__return_true',96 'permission_callback' => array( $this, 'test_basic_auth_permissions_check' ), 96 97 ), 97 98 'schema' => array( $this, 'test_schema' ), … … 109 110 $check = empty( $request['user_id'] ) ? current_user_can( 'edit_users' ) : current_user_can( 'edit_user', $request['user_id'] ); 110 111 return apply_filters( 'wpas_api_get_password_permissions_check', $check, $request ); 112 } 113 114 /** 115 * Checks if a given request has access to test Basic Auth headers. 116 * Only administrators can access this diagnostic endpoint. 117 * 118 * SECURITY FIX: CVE-2025-53340 - Restrict access to prevent unauthenticated access 119 * 120 * @param WP_REST_Request $request Full details about the request. 121 * @return bool True if the request has access, otherwise false. 122 */ 123 public function test_basic_auth_permissions_check( $request ) { 124 return is_user_logged_in() && current_user_can( 'manage_options' ); 111 125 } 112 126 … … 294 308 295 309 public function test_basic_authorization_header() { 310 296 311 $response = array(); 297 312 298 313 if ( isset( $_SERVER['PHP_AUTH_USER'] ) ) { 299 $response[' PHP_AUTH_USER'] = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) );314 $response['BASIC_AUTH_USER'] = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) ); 300 315 } 301 316 302 317 if ( isset( $_SERVER['PHP_AUTH_PW'] ) ) { 303 $response[' PHP_AUTH_PW'] = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );318 $response['BASIC_AUTH_PW'] = sanitize_text_field( wp_unslash( $_SERVER['PHP_AUTH_PW'] ) ); 304 319 } 305 320 -
awesome-support/trunk/readme.txt
r3410359 r3435609 4 4 Tags: helpdesk,ticket system,support,tickets,support ticket 5 5 Requires at least: 4.0 6 Tested up to: 6. 97 Stable tag: 6.3. 66 Tested up to: 6.8.3 7 Stable tag: 6.3.7 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 291 291 292 292 == Changelog == 293 293 = 6.3.7 294 * Fix vulnerable issue of Unauthenticated Sensitive Information Disclosure. 295 * Fix Missing Authorization to Unauthenticated Role Demotion. 296 * Update default fallback rules for the .htaccess file in the ticket folder. 294 297 = 6.3.6 298 * Fix vulnerability to sensitive data exposure. 295 299 * Fix vulnerable issue of PHP Object Injection. 296 300 * Create a Get Help button to reach out to Support (Free and Premium).
Note: See TracChangeset
for help on using the changeset viewer.