Changeset 3445248
- Timestamp:
- 01/23/2026 01:50:30 AM (2 months ago)
- Location:
- aiktp/trunk
- Files:
-
- 3 edited
-
aiktp.php (modified) (2 diffs)
-
includes/aiktp-sync.php (modified) (5 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
aiktp/trunk/aiktp.php
r3430333 r3445248 4 4 * Plugin URI: https://aiktp.com/wordpress 5 5 * 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.0 46 * Version: 5.0.05 7 7 * Author: John Luke - aiktp.com 8 8 * License: GPL v2 or later … … 22 22 23 23 // Define constants 24 define('AIKTPZ_VERSION', '5.0.0 4');24 define('AIKTPZ_VERSION', '5.0.05'); 25 25 define('AIKTPZ_PLUGIN_DIR', plugin_dir_path(__FILE__)); 26 26 define('AIKTPZ_PLUGIN_URL', plugin_dir_url(__FILE__)); -
aiktp/trunk/includes/aiktp-sync.php
r3430333 r3445248 121 121 'methods' => 'GET', 122 122 '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. 136 137 * 137 138 * When calling this endpoint from JavaScript, you MUST include the nonce header: … … 139 140 * 140 141 * @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()) { 149 147 return new WP_Error( 150 148 'rest_forbidden', 151 149 __('You must be logged in to WordPress to access this endpoint. Please include authentication headers (X-WP-Nonce) in your request.', 'aiktp'), 152 150 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) 153 160 ); 154 161 } … … 229 236 // Verify the configured author exists and has edit_posts capability 230 237 $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')) { 232 264 return new WP_Error( 233 265 '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'), 244 267 array('status' => 403) 245 268 ); … … 270 293 $user = get_userdata($aiktp_author); 271 294 295 // If configured author doesn't exist or doesn't have upload permission, find a valid admin 272 296 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')) { 273 320 return new WP_Error( 274 321 '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'), 276 323 array('status' => 403) 277 324 ); … … 329 376 * 330 377 * 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. 333 380 * 334 381 * We do NOT manually validate cookies or set current user here. -
aiktp/trunk/readme.txt
r3430333 r3445248 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.0 7 Stable tag: 5.0.0 47 Stable tag: 5.0.05 8 8 License: GPL v2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 87 87 == Changelog == 88 88 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 89 100 = 4.0.3 = 90 101 * Added GPL v2 license
Note: See TracChangeset
for help on using the changeset viewer.