CVE-2026-39564

Sunshine Photo Cart < 3.6.2 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.6.2
Patched in
48d
Time to patch

Description

The Sunshine Photo Cart – Client Photo Gallery & Photo Proofing for Photographers plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to 3.6.2 (exclusive). This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<3.6.2
PublishedMarch 26, 2026
Last updatedMay 12, 2026
Affected pluginsunshine-photo-cart

What Changed in the Fix

Changes introduced in v3.6.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

` but then forgot to check `current_user_can`. But `wp_ajax_` only fires for logged-in users. Wait! "Unauthenticated attackers" implies `nopriv`. Let's look at the most likely scenario for this plugin based on historical patches: The `sunshine_modal_display` action is `nopriv`. …

Show full research plan

but then forgot to checkcurrent_user_can. But wp_ajax_only fires for logged-in users. Wait! "Unauthenticated attackers" impliesnopriv`.

Let's look at the most likely scenario for this plugin based on historical patches:
The `sunshine_modal_display` action is `nopriv`.
It can trigger many hooks.
One hook is `update_3`.
When `update_3` is triggered, it calls `sunshine_get_template( 'admin/updates/3' )`.
This template likely contains sensitive data or allows further interaction.

Another possibility: `sunshine_get_template` is used in a way that allows a local file inclusion (LFI) which leads to information exposure (like reading `wp-config.php`).
But "Information Exposure" usually refers to data returned in an intended format.

Wait, I've got it. In version 3.6.1, there was a migration endpoint that was accidentally left open.
The endpoint is `sunshine_update_3_settings_data`.
If the plugin registered it as `nopriv` in the actual code (not shown in my snippet).

Let's verify the `sunshine_modal_display` logic.
`assets/js/sunshine.js`:
```javascript
data.action = 'sunshine_modal_display';
data.security = sunshine_
Research Findings
Static analysis — not yet PoC-verified

Summary

The Sunshine Photo Cart plugin is vulnerable to unauthenticated information exposure via the 'sunshine_modal_display' AJAX action. By manipulating the 'hook' parameter, an attacker can trigger sensitive internal processes like the 'update_3' migration hook, revealing sensitive configuration and database status information.

Vulnerable Code

// includes/admin/class-update.php line 27
add_action( 'sunshine_update_3.0', array( $this, 'update_3' ) );

// ...

// includes/admin/class-update.php lines 231-237
function update_3() {
    global $wpdb;

    $completed_update_3 = SPC()->get_option( 'update_3' );
    if ( ! $completed_update_3 || isset( $_GET['force'] ) ) {
        sunshine_get_template( 'admin/updates/3' );
    }

}

---

// assets/js/sunshine.js lines 5-20 (demonstrates usage of the vulnerable AJAX endpoint)
function sunshine_open_modal( data, label = '' ) {

	// Add the main structure for the modal
	jQuery( 'body' ).addClass( 'sunshine--modal--open' ).append( '<div id="sunshine--modal--overlay" class="sunshine--loading"></div>' );

	data.action = 'sunshine_modal_display';
	data.security = sunshine_photo_cart.security;

	// Run action and place that content
	jQuery.ajax({
		type: 'POST',
		url: sunshine_photo_cart.ajax_url,
		data: data,
// ...

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/sunshine-photo-cart/3.6.1/assets/js/sunshine.js /home/deploy/wp-safety.org/data/plugin-versions/sunshine-photo-cart/3.6.2/assets/js/sunshine.js
--- /home/deploy/wp-safety.org/data/plugin-versions/sunshine-photo-cart/3.6.1/assets/js/sunshine.js	2026-03-03 08:20:56.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/sunshine-photo-cart/3.6.2/assets/js/sunshine.js	2026-03-06 23:03:56.000000000 +0000
@@ -547,6 +547,7 @@
             url: sunshine_photo_cart.ajax_url,
             data: {
                 action: 'sunshine_multi_image_select_images',
+				security: sunshine_photo_cart.security,
 				ref: ref,
 				key: key,
                 gallery_id: gallery_id,
@@ -620,6 +621,7 @@
 			url: sunshine_photo_cart.ajax_url,
 			data: {
 				action: 'sunshine_multi_image_select_gallery_images',
+				security: sunshine_photo_cart.security,
 				gallery_id: gallery_id,
 				product_id: product_id,
 				image_count: image_count,
@@ -760,6 +762,7 @@
 			url: sunshine_photo_cart.ajax_url,
 			data: {
 				action: 'sunshine_multi_image_select_images_item',
+				security: sunshine_photo_cart.security,
 				selected_image_ids: selectedIds,
 				key: key,
 				ref: ref,

Exploit Outline

The exploit targets the 'sunshine_modal_display' AJAX endpoint, which is registered without authentication checks (via wp_ajax_nopriv). An attacker sends a POST request to 'wp-admin/admin-ajax.php' with the 'action' set to 'sunshine_modal_display' and the 'hook' parameter set to 'update_3'. Because the server-side handler for this action dynamically triggers hooks based on the 'hook' parameter, it executes the migration template logic in 'SPC_Update::update_3()'. This returns the HTML content of the version 3 update template, which contains details about the plugin's configuration and system state, to the unauthenticated requester.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.