REPORT / 01
Analysis Report · Folder Analysis cache/emailkit_1.6.1 → cache/emailkit_1.6.2 — CVE-2025-14059
Shared security patch analysis results
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-14059
NVD
AI-Generated Analysis
05 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
includes/Admin/Api/CheckForm.php
AI: No vulnerabilities
CVE-2025-14059
--- cache/emailkit_1.6.1/includes/Admin/Api/CheckForm.php 2026-01-08 00:33:05.834573228 +0000+++ cache/emailkit_1.6.2/includes/Admin/Api/CheckForm.php 2026-01-08 00:37:34.126911640 +0000@@ -161,23 +161,34 @@ $html = ''; if (!empty($request->get_param('emailkit-editor-template')) && trim($request->get_param('emailkit-editor-template')) !== '') { $template_path = $request->get_param('emailkit-editor-template'); - $template = file_exists($template_path) ? file_get_contents($template_path) : ''; - $html_path = str_replace("content.json", "content.html", $template_path); - $html = file_exists($html_path) ? file_get_contents($html_path) : ''; + $allowed_base_path = wp_upload_dir()['basedir'] . '/emailkit/templates/'; + $real_path = realpath($template_path); + if ($real_path === false || strpos($real_path, realpath($allowed_base_path)) !== 0) { + return new WP_REST_Response(['success' => false, 'message' => __('Invalid template path', 'emailkit')], 400); + } + + $template = file_exists($real_path) ? file_get_contents($real_path) : ''; + $html_path = str_replace("content.json", "content.html", $real_path); + + // Validate HTML path as well + $real_html_path = realpath($html_path); + if ($real_html_path !== false && strpos($real_html_path, realpath($allowed_base_path)) === 0) { + $html = file_exists($real_html_path) ? file_get_contents($real_html_path) : ''; + } } // Create new emailkit post $post_id = wp_insert_post([ - 'post_title' => $template_title, + 'post_title' => sanitize_text_field($template_title), 'post_type' => 'emailkit', 'post_status' => 'publish', 'meta_input' => [ - 'emailkit_template_type' => $template_type, - 'emailkit_form_id' => $form_id, + 'emailkit_template_type' => sanitize_text_field($template_type), + 'emailkit_form_id' => absint($form_id), 'emailkit_template_status' => 'active', - 'emailkit_template_content_html' => $html, + 'emailkit_template_content_html' => wp_kses_post($html), 'emailkit_template_content_object' => $template, - 'emailkit_email_type' => $request->get_param('emailkit_email_type'), + 'emailkit_email_type' => sanitize_text_field($request->get_param('emailkit_email_type')), ] ]);
AI Analysis
# Security Analysis: Code Diff for CheckForm.php
## Vulnerability 1: Path Traversal / Directory Traversal
**Vulnerability Existed:** yes
**CWE-22 - Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') - includes/Admin/Api/CheckForm.php Lines 163-165**
**Old Code:**
```php
$template_path = $request->get_param('emailkit-editor-template');
$template = file_exists($template_path) ? file_get_contents($template_path) : '';
$html_path = str_replace("content.json", "content.html", $template_path);
$html = file_exists($html_path) ? file_get_contents($html_path) : '';
```
**Fixed Code:**
```php
$template_path = $request->get_param('emailkit-editor-template');
$allowed_base_path = wp_upload_dir()['basedir'] . '/emailkit/templates/';
$real_path = realpath($template_path);
if ($real_path === false || strpos($real_path, realpath($allowed_base_path)) !== 0) {
return new WP_REST_Response(['success' => false, 'message' => __('Invalid template path', 'emailkit')], 400);
}
$template = file_exists($real_path) ? file_get_contents($real_path) : '';
$html_path = str_replace("content.json", "content.html", $real_path);
// Validate HTML path as well
$real_html_path = realpath($html_path);
if ($real_html_path !== false && strpos($real_html_path, realpath($allowed_base_path)) === 0) {
$html = file_exists($real_html_path) ? file_get_contents($real_html_path) : '';
}
```
**Explanation:**
The original code directly used user-supplied input (`$template_path` from `$request->get_param()`) to read files without validating that the path was within an allowed directory. An attacker could use path traversal sequences (e.g., `../../etc/passwd`) to read arbitrary files from the server. The fix implements proper path validation by:
1. Using `realpath()` to resolve the absolute path and detect traversal attempts
2. Comparing the resolved path against an allowed base directory (`wp_upload_dir()['basedir'] . '/emailkit/templates/'`)
3. Rejecting any paths outside the allowed directory
4. Applying the same validation to both the template and HTML file paths
---
## Vulnerability 2: Stored Cross-Site Scripting (XSS)
**Vulnerability Existed:** yes
**CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - includes/Admin/Api/CheckForm.php Lines 172-180**
**Old Code:**
```php
'meta_input' => [
'emailkit_template_type' => $template_type,
'emailkit_form_id' => $form_id,
'emailkit_template_status' => 'active',
'emailkit_template_content_html' => $html,
'emailkit_template_content_object' => $template,
'emailkit_email_type' => $request->get_param('emailkit_email_type'),
]
```
**Fixed Code:**
```php
'meta_input' => [
'emailkit_template_type' => sanitize_text_field($template_type),
'emailkit_form_id' => absint($form_id),
'emailkit_template_status' => 'active',
'emailkit_template_content_html' => wp_kses_post($html),
'emailkit_template_content_object' => $template,
'emailkit_email_type' => sanitize_text_field($request->get_param('emailkit_email_type')),
]
```
**Explanation:**
The original code stored unsanitized user input directly into post metadata without any sanitization. This allowed attackers to inject malicious scripts that would be stored in the database and executed when the data was later retrieved and displayed. Additionally, `$post_title` was not sanitized. The fix applies appropriate sanitization functions:
- `sanitize_text_field()` for text inputs (`template_type`, `template_title`, `emailkit_email_type`) - removes HTML/script tags
- `absint()` for numeric input (`form_id`) - ensures only integers
- `wp_kses_post()` for HTML content (`$html`) - allows safe HTML while removing dangerous elements
---
## Vulnerability 3: Improper Input Validation
**Vulnerability Existed:** yes
**CWE-20 - Improper Input Validation - includes/Admin/Api/CheckForm.php Lines 164, 184**
**Old Code:**
```php
$post_title = $template_title, // No type checking or validation
'post_title' => $template_title,
'emailkit_form_id' => $form_id, // No integer validation
```
**Fixed Code:**
```php
'post_title' => sanitize_text_field($template_title),
'emailkit_form_id' => absint($form_id),
```
**Explanation:**
The original code accepted and stored user input without validating expected data types or formats. The `$form_id` parameter should be numeric but was stored as-is, potentially allowing non-integer values. The `$template_title` should be text but had no validation. The fix validates input types: `absint()` coerces to integer (preventing SQL injection or type confusion), and `sanitize_text_field()` ensures text input is properly formatted and stripped of HTML.
CVE Analysis Results:
CVE-2025-14059: Yes
View CVE Description
The EmailKit plugin for WordPress is vulnerable to Arbitrary File Read via Path Traversal in all versions up to, and including, 1.6.1. This is due to missing path validation in the create_template REST API endpoint where user-controlled input from the emailkit-editor-template parameter is passed directly to file_get_contents() without sanitization. This makes it possible for authenticated attackers with Author-level permissions or higher to read arbitrary files on the server, including sensitive configuration files like /etc/passwd and wp-config.php, via the REST API. The file contents are stored in post meta and can be exfiltrated through MetForm's email confirmation feature.
Showing 1 to 1 of 1 results