REPORT / 01

Analysis Report · Folder Analysis cache/recras_6.4.1 → cache/recras_6.4.2 — CVE-2025-13497

Shared security patch analysis results

mode patchdiff ai claude_cli haiku
02 · Lifecycle actions cancel · resume · skip · regenerate
03 · Share this analysis copy link · embed report
03 · CVE Security Analysis & Writeups ai-generated · per cve

Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.

CVE-2025-13497 NVD
AI-Generated Analysis
05 · Findings filter · search · paginate
Use quotes for exact: "SQL injection" · Operators: hello AND bye, admin OR root, -error, NOT warning
Showing 0 to 0 of 0 results
editor/form-booking.php AI: No vulnerabilities CVE-2025-13497
--- cache/recras_6.4.1/editor/form-booking.php	2026-01-07 00:37:12.805967553 +0000+++ cache/recras_6.4.2/editor/form-booking.php	2026-01-07 00:37:26.254801297 +0000@@ -1,108 +1,108 @@ <?php-$instance = \Recras\Settings::getInstance();-if (!$instance) {+$recras_instance = \Recras\Settings::getInstance();+if (!$recras_instance) {     \Recras\Settings::errorNoRecrasName();     return; } -$model = new \Recras\Arrangement();-$arrangements = $model->getPackages($instance, true);+$recras_packages_model = new \Recras\Arrangement();+$recras_packages = $recras_packages_model->getPackages($recras_instance, true); ?> <dl>-    <dt><label><?php _e('Integration method', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label><?php esc_html_e('Integration method', 'recras'); ?></label>         <dd>             <label>                 <input type="radio" id="use_new_library_yes" name="integration_method" value="jslibrary" checked>-                <?php _e('Seamless (recommended)', \Recras\Plugin::TEXT_DOMAIN); ?>+                <?php esc_html_e('Seamless (recommended)', 'recras'); ?>             </label>             <br>             <label>                 <input type="radio" id="use_new_library_no" name="integration_method" value="iframe">-                <?php _e('iframe (uses setting in your Recras)', \Recras\Plugin::TEXT_DOMAIN); ?>+                <?php esc_html_e('iframe (uses setting in your Recras)', 'recras'); ?>             </label>         <p class="recras-notice">             <?php-            _e('Seamless integration uses the styling of your website. At Recras → Settings in the menu on the left, you can set an optional theme.', \Recras\Plugin::TEXT_DOMAIN);+            esc_html_e('Seamless integration uses the styling of your website. At Recras → Settings in the menu on the left, you can set an optional theme.', 'recras');             ?>             <br>             <?php-            _e('iframe integration uses the styling set in your Recras. You can change the styling in Recras via Settings → Other settings → Custom CSS.', \Recras\Plugin::TEXT_DOMAIN);+            esc_html_e('iframe integration uses the styling set in your Recras. You can change the styling in Recras via Settings → Other settings → Custom CSS.', 'recras');             ?>         </p>      <dt id="pack_sel_label">-        <label for="package_selection"><?php _e('Package selection', \Recras\Plugin::TEXT_DOMAIN); ?></label>+        <label for="package_selection"><?php esc_html_e('Package selection', 'recras'); ?></label>     <dd id="pack_sel_input">-        <?php unset($arrangements[0]); ?>+        <?php unset($recras_packages[0]); ?>         <select multiple id="package_selection">-            <?php foreach ($arrangements as $ID => $arrangement) { ?>-            <option value="<?= $ID; ?>"><?= $arrangement->arrangement; ?>+            <?php foreach ($recras_packages as $recras_package_id => $recras_package) { ?>+            <option value="<?= esc_html($recras_package_id); ?>"><?= esc_html($recras_package->arrangement); ?>             <?php } ?>         </select>         <p class="recras-notice">             <?php-            _e('To (de)select multiple packages, hold Ctrl and click (Cmd on Mac)', \Recras\Plugin::TEXT_DOMAIN);+            esc_html_e('To (de)select multiple packages, hold Ctrl and click (Cmd on Mac)', 'recras');             ?>         </p>     <dt id="pack_one_label" style="display: none;">-        <label for="arrangement_id"><?php _e('Package', \Recras\Plugin::TEXT_DOMAIN); ?></label>+        <label for="arrangement_id"><?php esc_html_e('Package', 'recras'); ?></label>     <dd id="pack_one_input" style="display: none;">-        <?php if (is_string($arrangements)) { ?>+        <?php if (is_string($recras_packages)) { ?>             <input type="number" id="arrangement_id" min="0">-            <?= $arrangements; ?>-        <?php } elseif(is_array($arrangements)) { ?>-            <?php unset($arrangements[0]); ?>+            <?= esc_html($recras_packages); ?>+        <?php } elseif(is_array($recras_packages)) { ?>+            <?php unset($recras_packages[0]); ?>             <select id="arrangement_id" required>-                <option value="0"><?php _e('No pre-filled package', \Recras\Plugin::TEXT_DOMAIN); ?>-                <?php foreach ($arrangements as $ID => $arrangement) { ?>-                <option value="<?= $ID; ?>"><?= $arrangement->arrangement; ?>+                <option value="0"><?php esc_html_e('No pre-filled package', 'recras'); ?>+                <?php foreach ($recras_packages as $recras_package_id => $recras_package) { ?>+                <option value="<?= esc_html($recras_package_id); ?>"><?= esc_html($recras_package->arrangement); ?>                 <?php } ?>             </select>         <?php } ?> -    <dt><label for="show_times"><?php _e('Preview times in programme', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="show_times"><?php esc_html_e('Preview times in programme', 'recras'); ?></label>         <dd><input type="checkbox" id="show_times">-    <dt><label><?php _e('Pre-fill amounts (requires pre-filled package)', \Recras\Plugin::TEXT_DOMAIN); ?></label>-        <dd><strong><?php _e('Sorry, this is only available using the Gutenberg editor.', \Recras\Plugin::TEXT_DOMAIN); ?></strong>-    <dt><label for="prefill_date"><?php _e('Pre-fill date (requires exactly 1 package selected)',\Recras\Plugin::TEXT_DOMAIN ); ?></label>+    <dt><label><?php esc_html_e('Pre-fill amounts (requires pre-filled package)', 'recras'); ?></label>+        <dd><strong><?php esc_html_e('Sorry, this is only available using the Gutenberg editor.', 'recras'); ?></strong>+    <dt><label for="prefill_date"><?php esc_html_e('Pre-fill date (requires exactly 1 package selected)','recras' ); ?></label>         <dd><input             type="date"             id="prefill_date"-            min="<?= date('Y-m-d') ?>"-            pattern="<?= \Recras\ContactForm::PATTERN_DATE; ?>"-            placeholder="<?= __('yyyy-mm-dd', \Recras\Plugin::TEXT_DOMAIN); ?>"+            min="<?= esc_html(date('Y-m-d')); ?>"+            pattern="<?= esc_html(\Recras\ContactForm::PATTERN_DATE); ?>"+            placeholder="<?= esc_html(__('yyyy-mm-dd', 'recras')); ?>"             disabled         >-    <dt><label for="prefill_time"><?php _e('Pre-fill time (requires exactly 1 package selected)',\Recras\Plugin::TEXT_DOMAIN ); ?></label>+    <dt><label for="prefill_time"><?php esc_html_e('Pre-fill time (requires exactly 1 package selected)','recras' ); ?></label>         <dd><input             type="time"             id="prefill_time"-            pattern="<?= \Recras\ContactForm::PATTERN_TIME; ?>"+            pattern="<?= esc_html(\Recras\ContactForm::PATTERN_TIME); ?>"             step="300"-            placeholder="<?= __('hh:mm', \Recras\Plugin::TEXT_DOMAIN); ?>"+            placeholder="<?= esc_html(__('hh:mm', 'recras')); ?>"             disabled         >-    <dt><label for="redirect_page"><?php _e('Thank-you page', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="redirect_page"><?php esc_html_e('Thank-you page', 'recras'); ?></label>         <dd><select id="redirect_page">-            <option value=""><?php _e("Don't redirect", \Recras\Plugin::TEXT_DOMAIN); ?>-            <optgroup label="<?php _e('Pages', \Recras\Plugin::TEXT_DOMAIN); ?>">+            <option value=""><?php esc_html_e("Don't redirect", 'recras'); ?>+            <optgroup label="<?php esc_html_e('Pages', 'recras'); ?>">                 <?php foreach (get_pages() as $page) { ?>-                <option value="<?= get_permalink($page->ID); ?>"><?= htmlspecialchars($page->post_title); ?>-                    <?php } ?>+                <option value="<?= esc_html(get_permalink($page->ID)); ?>"><?= esc_html($page->post_title); ?>+                <?php } ?>             </optgroup>-            <optgroup label="<?php _e('Posts', \Recras\Plugin::TEXT_DOMAIN); ?>">+            <optgroup label="<?php esc_html_e('Posts', 'recras'); ?>">                 <?php foreach (get_posts() as $post) { ?>-                <option value="<?= get_permalink($post->ID); ?>"><?= htmlspecialchars($post->post_title); ?>-                    <?php } ?>+                <option value="<?= esc_html(get_permalink($post->ID)); ?>"><?= esc_html($post->post_title); ?>+                <?php } ?>             </optgroup>         </select>-    <dt><label for="show_discounts"><?php _e('Show discount fields', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="show_discounts"><?php esc_html_e('Show discount fields', 'recras'); ?></label>         <dd><input type="checkbox" id="show_discounts" checked>-    <dt><label for="auto_resize"><?php _e('Automatic resize?', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="auto_resize"><?php esc_html_e('Automatic resize?', 'recras'); ?></label>         <dd><input type="checkbox" id="auto_resize" disabled>  </dl>-<button class="button button-primary" id="booking_submit"><?php _e('Insert shortcode', \Recras\Plugin::TEXT_DOMAIN); ?></button>+<button class="button button-primary" id="booking_submit"><?php esc_html_e('Insert shortcode', 'recras'); ?></button>  <script>     [...document.querySelectorAll('[name="integration_method"]')].forEach(function(el) {@@ -142,7 +142,7 @@         } else {             packageIDsMultiple = [...selectedPackages].map(el => el.value);         }-        let shortcode = '[<?= \Recras\OnlineBooking::SHORTCODE; ?>';+        let shortcode = '[<?= esc_js(\Recras\OnlineBooking::SHORTCODE); ?>';         if (packageIDsMultiple.length > 0 && useNewLibrary) {             shortcode += ' package_list="' + packageIDsMultiple.join(',') + '"';         } else if (arrangementID) {
AI Analysis
# Security Analysis Report

## Summary
This diff contains security hardening measures focused on output escaping and variable naming improvements in a WordPress plugin file.

---

## Vulnerability 1

**Vulnerability Existed:** yes

**Cross-Site Scripting (XSS) - CWE-79 - editor/form-booking.php - Multiple lines (throughout)**

**Old Code:**
```php
<?php _e('Integration method', \Recras\Plugin::TEXT_DOMAIN); ?>
<?= $arrangement->arrangement; ?>
<?= $ID; ?>
<?= htmlspecialchars($page->post_title); ?>
<?= \Recras\OnlineBooking::SHORTCODE; ?>
```

**Fixed Code:**
```php
<?php esc_html_e('Integration method', 'recras'); ?>
<?= esc_html($recras_package->arrangement); ?>
<?= esc_html($recras_package_id); ?>
<?= esc_html($page->post_title); ?>
<?= esc_js(\Recras\OnlineBooking::SHORTCODE); ?>
```

**Explanation:**
The original code had multiple XSS vulnerabilities:

1. **Translation functions**: Used `_e()` instead of `esc_html_e()`, allowing unescaped HTML in translatable strings
2. **Variable output in HTML context**: Variables like `$arrangement->arrangement`, `$ID`, `$page->post_title`, and `$page->post_title` were output without proper escaping, vulnerable to XSS attacks
3. **Inconsistent escaping**: Used `htmlspecialchars()` which only escapes HTML entities but is less reliable than WordPress escaping functions
4. **JavaScript context**: The shortcode constant was output in JavaScript context without `esc_js()` escaping

The fixes properly use WordPress escaping functions:
- `esc_html_e()` for localized HTML output
- `esc_html()` for HTML context variables
- `esc_js()` for JavaScript context output
- Consistent use of the 'recras' text domain instead of `\Recras\Plugin::TEXT_DOMAIN`

---

## Vulnerability 2

**Vulnerability Existed:** yes

**Information Disclosure / Code Quality - editor/form-booking.php - Lines 1-9**

**Old Code:**
```php
$instance = \Recras\Settings::getInstance();
$model = new \Recras\Arrangement();
$arrangements = $model->getPackages($instance, true);
```

**Fixed Code:**
```php
$recras_instance = \Recras\Settings::getInstance();
$recras_packages_model = new \Recras\Arrangement();
$recras_packages = $recras_packages_model->getPackages($recras_instance, true);
```

**Explanation:**
While not a direct security vulnerability, the variable naming improvements reduce namespace collision risks and improve code clarity. Generic names like `$instance`, `$model`, and `$arrangements` could be accidentally overwritten or confused with other parts of the codebase. Prefixing with `recras_` makes the scope and purpose explicit, reducing the risk of variable shadowing attacks or accidental misuse that could lead to security issues downstream.

---

## Summary of Security Improvements

This patch implements **defense-in-depth output escaping** following WordPress security best practices:
- Eliminates XSS vulnerabilities in user-facing content
- Uses context-appropriate escaping functions (HTML vs JavaScript)
- Improves code maintainability through better variable naming conventions
CVE Analysis Results:
CVE-2025-13497: Yes
View CVE Description
The Recras WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'recrasname' shortcode attribute in all versions up to, and including, 6.4.1. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
editor/form-product.php AI: 1 vulnerabilities 1 true positive CVE-2025-13497
--- cache/recras_6.4.1/editor/form-product.php	2026-01-07 00:37:12.805967553 +0000+++ cache/recras_6.4.2/editor/form-product.php	2026-01-07 00:37:26.254801297 +0000@@ -1,43 +1,43 @@ <?php-$instance = \Recras\Settings::getInstance();-if (!$instance) {+$recras_instance = \Recras\Settings::getInstance();+if (!$recras_instance) {     \Recras\Settings::errorNoRecrasName();     return; } -$model = new \Recras\Products();-$products = $model->getProducts($instance);+$recras_products_model = new \Recras\Products();+$recras_products = $recras_products_model->getProducts($recras_instance); ?>  <dl>-    <dt><label for="product_id"><?php _e('Product', \Recras\Plugin::TEXT_DOMAIN); ?></label>-    <dd><?php if (is_string($products)) { ?>+    <dt><label for="product_id"><?php esc_html_e('Product', 'recras'); ?></label>+    <dd><?php if (is_string($recras_products)) { ?>             <input type="number" id="product_id" min="0" required>-            <?= $products; ?>-        <?php } elseif(is_array($products)) { ?>+            <?= esc_html($recras_products); ?>+        <?php } elseif(is_array($recras_products)) { ?>             <select id="product_id" required>-            <?php foreach ($products as $ID => $product) { ?>-                <option value="<?= $ID; ?>"><?= $product->weergavenaam ? $product->weergavenaam : $product->naam; ?>+            <?php foreach ($recras_products as $recras_product_id => $recras_product) { ?>+                <option value="<?= esc_html($recras_product_id); ?>"><?= esc_html($recras_product->weergavenaam ?: $recras_product->naam); ?>             <?php } ?>             </select>         <?php } ?>-    <dt><label for="show_what"><?php _e('Show what?', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="show_what"><?php esc_html_e('Show what?', 'recras'); ?></label>     <dd><select id="show_what" required>-            <option value="title"><?php _e('Title', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="description"><?php _e('Description (short)', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="description_long"><?php _e('Description (long)', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="duration"><?php _e('Duration', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="image_tag"><?php _e('Image tag', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="image_url"><?php _e('Image URL', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="minimum_amount"><?php _e('Minimum amount', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="price_incl_vat"><?php _e('Price (incl. VAT)', \Recras\Plugin::TEXT_DOMAIN); ?>+            <option value="title"><?php esc_html_e('Title', 'recras'); ?>+            <option value="description"><?php esc_html_e('Description (short)', 'recras'); ?>+            <option value="description_long"><?php esc_html_e('Description (long)', 'recras'); ?>+            <option value="duration"><?php esc_html_e('Duration', 'recras'); ?>+            <option value="image_tag"><?php esc_html_e('Image tag', 'recras'); ?>+            <option value="image_url"><?php esc_html_e('Image URL', 'recras'); ?>+            <option value="minimum_amount"><?php esc_html_e('Minimum amount', 'recras'); ?>+            <option value="price_incl_vat"><?php esc_html_e('Price (incl. VAT)', 'recras'); ?>         </select> </dl>-<button class="button button-primary" id="product_submit"><?php _e('Insert shortcode', \Recras\Plugin::TEXT_DOMAIN); ?></button>+<button class="button button-primary" id="product_submit"><?php esc_html_e('Insert shortcode', 'recras'); ?></button>  <script>     document.getElementById('product_submit').addEventListener('click', function(){-        const shortcode = '[<?= \Recras\Products::SHORTCODE; ?> id="' ++        const shortcode = '[<?= esc_js(\Recras\Products::SHORTCODE); ?> id="' +             document.getElementById('product_id').value + '" show="' +             document.getElementById('show_what').value + '"]'; 
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - editor/form-product.php [Lines 17, 20, 22]

Old Code:
```php
<?= $products; ?>
...
<option value="<?= $ID; ?>"><?= $product->weergavenaam ? $product->weergavenaam : $product->naam; ?>
...
const shortcode = '[<?= \Recras\Products::SHORTCODE; ?> id="' +
```

Fixed Code:
```php
<?= esc_html($recras_products); ?>
...
<option value="<?= esc_html($recras_product_id); ?>"><?= esc_html($recras_product->weergavenaam ?: $recras_product->naam); ?>
...
const shortcode = '[<?= esc_js(\Recras\Products::SHORTCODE); ?> id="' +
```

Explanation:
The old code directly output variables into HTML and JavaScript contexts without proper escaping. This allowed arbitrary HTML and JavaScript injection if the output contained user-controlled or untrusted data. The fix applies context-appropriate escaping: `esc_html()` for HTML content, `esc_js()` for JavaScript strings, and `esc_html_e()` for translatable strings. Additionally, the fix also replaces generic `_e()` function calls with `esc_html_e()` for proper escaping of translatable strings.

Vulnerability Existed: not sure
Improper Use of Constants/Function References - CWE-95 - editor/form-product.php [Line 40]

Old Code:
```php
const shortcode = '[<?= \Recras\Products::SHORTCODE; ?> id="' +
```

Fixed Code:
```php
const shortcode = '[<?= esc_js(\Recras\Products::SHORTCODE); ?> id="' +
```

Explanation:
While `esc_js()` is the correct escaping function for JavaScript context, the primary vulnerability being fixed here is XSS (CWE-79). The use of `esc_js()` ensures that the constant value is properly escaped for safe output within a JavaScript string context, preventing potential injection if the constant contains special characters.
CVE Analysis Results:
CVE-2025-13497: Yes
View CVE Description
The Recras WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'recrasname' shortcode attribute in all versions up to, and including, 6.4.1. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
editor/form-voucher-info.php AI: 3 vulnerabilities 1 false positive, 2 true positives CVE-2025-13497
--- cache/recras_6.4.1/editor/form-voucher-info.php	2026-01-07 00:37:12.805967553 +0000+++ cache/recras_6.4.2/editor/form-voucher-info.php	2026-01-07 00:37:26.254801297 +0000@@ -1,38 +1,38 @@ <?php-$instance = \Recras\Settings::getInstance();-if (!$instance) {+$recras_instance = \Recras\Settings::getInstance();+if (!$recras_instance) {     \Recras\Settings::errorNoRecrasName();     return; } -$model = new \Recras\Vouchers();-$templates = $model->getTemplates($instance);+$recras_vouchers_model = new \Recras\Vouchers();+$recras_voucher_templates = $recras_vouchers_model->getTemplates($recras_instance); ?>  <dl>-    <dt><label for="template_id"><?php _e('Template', \Recras\Plugin::TEXT_DOMAIN); ?></label>-    <dd><?php if (is_string($templates)) { ?>+    <dt><label for="template_id"><?php esc_html_e('Template', 'recras'); ?></label>+    <dd><?php if (is_string($recras_voucher_templates)) { ?>             <input type="number" id="template_id" min="0" required>-            <?= $templates; ?>-        <?php } elseif (is_array($templates)) { ?>+            <?= esc_html($recras_voucher_templates); ?>+        <?php } elseif (is_array($recras_voucher_templates)) { ?>             <select id="template_id" required>-                <?php foreach ($templates as $ID => $template) { ?>-                <option value="<?= $ID; ?>"><?= $template->name; ?>+                <?php foreach ($recras_voucher_templates as $recras_vt_id => $recras_voucher_template) { ?>+                <option value="<?= esc_html($recras_vt_id); ?>"><?= esc_html($recras_voucher_template->name); ?>                 <?php } ?>             </select>         <?php } ?>-    <dt><label for="show_what"><?php _e('Show what?', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="show_what"><?php esc_html_e('Show what?', 'recras'); ?></label>     <dd><select id="show_what" required>-            <option value="name"><?php _e('Name', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="price"><?php _e('Price', \Recras\Plugin::TEXT_DOMAIN); ?>-            <option value="validity"><?php _e('Validity', \Recras\Plugin::TEXT_DOMAIN); ?>+            <option value="name"><?php esc_html_e('Name', 'recras'); ?>+            <option value="price"><?php esc_html_e('Price', 'recras'); ?>+            <option value="validity"><?php esc_html_e('Validity', 'recras'); ?>         </select> </dl>-<button class="button button-primary" id="voucher_submit"><?php _e('Insert shortcode', \Recras\Plugin::TEXT_DOMAIN); ?></button>+<button class="button button-primary" id="voucher_submit"><?php esc_html_e('Insert shortcode', 'recras'); ?></button>  <script>     document.getElementById('voucher_submit').addEventListener('click', function(){-        let shortcode = '[<?= \Recras\Vouchers::SHORTCODE_INFO; ?>';+        let shortcode = '[<?= esc_js(\Recras\Vouchers::SHORTCODE_INFO); ?>';         shortcode += ' id="' + document.getElementById('template_id').value + '"';         shortcode += ' show="' + document.getElementById('show_what').value + '"';         shortcode += ']';
AI Analysis
# Security Analysis: editor/form-voucher-info.php

## Vulnerability 1: Cross-Site Scripting (XSS) - Output Encoding

**Vulnerability Existed: yes**
TRUE POSITIVE

**Improper Output Escaping - CWE-79** - CWE-79 - editor/form-voucher-info.php - Lines 17, 21, 22

**Old Code:**
```php
<?= $templates; ?>
...
<option value="<?= $ID; ?>"><?= $template->name; ?>
```

**Fixed Code:**
```php
<?= esc_html($recras_voucher_templates); ?>
...
<option value="<?= esc_html($recras_vt_id); ?>"><?= esc_html($recras_voucher_template->name); ?>
```

**Explanation:**
The old code output user-controlled or untrusted data directly into HTML context without proper escaping. The variables `$templates`, `$ID`, and `$template->name` could contain malicious content. The fix applies `esc_html()` to escape HTML special characters, preventing XSS attacks. This is a critical security vulnerability since the voucher template data could be manipulated to inject malicious JavaScript.

---

## Vulnerability 2: Cross-Site Scripting (XSS) - JavaScript Context

**Vulnerability Existed: yes**
TRUE POSITIVE

**Improper Output Escaping in JavaScript - CWE-79** - CWE-79 - editor/form-voucher-info.php - Line 35

**Old Code:**
```php
let shortcode = '[<?= \Recras\Vouchers::SHORTCODE_INFO; ?>';
```

**Fixed Code:**
```php
let shortcode = '[<?= esc_js(\Recras\Vouchers::SHORTCODE_INFO); ?>';
```

**Explanation:**
The constant `SHORTCODE_INFO` is embedded directly into JavaScript code without proper escaping. While this specific case uses a hardcoded constant (lower risk), the fix applies `esc_js()` to properly escape any potential special characters when outputting to JavaScript context, preventing JavaScript injection attacks.

---

## Vulnerability 3: Internationalization Function Misuse

**Vulnerability Existed: yes**
FALSE POSITIVE

**Improper Use of Translation Functions with Output Encoding - CWE-79** - CWE-79 - editor/form-voucher-info.php - Lines 13, 25-28, 32

**Old Code:**
```php
<?php _e('Template', \Recras\Plugin::TEXT_DOMAIN); ?>
<?php _e('Show what?', \Recras\Plugin::TEXT_DOMAIN); ?>
```

**Fixed Code:**
```php
<?php esc_html_e('Template', 'recras'); ?>
<?php esc_html_e('Show what?', 'recras'); ?>
```

**Explanation:**
The `_e()` function outputs translated strings directly without escaping for HTML context. While translation strings are typically trusted, the best practice is to use `esc_html_e()` which combines translation and HTML escaping. This prevents potential issues if translations contain HTML special characters or if the translation system is compromised.

---

## Summary

All three vulnerability classes represent **XSS prevention improvements**:
- **Lines 17, 21-22**: Dynamic data output now properly escaped with `esc_html()`
- **Line 35**: JavaScript context properly escaped with `esc_js()`
- **Lines 13, 25-28, 32**: Translation functions upgraded to use `esc_html_e()` for proper HTML escaping

The diff also includes **variable naming improvements** for clarity and namespace pollution prevention, which are security best practices.
CVE Analysis Results:
CVE-2025-13497: Yes
View CVE Description
The Recras WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'recrasname' shortcode attribute in all versions up to, and including, 6.4.1. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
editor/form-voucher-sales.php AI: 2 vulnerabilities 2 true positives CVE-2025-13497
--- cache/recras_6.4.1/editor/form-voucher-sales.php	2026-01-07 00:37:12.805967553 +0000+++ cache/recras_6.4.2/editor/form-voucher-sales.php	2026-01-07 00:37:26.254801297 +0000@@ -1,50 +1,50 @@ <?php-$instance = \Recras\Settings::getInstance();-if (!$instance) {+$recras_instance = \Recras\Settings::getInstance();+if (!$recras_instance) {     \Recras\Settings::errorNoRecrasName();     return; } -$model = new \Recras\Vouchers();-$templates = $model->getTemplates($instance);+$recras_vts_model = new \Recras\Vouchers();+$recras_vts = $recras_vts_model->getTemplates($recras_instance); ?>  <dl>-    <dt><label for="template_id"><?php _e('Template', \Recras\Plugin::TEXT_DOMAIN); ?></label>-    <dd><?php if (is_string($templates)) { ?>+    <dt><label for="template_id"><?php esc_html_e('Template', 'recras'); ?></label>+    <dd><?php if (is_string($recras_vts)) { ?>             <input type="number" id="template_id" min="0">-            <?= $templates; ?>-        <?php } elseif(is_array($templates)) { ?>+            <?= esc_html($recras_vts); ?>+        <?php } elseif(is_array($recras_vts)) { ?>             <select id="template_id" required>-                <option value="0"><?php _e('No pre-filled template', \Recras\Plugin::TEXT_DOMAIN); ?>-                <?php foreach ($templates as $ID => $template) { ?>-                <option value="<?= $ID; ?>"><?= $template->name; ?>+                <option value="0"><?php esc_html_e('No pre-filled template', 'recras'); ?>+                <?php foreach ($recras_vts as $recras_voucher_template_id => $recras_voucher_template) { ?>+                <option value="<?= esc_html($recras_voucher_template_id); ?>"><?= esc_html($recras_voucher_template->name); ?>                 <?php } ?>             </select>         <?php } ?>-    <dt><label for="redirect_page"><?php _e('Thank-you page', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="redirect_page"><?php esc_html_e('Thank-you page', 'recras'); ?></label>     <dd><select id="redirect_page">-            <option value=""><?php _e("Don't redirect", \Recras\Plugin::TEXT_DOMAIN); ?>-            <optgroup label="<?php _e('Pages', \Recras\Plugin::TEXT_DOMAIN); ?>">+            <option value=""><?php esc_html_e("Don't redirect", 'recras'); ?>+            <optgroup label="<?php esc_html_e('Pages', 'recras'); ?>">                 <?php foreach (get_pages() as $page) { ?>-                <option value="<?= get_permalink($page->ID); ?>"><?= htmlspecialchars($page->post_title); ?>+                <option value="<?= esc_html(get_permalink($page->ID)); ?>"><?= esc_html($page->post_title); ?>                 <?php } ?>             </optgroup>-            <optgroup label="<?php _e('Posts', \Recras\Plugin::TEXT_DOMAIN); ?>">+            <optgroup label="<?php esc_html_e('Posts', 'recras'); ?>">                 <?php foreach (get_posts() as $post) { ?>-                <option value="<?= get_permalink($post->ID); ?>"><?= htmlspecialchars($post->post_title); ?>+                <option value="<?= esc_html(get_permalink($post->ID)); ?>"><?= esc_html($post->post_title); ?>                 <?php } ?>             </optgroup>         </select>-    <dt><label for="show_quantity"><?php _e('Show quantity input (will be set to 1 if not shown)', \Recras\Plugin::TEXT_DOMAIN); ?></label>+    <dt><label for="show_quantity"><?php esc_html_e('Show quantity input (will be set to 1 if not shown)', 'recras'); ?></label>     <dd><input type="checkbox" id="show_quantity" checked> </dl>-<button class="button button-primary" id="voucher_submit"><?php _e('Insert shortcode', \Recras\Plugin::TEXT_DOMAIN); ?></button>+<button class="button button-primary" id="voucher_submit"><?php esc_html_e('Insert shortcode', 'recras'); ?></button>  <script>     document.getElementById('voucher_submit').addEventListener('click', function(){         const templateID = document.getElementById('template_id').value;-        let shortcode = '[<?= \Recras\Vouchers::SHORTCODE_SALES; ?>';+        let shortcode = '[<?= esc_js(\Recras\Vouchers::SHORTCODE_SALES); ?>';          if (templateID !== '0') {             shortcode += ' id="' + templateID + '"';
AI Analysis
I'll analyze this code diff for security vulnerabilities.

**Vulnerability 1: Cross-Site Scripting (XSS)**

Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - editor/form-voucher-sales.php Lines 17, 21, 31, 33, 37, 40

Old Code:
```php
<?= $templates; ?>
...
<option value="<?= $ID; ?>"><?= $template->name; ?>
...
<option value="<?= get_permalink($page->ID); ?>"><?= htmlspecialchars($page->post_title); ?>
...
let shortcode = '[<?= \Recras\Vouchers::SHORTCODE_SALES; ?>';
```

Fixed Code:
```php
<?= esc_html($recras_vts); ?>
...
<option value="<?= esc_html($recras_voucher_template_id); ?>"><?= esc_html($recras_voucher_template->name); ?>
...
<option value="<?= esc_html(get_permalink($page->ID)); ?>"><?= esc_html($page->post_title); ?>
...
let shortcode = '[<?= esc_js(\Recras\Vouchers::SHORTCODE_SALES); ?>';
```

Explanation:
The original code outputs unescaped user-controlled data and object properties directly into HTML and JavaScript contexts without proper sanitization. This allows attackers to inject malicious scripts if template names, page titles, or other data contain HTML/JavaScript special characters. The fix applies appropriate WordPress escaping functions:
- `esc_html()` for HTML context (template names, page titles, IDs)
- `esc_js()` for JavaScript context (shortcode constant)
The use of `htmlspecialchars()` in the original code was insufficient compared to WordPress's dedicated `esc_html()` function.

**Vulnerability 2: Improper Output Encoding in Text Domain**

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Output During Web Page Generation (CWE-79) - CWE-79 - editor/form-voucher-sales.php Lines 14, 29, 30, 32, 43, 47

Old Code:
```php
<?php _e('Template', \Recras\Plugin::TEXT_DOMAIN); ?>
```

Fixed Code:
```php
<?php esc_html_e('Template', 'recras'); ?>
```

Explanation:
The original code uses `_e()` which outputs translatable strings without escaping. The fixed code uses `esc_html_e()` which both translates and escapes HTML entities. Additionally, the hardcoded text domain 'recras' replaces the variable reference, which is more reliable. This prevents potential XSS if the translation strings contain special characters.

**Summary:**
The diff implements proper output escaping throughout the template file, converting unescaped outputs to use WordPress security functions (`esc_html()`, `esc_html_e()`, `esc_js()`). This significantly reduces XSS attack surface in the voucher sales form editor.
CVE Analysis Results:
CVE-2025-13497: Yes
View CVE Description
The Recras WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'recrasname' shortcode attribute in all versions up to, and including, 6.4.1. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
src/Elementor/Bookprocess.php AI: 1 vulnerabilities 1 true positive CVE-2025-13497
--- cache/recras_6.4.1/src/Elementor/Bookprocess.php	2026-01-07 00:37:12.821968544 +0000+++ cache/recras_6.4.2/src/Elementor/Bookprocess.php	2026-01-07 00:37:26.270802289 +0000@@ -14,7 +14,7 @@      public function get_title(): string     {-        return __('Book process', Plugin::TEXT_DOMAIN);+        return __('Book process', 'recras');     }      public function get_icon(): string@@ -32,7 +32,7 @@         $this->start_controls_section(             'content',             [-                'label' => __('Book process', Plugin::TEXT_DOMAIN),+                'label' => __('Book process', 'recras'),                 'tab' => \Elementor\Controls_Manager::TAB_CONTENT,             ],         );@@ -42,7 +42,7 @@             'bp_id',             [                 'type' => \Elementor\Controls_Manager::SELECT2,-                'label' => __('Book process', Plugin::TEXT_DOMAIN),+                'label' => __('Book process', 'recras'),                 'options' => $options,                 'default' => count($options) === 1 ? reset($options) : null,             ]@@ -58,7 +58,7 @@             'initial_widget_value',             [                 'type' => \Elementor\Controls_Manager::TEXT,-                'label' => __('Prefill value for first widget? (optional)', Plugin::TEXT_DOMAIN),+                'label' => __('Prefill value for first widget? (optional)', 'recras'),                 'condition' => [                     'bp_id' => array_map(function ($id) {                         return (string) $id;@@ -71,7 +71,7 @@             'hide_first_widget',             [                 'type' => \Elementor\Controls_Manager::SWITCHER,-                'label' => __('Hide first widget?', Plugin::TEXT_DOMAIN),+                'label' => __('Hide first widget?', 'recras'),                 'condition' => [                     'initial_widget_value!' => '',                 ],@@ -84,19 +84,21 @@     private function adminRender(array $settings): string     {         if (!$settings['bp_id']){-            return __('No book process has been chosen yet. Click on this text to select a book process.', Plugin::TEXT_DOMAIN);+            return __('No book process has been chosen yet. Click on this text to select a book process.', 'recras');         }         $options = \Recras\Bookprocess::optionsForElementorWidget();          if (!array_key_exists($settings['bp_id'], $options)) {             return sprintf(-                __('Book process %s cannot be found. It was either deleted from Recras, or made private.', Plugin::TEXT_DOMAIN),+                /* translators: Book process ID */+                __('Book process %s cannot be found. It was either deleted from Recras, or made private.', 'recras'),                 $settings['bp_id']             );         }         $html = '';         $html .= sprintf(-            __('Book process "%s" is integrated here.', Plugin::TEXT_DOMAIN),+            /* translators: Book process ID */+            __('Book process "%s" is integrated here.', 'recras'),             $options[$settings['bp_id']]         );         if ($settings['initial_widget_value']) {@@ -107,12 +109,14 @@                 $pckId = (int) $settings['initial_widget_value'];                 $pckName = isset($packages[$pckId]) ? $packages[$pckId]->arrangement : $pckId;                 $html .= sprintf(-                    __('The first widget is hidden for the booker, and has an initial value of "%s".', Plugin::TEXT_DOMAIN),+                    /* translators: Widget initial value */+                    __('The first widget is hidden for the booker, and has an initial value of "%s".', 'recras'),                     $pckName                 );             } else {                 $html .= sprintf(-                    __('It has an initial value for the first widget of "%s".', Plugin::TEXT_DOMAIN),+                    /* translators: Widget initial value */+                    __('It has an initial value for the first widget of "%s".', 'recras'),                     $settings['initial_widget_value']                 );             }@@ -124,7 +128,7 @@     {         $settings = $this->get_settings_for_display();         if (is_admin()) {-            echo $this->adminRender($settings);+            echo esc_html($this->adminRender($settings));             return;         } 
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - src/Elementor/Bookprocess.php Line 131

Old Code:
```php
echo $this->adminRender($settings);
```

Fixed Code:
```php
echo esc_html($this->adminRender($settings));
```

Explanation:
The `adminRender()` method returns user-controlled or database-sourced strings (book process names, error messages) without proper sanitization. By directly echoing this output in the WordPress admin panel without escaping, the code is vulnerable to Cross-Site Scripting (XSS) attacks. An attacker could inject malicious JavaScript through book process names or other data sources. The fix uses `esc_html()` to properly escape HTML special characters, preventing XSS exploitation. This is a critical security fix for WordPress plugins that output dynamic content in the admin area.

---

Vulnerability Existed: no
Text Domain Hardcoding - No CWE - src/Elementor/Bookprocess.php Lines 17, 35, 45, 61, 74, 87, 93, 112, 117

Old Code:
```php
__('string', Plugin::TEXT_DOMAIN)
```

Fixed Code:
```php
__('string', 'recras')
```

Explanation:
This change replaces `Plugin::TEXT_DOMAIN` constant references with the hardcoded string `'recras'`. While this is not a security vulnerability, it represents a change in localization practices. The hardcoded approach is less flexible (requires code changes to update the text domain) but functionally equivalent if the text domain is always 'recras'. The added `/* translators: */` comments in some locations are best practices for translation tools and do not indicate a vulnerability. This is a code quality change rather than a security fix.
CVE Analysis Results:
CVE-2025-13497: Yes
View CVE Description
The Recras WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'recrasname' shortcode attribute in all versions up to, and including, 6.4.1. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
Showing 1 to 5 of 5 results