Sunshine Photo Cart – Client Photo Gallery & Photo Proofing for Photographers <= 3.6.7 - Missing Authorization
Description
The Sunshine Photo Cart – Client Photo Gallery & Photo Proofing for Photographers plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.6.7. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.6.7What Changed in the Fix
Changes introduced in v3.6.8
Source Code
WordPress.org SVNThis research plan outlines the technical steps to exploit a missing authorization vulnerability in Sunshine Photo Cart <= 3.6.7. ## 1. Vulnerability Summary The **Sunshine Photo Cart** plugin for WordPress registers several AJAX handlers intended for administrative use using the `wp_ajax_` hook. I…
Show full research plan
This research plan outlines the technical steps to exploit a missing authorization vulnerability in Sunshine Photo Cart <= 3.6.7.
1. Vulnerability Summary
The Sunshine Photo Cart plugin for WordPress registers several AJAX handlers intended for administrative use using the wp_ajax_ hook. In versions up to 3.6.7, specifically within the SPC_Dashboard_Widget class and likely the SPC_Admin_Order and Sunshine_Admin classes, these handlers lack proper capability checks (e.g., current_user_can('manage_options')).
This oversight allows any authenticated user, including those with Subscriber level permissions, to perform unauthorized actions such as viewing sensitive financial sales data or potentially modifying order and gallery metadata.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method: POST
- Authentication: Subscriber-level account or higher.
- Vulnerable Actions:
sunshine_dashboard_calculate_stats: Discloses sales totals (Confidentiality).sunshine_order_save_notes: Modifies order notes (Integrity - inferred fromsunshine-order.php).sunshine_post_sort: Reorders posts/galleries (Integrity - inferred fromclass-admin.php).
- Preconditions: At least one order must exist in the system for the stats disclosure to be meaningful
Summary
The Sunshine Photo Cart plugin for WordPress is vulnerable to unauthorized access and data disclosure due to missing capability checks and nonce verification on several AJAX handlers and administrative functions. Authenticated attackers with subscriber-level permissions or higher can view sensitive financial sales data, reorder galleries/products, and potentially perform unauthorized gallery imports.
Vulnerable Code
// includes/admin/dashboard.php line 109 function calculate_stats() { global $wpdb; $data = get_transient( 'sunshine-dashboard-sales' ); if ( empty( $data ) ) { --- // includes/admin/class-admin.php line 703 public function term_sort() { $categories = sanitize_text_field( $_POST['categories'] ); $categories = str_replace( 'tag-', '', $categories ); $categories = explode( ',', $categories ); $i = 1; foreach ( $categories as $category_id ) { update_term_meta( $category_id, 'order', $i ); $i++; } } public function post_sort() { $posts = sanitize_text_field( $_POST['posts'] ); $posts = str_replace( 'post-', '', $posts ); $posts = explode( ',', $posts ); $i = 1; foreach ( $posts as $post_id ) { wp_update_post( array( 'ID' => $post_id, 'menu_order' => $i, ) ); $i++; } } --- // includes/admin/class-admin.php line 981 public function show_post_debug() { if ( isset( $_GET['sunshine_debug'] ) && isset( $_GET['post'] ) ) { $meta = get_post_meta( intval( $_GET['post'] ) ); echo '<!-- SUNSHINE DEBUG META -->'; sunshine_dump_var( $meta ); --- // includes/admin/sunshine-gallery.php line 1703 function sunshine_ajax_gallery_import_list() { if ( ! current_user_can( 'upload_files' ) ) { wp_send_json_error( array( 'message' => __( 'You do not have permission to import images.', 'sunshine-photo-cart' ), ) ); }
Security Fix
@@ -701,23 +710,53 @@ } public function term_sort() { - $categories = sanitize_text_field( $_POST['categories'] ); + check_ajax_referer( 'sunshine_sort', 'security' ); + + if ( ! current_user_can( 'sunshine_manage_options' ) ) { + wp_send_json_error(); + } + + $allowed_taxonomies = array( 'sunshine-product-category', 'sunshine-product-option' ); + + $categories = isset( $_POST['categories'] ) ? sanitize_text_field( wp_unslash( $_POST['categories'] ) ) : ''; $categories = str_replace( 'tag-', '', $categories ); $categories = explode( ',', $categories ); $i = 1; foreach ( $categories as $category_id ) { + $category_id = absint( $category_id ); + if ( ! $category_id ) { + continue; + } + $term = get_term( $category_id ); + if ( ! $term || is_wp_error( $term ) || ! in_array( $term->taxonomy, $allowed_taxonomies, true ) ) { + continue; + } update_term_meta( $category_id, 'order', $i ); $i++; } + + wp_send_json_success(); } public function post_sort() { - $posts = sanitize_text_field( $_POST['posts'] ); + check_ajax_referer( 'sunshine_sort', 'security' ); + + if ( ! current_user_can( 'sunshine_manage_options' ) ) { + wp_send_json_error(); + } + + $allowed_post_types = array( 'sunshine-product', 'sunshine-gallery' ); + + $posts = isset( $_POST['posts'] ) ? sanitize_text_field( wp_unslash( $_POST['posts'] ) ) : ''; $posts = str_replace( 'post-', '', $posts ); $posts = explode( ',', $posts ); $i = 1; foreach ( $posts as $post_id ) { + $post_id = absint( $post_id ); + if ( ! $post_id || ! in_array( get_post_type( $post_id ), $allowed_post_types, true ) ) { + continue; + } wp_update_post( array( 'ID' => $post_id, @@ -726,6 +765,8 @@ ); $i++; } + + wp_send_json_success(); } @@ -109,6 +110,12 @@ function calculate_stats() { global $wpdb; + check_ajax_referer( 'sunshine_dashboard', 'security' ); + + if ( ! current_user_can( 'sunshine_manage_options' ) ) { + wp_send_json_error(); + } + $data = get_transient( 'sunshine-dashboard-sales' ); if ( empty( $data ) ) {
Exploit Outline
To exploit this vulnerability, an attacker first authenticates as a Subscriber (or any other user role). They then send POST requests to the `/wp-admin/admin-ajax.php` endpoint. To disclose sales data, the attacker sets the `action` parameter to `sunshine_dashboard_calculate_stats`. Because version 3.6.7 fails to check user capabilities or nonces for this action, the server will calculate and return financial statistics (current month, last month, and lifetime sales totals) in the JSON response. Similar unauthorized actions can be performed by targeting other vulnerable actions like `sunshine_post_sort` (to modify the order of galleries) or by accessing administrative URLs with the `sunshine_debug` parameter to leak metadata.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.