The vulnerability is Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
javascript
// vulnerable code

const fs = require('fs');
const http = require('http');
const url = require('url');

http.createServer((req, res) => {
  const query = url.parse(req.url, true).query;
  const filename = '.' + query.file;

  fs.readFile(filename, (err, data) => {
    if (err) {
      res.writeHead(404);
      res.end('File not found');
      return;
    }
    res.writeHead(200);
    res.end(data);
  });
}).listen(8080);
javascript // vulnerable code const fs = require('fs'); const http = require('http'); const url = require('url'); http.createServer((req, res) => { const query = url.parse(req.url, true).query; const filename = '.' + query.file; fs.readFile(filename, (err, data) => { if (err) { res.writeHead(404); res.end('File not found'); return; } res.writeHead(200); res.end(data); }); }).listen(8080); To fix the vulnerability, we use the `path` module to safely construct our file path. By using `path.join(__dirname, '.', query.file)`, we ensure that the resulting path is always within the application's directory. Additionally, we check if the processed filename starts with the safe base path, i.e., `path.join(__dirname, '.')`. If it doesn't, we return a 403 Access Denied response. This ensures that even if an attacker tries to access outside of the allowed directory using path traversal techniques, their attempts will be blocked.
javascript
// solution how to fix the vulnerable code

const fs = require('fs');
const http = require('http');
const url = require('url');
const path = require('path');

http.createServer((req, res) => {
  const query = url.parse(req.url, true).query;
  const filename = path.join(__dirname, '.', query.file);

  if (!filename.startsWith(path.join(__dirname, '.'))) {
    res.writeHead(403);
    res.end('Access denied');
    return;
  }

  fs.readFile(filename, (err, data) => {
    if (err) {
      res.writeHead(404);
      res.end('File not found');
      return;
    }
    res.writeHead(200);
    res.end(data);
  });
}).listen(8080);