CVE-2023-29827 Overview
CVE-2023-29827 is a server-side template injection (SSTI) vulnerability affecting EJS (Embedded JavaScript templates) version 3.1.9, a popular templating engine used in Node.js applications. The vulnerability allows attackers to inject malicious templates through the closeDelimiter configuration parameter when the EJS file content is controllable by the attacker.
This vulnerability is disputed by the vendor, who states that the render function is not intended to be used with untrusted input. However, the potential for exploitation exists in applications that inadvertently pass user-controlled data to EJS configuration options.
Critical Impact
Server-side template injection can lead to remote code execution, allowing attackers to execute arbitrary commands on the server, access sensitive data, and potentially compromise the entire application infrastructure.
Affected Products
- EJS (Embedded JavaScript templates) v3.1.9 for Node.js
- Applications using EJS with user-controllable configuration parameters
- Node.js web applications implementing EJS templating with untrusted input
Discovery Timeline
- 2023-05-04 - CVE-2023-29827 published to NVD
- 2025-12-03 - Last updated in NVD database
Technical Details for CVE-2023-29827
Vulnerability Analysis
This server-side template injection vulnerability exists within the EJS templating engine's configuration handling. The core issue stems from the way EJS processes the closeDelimiter parameter, which defines the ending delimiter for template tags. When an application allows user-controlled input to influence EJS configuration settings, an attacker can manipulate this parameter to inject and execute arbitrary JavaScript code on the server.
Server-side template injection vulnerabilities are particularly dangerous in Node.js environments because successful exploitation can lead to full remote code execution. Unlike client-side issues, SSTI attacks execute directly on the server, giving attackers access to server resources, environment variables, file systems, and potentially connected databases.
The vendor has disputed this CVE, indicating that passing untrusted input to the render function or configuration options is explicitly outside the intended use case as documented in their security policy.
Root Cause
The root cause is improper input validation (CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component) in the template rendering configuration. The EJS engine does not adequately sanitize or restrict the values that can be passed to configuration parameters like closeDelimiter. When these parameters accept arbitrary user input without proper validation, they become vectors for template injection attacks.
The vulnerability specifically targets the delimiter configuration mechanism, which is designed to allow customization of template syntax but lacks sufficient safeguards against malicious manipulation when exposed to untrusted input.
Attack Vector
The attack is network-based and requires no privileges or user interaction to exploit. An attacker can exploit this vulnerability by:
- Identifying an application endpoint that passes user-controllable data to EJS configuration options
- Crafting a malicious payload that manipulates the closeDelimiter parameter
- Injecting JavaScript code that will be executed during template rendering
- Achieving remote code execution on the target server
The vulnerability is exploited by manipulating the closeDelimiter configuration parameter to inject malicious JavaScript code during the template rendering process. When EJS processes a template with an attacker-controlled delimiter configuration, the injected code is executed in the context of the Node.js server. Technical details and proof-of-concept information can be found in the GitHub Issue #720 submitted to the EJS repository. The vendor's security documentation outlining intended usage boundaries is available in their SECURITY.md.
Detection Methods for CVE-2023-29827
Indicators of Compromise
- Unusual template rendering errors or exceptions in application logs
- Suspicious values in HTTP request parameters targeting EJS configuration options (e.g., closeDelimiter, openDelimiter, delimiter)
- Unexpected process spawning or command execution from Node.js application processes
- Anomalous outbound network connections from the web application server
Detection Strategies
- Implement application-level logging to capture all values passed to EJS render functions and configuration options
- Deploy Web Application Firewall (WAF) rules to detect template injection patterns in request parameters
- Use static application security testing (SAST) tools to identify code paths where user input flows into EJS configuration
- Monitor for suspicious JavaScript execution patterns or unusual template rendering behavior
Monitoring Recommendations
- Enable verbose logging for template rendering operations and monitor for unusual delimiter configurations
- Implement anomaly detection for Node.js process behavior, including unexpected child process creation
- Set up alerts for error spikes in EJS template processing that may indicate injection attempts
- Review application dependencies regularly using npm audit or similar tools to identify vulnerable EJS versions
How to Mitigate CVE-2023-29827
Immediate Actions Required
- Audit all code paths where user input may flow into EJS configuration options or render functions
- Implement strict input validation and sanitization for any data that influences template rendering
- Consider using hardcoded delimiter configurations rather than allowing dynamic customization
- Review the EJS Security Documentation to ensure proper usage patterns
Patch Information
The vendor has disputed this vulnerability, stating that the render function is not intended to be used with untrusted input. As such, there is no specific patch for this issue. The recommended mitigation is to follow secure coding practices by never passing untrusted user input to EJS configuration options or render functions.
Review the GitHub Issue #720 for the full discussion and vendor response regarding this vulnerability.
Workarounds
- Never pass user-controlled input to EJS configuration options including closeDelimiter, openDelimiter, or other rendering parameters
- Implement an allowlist approach for any configurable template options, rejecting unexpected values
- Use template sandboxing or security wrappers to limit the capabilities available within templates
- Consider migrating to alternative templating engines with stronger security boundaries if dynamic delimiter configuration is required
# Configuration example - Hardcode EJS delimiters to prevent injection
# In your Node.js application, use fixed configuration values:
# Example secure EJS configuration in your application
# const ejs = require('ejs');
#
# // Use hardcoded, safe delimiter values - never from user input
# const safeOptions = {
# delimiter: '%',
# openDelimiter: '<',
# closeDelimiter: '>',
# // Never allow these to be set from request parameters
# };
#
# ejs.render(template, data, safeOptions);
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


