Atomic Edge analysis of CVE-2026-0831:
The vulnerability is an unauthenticated arbitrary JSON file write in the Templately WordPress plugin versions <=3.4.8. The flaw resides in the AI content generation functionality, specifically within the `save_template_to_file()` method, allowing attackers to write `.ai.json` files to arbitrary locations within the WordPress uploads directory. With a CVSS score of 5.3, this represents a medium-severity integrity violation.
The root cause is inadequate input validation in the `save_template_to_file()` function within `/templately/includes/Core/Importer/Utils/AIUtils.php`. User-controlled parameters `session_id`, `content_id`, and `ai_page_ids` are directly incorporated into file path construction without sanitization. The function builds paths using concatenation: `$page_dir = $tmp_dir . $found_key . DIRECTORY_SEPARATOR;` and `$file_path = $page_dir . $content_id . '.ai.json';`. The `$found_key` value originates from the `$ai_page_ids` array, which contains user-supplied path components. No validation prevents directory traversal sequences or ensures paths remain within intended boundaries.
Exploitation occurs via the `/wp-json/templately/v1/ai-content/ai-update` REST API endpoint. Attackers send POST requests containing malicious `session_id`, `content_id`, and `ai_page_ids` parameters. The `ai_page_ids` array can include path traversal sequences like `../../../` to escape the intended `templately/tmp/` subdirectory. For example, setting `ai_page_ids` to `["../../../malicious"]` and `content_id` to `payload` results in writing `payload.ai.json` to `wp-content/uploads/malicious/`. No authentication or API key validation is required in vulnerable versions.
The patch introduces multiple security layers. First, it adds API key validation in `AIContent::permission_check()` requiring the `X-Templately-Apikey` header to match a stored user key. Second, it implements `AIUtils::sanitize_path_component()` which rejects values containing `..`, `/`, or “. Third, `AIUtils::validate_file_path()` ensures the final path resides within the WordPress uploads directory using `realpath()` comparison. Fourth, the `save_template_to_file()` function now sanitizes `session_id`, `content_id`, and splits `found_key` into components for individual sanitization. These changes collectively prevent path traversal and restrict file writes to the intended directory structure.
Successful exploitation allows attackers to write arbitrary JSON files anywhere within the WordPress uploads directory. While limited to `.ai.json` extension, this can facilitate various attacks including storing malicious configuration, poisoning cache files, or preparing for other vulnerabilities. The write capability could be combined with other plugin or theme features that execute or include files from the uploads directory, potentially leading to remote code execution. The attack requires no authentication, making it accessible to any external actor.
