CVE-2026-56007

Ocean Product Sharing <= 2.2.2 - Authenticated (Shop manager+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
4.4
CVSS Score
4.4
CVSS Score
medium
Severity
2.2.3
Patched in
6d
Time to patch

Description

The Ocean Product Sharing plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.2.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with shop manager-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.2.2
PublishedJune 18, 2026
Last updatedJune 23, 2026
Affected pluginocean-product-sharing

What Changed in the Fix

Changes introduced in v2.2.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-56007 (Ocean Product Sharing Stored XSS) ## 1. Vulnerability Summary The **Ocean Product Sharing** plugin (up to 2.2.2) is vulnerable to Stored Cross-Site Scripting (XSS) due to improper sanitization and escaping of plugin settings managed through the WordPres…

Show full research plan

Exploitation Research Plan: CVE-2026-56007 (Ocean Product Sharing Stored XSS)

1. Vulnerability Summary

The Ocean Product Sharing plugin (up to 2.2.2) is vulnerable to Stored Cross-Site Scripting (XSS) due to improper sanitization and escaping of plugin settings managed through the WordPress Customizer. Specifically, settings related to colors and styling (e.g., icon colors, background colors) are stored and subsequently output into the site's <head> within a <style> block via the ocean_head_css filter. Because the plugin does not properly sanitize these inputs upon saving or escape them upon output, an authenticated user with permission to modify these settings (Shop Managers and above) can inject malicious scripts.

This vulnerability is significant in environments where unfiltered_html is disabled (such as WordPress Multi-site for non-Super Admins), as it allows users to bypass intended security restrictions on executing JavaScript.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: customize_save (Standard WordPress Customizer save action)
  • Vulnerable Parameter: customized (A JSON-encoded string containing the setting ID and its malicious value)
  • Setting IDs (Inferred from includes/options.php and .pot file):
    • ocean_product_sharing_borders_color
    • ocean_product_sharing_bg_color
    • ocean_product_sharing_icons_color
  • Authentication: Authenticated (Shop Manager or higher). Note that Shop Managers must have the edit_theme_options capability or the plugin must explicitly grant them access to its Customizer section.
  • Preconditions: The OceanWP theme must be active, as the plugin hooks into OceanWP-specific filters (ocean_customize_options_data, ocean_head_css).

3. Code Flow

  1. Entry Point: An authenticated user accesses the WordPress Customizer.
  2. Registration: Ocean_Product_Sharing::register_customize_options (in ocean-product-sharing.php) calls ops_customizer_options() (in includes/options.php) to register settings like ocean_product_sharing_icons_color.
  3. Storage: When the user saves settings, a POST request is sent to admin-ajax.php with action=customize_save. WordPress core saves the values into the wp_options table.
  4. Retrieval & Sink:
    • On the frontend, Ocean_Product_Sharing::ops_setup registers the filter add_filter('ocean_head_css', array( $this, 'ops_head_css' ));.
    • The ops_head_css function (likely in includes/helpers.php) retrieves the stored options using get_theme_mod() or get_option().
    • The values are concatenated into a CSS string and returned to the theme, which outputs them inside a <style> tag in the <head> of the page.
    • If a color value like */</style><script>alert(1)</script><style>/* is used, it breaks out of the CSS context and executes the script.

4. Nonce Acquisition Strategy

The WordPress Customizer requires a specific nonce for the customize_save action. This nonce is unique to the user's session.

  1. Preparation: Ensure the agent is logged in as a user with Shop Manager or Admin privileges.
  2. Navigation: Use browser_navigate to go to the Customizer page: /wp-admin/customize.php.
  3. Extraction: Use browser_eval to extract the nonce and customize_url from the _wpCustomizeSettings object globally available in the Customizer's JavaScript context.
    • JavaScript: window._wpCustomizeSettings?.nonce?.save
  4. Identification: The customize_save action also requires a customized parameter containing the changes.

5. Exploitation Strategy

  1. Construct Payload: The payload must break out of a CSS declaration.
    • Example: green; } </style><script>alert(document.domain)</script><style> .dummy { color: blue
  2. Request Construction: Use the http_request tool to send the following POST request:
    • URL: https://<target>/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body Parameters:
      • action: customize_save
      • wp_customize: on
      • nonce: [EXTRACTED_NONCE]
      • customized: {"ocean_product_sharing_icons_color":"green;}</style><script>alert(1)</script><style>/*"}
  3. Triggering: Navigate to any single product page (WooCommerce) or download item (EDD) where the sharing buttons are rendered.

6. Test Data Setup

  1. Theme: Install and activate the OceanWP theme.
  2. Dependencies: Install and activate WooCommerce.
  3. Product: Create at least one public product:
    • wp post create --post_type=product --post_title="Security Test Product" --post_status=publish
  4. Plugin Config: Ensure the "Product Sharing" feature is enabled in the Customizer settings.
  5. User: Create a Shop Manager user if testing role-based access:
    • wp user create shopmanager shopmanager@example.com --role=shop_manager --user_pass=password

7. Expected Results

  • The admin-ajax.php request should return a 200 OK with a JSON response indicating {"success":true}.
  • Upon visiting the "Security Test Product" page, the HTML source code within the <head> section should contain the injected <script> tag.
  • The browser should execute the JavaScript payload.

8. Verification Steps

  1. DB Check: Use WP-CLI to verify the option is stored:
    • wp option get theme_mods_oceanwp (Look for the ocean_product_sharing_icons_color key).
  2. Response Check: Use http_request (GET) to fetch the product page and grep for the payload:
    • grep -a10 "ocean-product-sharing" product_page_source.html

9. Alternative Approaches

  • Other Settings: If ocean_product_sharing_icons_color is sanitized, attempt exploitation via ocean_product_sharing_bg_color or ocean_product_sharing_borders_color.
  • Direct Option Update: If the Customizer UI is restricted, check if the plugin exposes an AJAX handler for its "Theme Panel" (referenced in ocean-product-sharing.php as oe_theme_panels) which might allow updating options with lower capability requirements.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Ocean Product Sharing plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to 2.2.2. This occurs due to insufficient input sanitization and output escaping of settings managed through the WordPress Customizer and product metadata, allowing authenticated attackers with Shop Manager privileges or higher to inject arbitrary web scripts into pages.

Vulnerable Code

// ocean-product-sharing.php line 261
	public function register_customize_options($options) {

		if ( OCEAN_EXTRA_ACTIVE
			&& class_exists( 'Ocean_Extra_Theme_Panel' ) ) {

			if ( empty( Ocean_Extra_Theme_Panel::get_setting( 'ocean_product_sharing_panel' ) ) ) {
				return $options;
			}

		}

		include_once $this->plugin_path . '/includes/options.php';

		$options['ocean_product_sharing_settings'] = ops_customizer_options();

		return $options;
	}

---

// template/product-share.php line 21
$product_title = get_the_title();
$product_url   = get_permalink();
$product_img   = wp_get_attachment_url( get_post_thumbnail_id() ); ?>

<div class="oew-product-share clr">

	<ul class="ocean-social-share clr" aria-label="<?php echo esc_attr__( 'Share this product on social media', 'ocean-product-sharing' ); ?>">

// ... lines 39, 77, and 100 contain variations of:
// echo html_entity_decode( wp_strip_all_tags( $product_title ) );

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/ocean-product-sharing/2.2.2/template/product-share.php /home/deploy/wp-safety.org/data/plugin-versions/ocean-product-sharing/2.2.3/template/product-share.php
--- /home/deploy/wp-safety.org/data/plugin-versions/ocean-product-sharing/2.2.2/template/product-share.php	2023-12-11 11:02:30.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/ocean-product-sharing/2.2.3/template/product-share.php	2026-06-15 10:26:18.000000000 +0000
@@ -19,9 +19,43 @@
 }
 
 // Vars
-$product_title = get_the_title();
+$product_title = wp_strip_all_tags( get_the_title() );
 $product_url   = get_permalink();
-$product_img   = wp_get_attachment_url( get_post_thumbnail_id() ); ?>
+$product_img   = wp_get_attachment_url( get_post_thumbnail_id() );
+
+$twitter_url = add_query_arg(
+	array(
+		'text' => $product_title,
+		'url'  => $product_url,
+	),
+	'https://twitter.com/intent/tweet'
+);
+
+$facebook_url = add_query_arg(
+	array(
+		'u' => $product_url,
+	),
+	'https://www.facebook.com/sharer.php'
+);
+
+$pinterest_url = add_query_arg(
+	array(
+		'url'         => $product_url,
+		'media'       => $product_img,
+		'description' => $product_title,
+	),
+	'https://www.pinterest.com/pin/create/button/'
+);
+
+$email_url = add_query_arg(
+	array(
+		'subject' => $product_title,
+		'body'    => $product_url,
+	),
+	'mailto:'
+);
+
+?>
 
 <div class="oew-product-share clr">
 
@@ -36,7 +70,7 @@
 				?>
 
 				<li class="twitter">
-					<a aria-label="<?php esc_attr_e( 'Share this product on X', 'ocean-product-sharing' ); ?>" class="twitter-share-button" href="https://twitter.com/intent/tweet?text=<?php echo html_entity_decode( wp_strip_all_tags( $product_title ) ); ?>+<?php echo esc_url( $product_url ); ?>" onclick="ops_onClick( this.href );return false;">
+					<a aria-label="<?php esc_attr_e( 'Share this product on X', 'ocean-product-sharing' ); ?>" class="twitter-share-button" href="<?php echo esc_url( $twitter_url ); ?>" onclick="ops_onClick( this.href );return false;">
 						<span class="screen-reader-text"><?php echo esc_attr__( 'Opens in a new window', 'ocean-product-sharing' ); ?></span>
 						<span class="ops-icon-wrap">
 							<svg class="ops-icon" role="img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
@@ -54,7 +88,7 @@
 				?>
 
 				<li class="facebook">
-					<a href="https://www.facebook.com/sharer.php?u=<?php echo rawurlencode( esc_url( $product_url ) ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share on Facebook', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
+					<a href="<?php echo esc_url( $facebook_url ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share on Facebook', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
 						<span class="screen-reader-text"><?php echo esc_attr__( 'Opens in a new window', 'ocean-product-sharing' ); ?></span>
 						<span class="ops-icon-wrap">
 							<svg class="ops-icon" role="img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
@@ -74,7 +108,7 @@
 				?>
 
 				<li class="pinterest">
-					<a href="https://www.pinterest.com/pin/create/button/?url=<?php echo rawurlencode( esc_url( $product_url ) ); ?>&amp;media=<?php echo wp_get_attachment_url( get_post_thumbnail_id() ); ?>&amp;description=<?php echo rawurlencode( wp_strip_all_tags( $product_title ) ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share on Pinterest', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
+					<a href="<?php echo esc_url( $pinterest_url ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share on Pinterest', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
 						<span class="screen-reader-text"><?php echo esc_attr__( 'Opens in a new window', 'ocean-product-sharing' ); ?></span>
 						<span class="ops-icon-wrap">
 							<svg class="ops-icon" role="img" viewBox="0 0 496 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
@@ -97,7 +131,7 @@
 				?>
 
 				<li class="email">
-					<a href="mailto:?subject=<?php echo html_entity_decode( wp_strip_all_tags( $product_title ) ); ?>&amp;body=<?php echo esc_url( $product_url ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share via email', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
+					<a href="<?php echo esc_url( $email_url, array( 'mailto' ) ); ?>" target="_blank" aria-label="<?php esc_attr_e( 'Share via email', 'ocean-product-sharing' ); ?>" onclick="ops_onClick( this.href );return false;">
 						<span class="screen-reader-text"><?php echo esc_attr__( 'Opens in a new window', 'ocean-product-sharing' ); ?></span>
 						<span class="ops-icon-wrap">
 							<svg class="ops-icon" role="img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">

Exploit Outline

To exploit this vulnerability, an attacker must have Shop Manager or higher privileges. The primary attack vector involves the WordPress Customizer, where an attacker can submit a payload through the 'customize_save' AJAX action. By injecting a payload like `*/</style><script>alert(1)</script><style>/*` into styling settings (such as `ocean_product_sharing_icons_color`), the attacker can break out of the CSS block generated by the `ocean_head_css` filter in the document head. Alternatively, malicious scripts can be injected into product titles, which are rendered unescaped in the social sharing links on the front-end product pages. The vulnerability is especially effective in multi-site environments or where `unfiltered_html` is disabled.

Check if your site is affected.

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