This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Node

1 - Security

Notes from Node.js Security: Pentesting and Exploitation course on StackSkills.

Vulnerabilities

Full code examples on github

Global Namespace Pollution

Be very careful with global variables.

HTTP Parameter Polution (express)

If you pass the same url parameter multiple times in request they will all be read as comma seperated values.
For example consider this code:

app.get('/hpp', (req, res) => {
    res.send(req.query.id);
});

And we sent this request url/hpp?id=123&id=456 the response would be 123,456, be aware of the implications of this.

eval() is Evil

Be careful with eval.
For example consider this code:

app.get('/eval', (req, res) => {
    let resp=eval("("+req,query.name+")");
    res.send(resp);
});

We could pass something like process.exit(1) using the name parameter and this would kill the web server. We could leverage an exploit like this to allow a remote connection to the web server.

Remote OS Command Execution

Be careful with child_process.
For example consider this code:

var exe = require('child_process');  
app.get('/os', (req, res) => {
    exe.exec('ping -c 2 ' + req.query.ping, (err, data) => {
        res.send(data);
    });
});

We could pass something like 127.0.0.1; whoami, and get the whoami response back from the host. Obviously we could do much more malicious things than determine the user.

Untrusted User Input

For example consider this code:

app.get('/hello', (req, res) => {
    res.send('hello ' + req.query.name);
});

We could pass someting like <img src=x onerror=alert('haha')> and that html would be rendered allowing us to do things like XSS.

Regex DoS

Ensure you are using safe regex, if you use unsafe regex, it will be easy for attackers to induce load on your server.

Information Disclosure

Ideally we want to hide things like our techstack/frameworks from the users (and attackers), this info can come up in headers, error pages, and cookies.
Helmet can be used to help make this easier.

To disable the x-powered-by header you can either do app.disable('x-powered-b') or if you are using helmet, app.use(helmet.hidePoweredBy())

Secure Code Tips

Use strict mode.
Use helmet (if you are using express) or obfuscate the same info yourself.

Things to check in a code review

  • File & DB Operations
  • Insecure Crypto
  • Insecure SSL
  • Insecure Server to Server SSL
  • Logical Flaws
  • Untrusted user input

2 - Snippets

Encoding/decoding

To base64 encode a string: new Buffer(str).toString('base64')
To decode a base64 string: new Buffer(str, 'base64').toString('ascii')

3 - Using Docker with Node

Dockerfile

This is an example of a Dockerfile for a node application.

FROM alpine:3.4  

RUN apk add --no-cache --update nodejs &&\
    mkdir /app

ENTRYPOINT /app

ADD . /app

EXPOSE 3000 4300

CMD npm start

Here is a line by line breakdown:

  • We start with alpine, this will help us keep only the things we absolutely need in the image
  • In the first line of the run statement we install nodejs (this includes npm)
  • In the second line we make a directory to add our app to
  • We set our working directory to the newly created app directory
  • Expose the ports your app listens only
  • Use npm start to start the app on container startup

Building

Coming soon

Running

Coming soon

Managing App Configuration

Coming soon