Arbitrary Code Execution Affecting ejs package, versions <2.5.3
Threat Intelligence
Do your applications use this vulnerable package?
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applications- Snyk ID npm:ejs:20161128
- published 28 Nov 2016
- disclosed 27 Nov 2016
- credit Snyk Security Research Team
Introduced: 27 Nov 2016
CVE-2017-1000228 Open this link in a new tabHow to fix?
The vulnerability can be resolved by either using the GitHub integration to generate a pull-request from your dashboard or by running snyk wizard
from the command-line interface.
Otherwise, Upgrade ejs
to version 2.5.3
or higher.
Overview
ejs
is a popular JavaScript templating engine.
Affected versions of the package are vulnerable to Remote Code Execution by letting the attacker under certain conditions control the source folder from which the engine renders include files.
You can read more about this vulnerability on the Snyk blog.
There's also a Cross-site Scripting & Denial of Service vulnerabilities caused by the same behaviour.
Details
ejs
provides a few different options for you to render a template, two being very similar: ejs.render()
and ejs.renderFile()
. The only difference being that render
expects a string to be used for the template and renderFile
expects a path to a template file.
Both functions can be invoked in two ways. The first is calling them with template
, data
, and options
:
ejs.render(str, data, options);
ejs.renderFile(filename, data, options, callback)
The second way would be by calling only the template
and data
, while ejs
lets the options
be passed as part of the data
:
ejs.render(str, dataAndOptions);
ejs.renderFile(filename, dataAndOptions, callback)
If used with a variable list supplied by the user (e.g. by reading it from the URI with qs
or equivalent), an attacker can control ejs
options. This includes the root
option, which allows changing the project root for includes with an absolute path.
ejs.renderFile('my-template', {root:'/bad/root/'}, callback);
By passing along the root directive in the line above, any includes would now be pulled from /bad/root
instead of the path intended. This allows the attacker to take control of the root directory for included scripts and divert it to a library under his control, thus leading to remote code execution.
The fix introduced in version 2.5.3
blacklisted root
options from options passed via the data
object.
Disclosure Timeline
- November 27th, 2016 - Reported the issue to package owner.
- November 27th, 2016 - Issue acknowledged by package owner.
- November 28th, 2016 - Issue fixed and version
2.5.3
released.