Search code examples
node.jsexpresscode-injection

Nodejs: Is it secure to retrieve a file by express param?


Is the code below secure or do I need to protect the param against injection? Is it possible to access a file outside of /content/includes?

app.get('/api/includes/:slug', (req, res) => {
  const file = __dirname + '/content/includes/' + req.params.slug + '.html';
  if (fs.existsSync(file)) res.sendFile(file);
  else res.sendStatus(404);
});

Solution

  • It is definitely possible to access files outside of /content/includes simply by adding ../ to the slug path. You can use path.normalize to traverse the path and remove all ../, but this will still give you a path that can be outside of your intended directory, so you can use path.join to ensure your intended directory is at the start of the intended path.

    // remove all `../` from the start of the slug.
    const relativeSlug = req.params.slug.replace(/^(\.\.\/)+/, '');
    // normalize the path
    const normalizedSlug = path.normalize(relativeSlug);
    const file = path.join(__dirname + '/content/includes/', normalizedSlug);
    

    This will help ensure that the slug path is under your intended directory.

    The process running your server should also have limited access to the file system and not be able to read much from other directories to begin with.

    See more about this here: https://www.owasp.org/index.php/Path_Traversal