Plugin Directory

Changeset 3445248


Ignore:
Timestamp:
01/23/2026 01:50:30 AM (2 months ago)
Author:
aiktp
Message:

update to version 5.0.0.5 to fix Missing Authorization to Authenticated

Location:
aiktp/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • aiktp/trunk/aiktp.php

    r3430333 r3445248  
    44 * Plugin URI: https://aiktp.com/wordpress
    55 * Description: AIKTP - AI powered WordPress content automation. Create SEO optimized articles, bulk generate WooCommerce product descriptions, and sync posts directly from aiktp.com.
    6  * Version: 5.0.04
     6 * Version: 5.0.05
    77 * Author: John Luke - aiktp.com
    88 * License: GPL v2 or later
     
    2222
    2323// Define constants
    24 define('AIKTPZ_VERSION', '5.0.04');
     24define('AIKTPZ_VERSION', '5.0.05');
    2525define('AIKTPZ_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2626define('AIKTPZ_PLUGIN_URL', plugin_dir_url(__FILE__));
  • aiktp/trunk/includes/aiktp-sync.php

    r3430333 r3445248  
    121121            'methods' => 'GET',
    122122            'callback' => array($this, 'get_valid_token'),
    123             'permission_callback' => array($this, 'verify_user_logged_in')
    124         ));
    125     }
    126    
    127    
    128     /**
    129      * Verify user is logged in (for token retrieval)
    130      *
    131      * This method ensures only logged-in users can retrieve the shared secret token.
    132      * SECURITY: Token retrieval must be restricted to authenticated users to prevent token leakage.
    133      *
    134      * NOTE: We check get_current_user_id() directly because is_user_logged_in()
    135      * doesn't work reliably in REST API context without proper authentication headers.
     123            'permission_callback' => array($this, 'verify_admin_capability')
     124        ));
     125    }
     126   
     127   
     128    /**
     129     * Verify user has admin capability (for token retrieval)
     130     *
     131     * This method ensures only administrators with manage_options capability can retrieve the shared secret token.
     132     * SECURITY FIX (CVE-2026-1103): Previously only checked is_user_logged_in(), which allowed any authenticated
     133     * user (including Subscribers) to retrieve the admin token. Now requires manage_options capability.
     134     *
     135     * The token grants access to create posts, upload media, and access private content, so it must be
     136     * restricted to administrators only.
    136137     *
    137138     * When calling this endpoint from JavaScript, you MUST include the nonce header:
     
    139140     *
    140141     * @param WP_REST_Request $request The REST API request object
    141      * @return bool|WP_Error True if user is logged in, WP_Error otherwise
    142      */
    143     public function verify_user_logged_in($request) {
    144         // Get current user ID - works better in REST API context
    145         $user_id = get_current_user_id();
    146        
    147         // If user ID is 0, user is not logged in
    148         if ($user_id === 0) {
     142     * @return bool|WP_Error True if user has manage_options capability, WP_Error otherwise
     143     */
     144    public function verify_admin_capability($request) {
     145        // Check if user is logged in first
     146        if (!is_user_logged_in()) {
    149147            return new WP_Error(
    150148                'rest_forbidden',
    151149                __('You must be logged in to WordPress to access this endpoint. Please include authentication headers (X-WP-Nonce) in your request.', 'aiktp'),
    152150                array('status' => 401)
     151            );
     152        }
     153       
     154        // Check if user has manage_options capability (administrator)
     155        if (!current_user_can('manage_options')) {
     156            return new WP_Error(
     157                'rest_forbidden',
     158                __('You do not have sufficient permissions to access this endpoint. Only administrators can retrieve the sync token.', 'aiktp'),
     159                array('status' => 403)
    153160            );
    154161        }
     
    229236        // Verify the configured author exists and has edit_posts capability
    230237        $user = get_userdata($aiktp_author);
    231         if (!$user || !user_can($user, 'edit_posts')) {
     238       
     239        // If configured author doesn't exist or doesn't have permissions, find a valid admin
     240        if (!$user || !user_can($user, 'edit_posts') || !user_can($user, 'publish_posts')) {
     241            // Try to find an administrator user
     242            $admins = get_users(array(
     243                'role' => 'administrator',
     244                'number' => 1,
     245                'orderby' => 'ID',
     246                'order' => 'ASC'
     247            ));
     248           
     249            if (!empty($admins)) {
     250                $user = $admins[0];
     251                // Update the option to use this admin for future requests
     252                update_option('aiktp_author', $user->ID);
     253            } else {
     254                return new WP_Error(
     255                    'rest_forbidden',
     256                    __('No administrator user found. Please ensure at least one administrator account exists.', 'aiktp'),
     257                    array('status' => 403)
     258                );
     259            }
     260        }
     261       
     262        // Double-check the user has required capabilities
     263        if (!user_can($user, 'edit_posts') || !user_can($user, 'publish_posts')) {
    232264            return new WP_Error(
    233265                'rest_forbidden',
    234                 __('Configured AIKTP author does not have permission to create posts. Please check plugin settings.', 'aiktp'),
    235                 array('status' => 403)
    236             );
    237         }
    238        
    239         // Also verify publish_posts capability for publish operations
    240         if (!user_can($user, 'publish_posts')) {
    241             return new WP_Error(
    242                 'rest_forbidden',
    243                 __('Configured AIKTP author does not have permission to publish posts. Please check plugin settings.', 'aiktp'),
     266                __('User does not have permission to create and publish posts.', 'aiktp'),
    244267                array('status' => 403)
    245268            );
     
    270293        $user = get_userdata($aiktp_author);
    271294       
     295        // If configured author doesn't exist or doesn't have upload permission, find a valid admin
    272296        if (!$user || !user_can($user, 'upload_files')) {
     297            // Try to find an administrator user
     298            $admins = get_users(array(
     299                'role' => 'administrator',
     300                'number' => 1,
     301                'orderby' => 'ID',
     302                'order' => 'ASC'
     303            ));
     304           
     305            if (!empty($admins)) {
     306                $user = $admins[0];
     307                // Update the option to use this admin for future requests
     308                update_option('aiktp_author', $user->ID);
     309            } else {
     310                return new WP_Error(
     311                    'rest_forbidden',
     312                    __('No administrator user found. Please ensure at least one administrator account exists.', 'aiktp'),
     313                    array('status' => 403)
     314                );
     315            }
     316        }
     317       
     318        // Double-check the user has upload capability
     319        if (!user_can($user, 'upload_files')) {
    273320            return new WP_Error(
    274321                'rest_forbidden',
    275                 __('Configured AIKTP author does not have permission to upload files. Please check plugin settings.', 'aiktp'),
     322                __('User does not have permission to upload files.', 'aiktp'),
    276323                array('status' => 403)
    277324            );
     
    329376     *
    330377     * SECURITY NOTE:
    331      * Authentication is handled by the permission_callback (verify_user_logged_in).
    332      * This function simply generates/returns the token for authenticated users.
     378     * Authentication is handled by the permission_callback (verify_admin_capability).
     379     * This function simply generates/returns the token for authenticated administrators.
    333380     *
    334381     * We do NOT manually validate cookies or set current user here.
  • aiktp/trunk/readme.txt

    r3430333 r3445248  
    55Tested up to: 6.9
    66Requires PHP: 7.0
    7 Stable tag: 5.0.04
     7Stable tag: 5.0.05
    88License: GPL v2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    8787== Changelog ==
    8888
     89= 5.0.05 =
     90* SECURITY FIX: Fixed authorization vulnerability (CVE-2026-1103) in /getToken endpoint
     91* Changed permission callback from verify_user_logged_in to verify_admin_capability
     92* Now requires manage_options capability to retrieve sync token
     93* Prevents subscribers and low-privilege users from accessing admin token
     94* Comprehensive security review and WordPress coding standards compliance
     95
     96= 5.0.04 =
     97* Improved REST API authentication and authorization
     98* Enhanced token-based security for external integrations
     99
    89100= 4.0.3 =
    90101* Added GPL v2 license
Note: See TracChangeset for help on using the changeset viewer.