here's a POC
in a directory with these contents
drwxr-xr-x 2 hope hope 4096 Feb 25 07:26 dir1
-rw-r--r-- 1 hope hope 0 Feb 25 07:26 file-noext
-rw-r--r-- 1 hope hope 1941 Feb 25 07:47 listfiles.js
-rw-r--r-- 1 hope hope 112 Feb 25 07:50 note.txt
running this node app listfiles.js
"use strict";
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
// for custom portnum specify in command line e.g. node listfiles.js 5678
const port = process.argv[2] || 8080;
http.createServer(function (req, res) {
console.log(`${req.method} ${req.url}`);
// parse URL
const parsedUrl = url.parse(req.url);
// extract URL path
// Avoid https://en.wikipedia.org/wiki/Directory_traversal_attack
// e.g curl --path-as-is http://localhost:9000/../fileInDanger.txt
// by limiting the path to current directory only
const sanitizePath = path.normalize(parsedUrl.pathname).replace(/^(\.\.[\/\\])+/, '');
let pathname = path.join(__dirname, sanitizePath);
fs.exists(pathname, function (exist) {
if(!exist) {
// if the path is not found, return 404
res.statusCode = 404;
res.end(`File ${pathname} not found`);
return;
}
fs.readdir(pathname, (err, items) => {
var i = 0;
// regex from https://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript
var re = /(?:\.([^.]+))?$/; var desc, ext, content = "";
for (i = 0; i < items.length; i++) {
ext = re.exec(items[i].toString())[1];
if (typeof ext == 'undefined') { ext = "none" };
switch(ext) {
case "js":
desc = "JavaScript"; break;
case "txt":
desc = "text file"; break;
case "none":
desc = "none or undefined"; break;
default:
console.log("fell through");
}
content += ( "Item " + i.toString() + ": " + items[i].toString() + ", extension = " + ext + ", desc = " + desc + "<br>" );
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
});
});
}).listen(parseInt(port));
console.log(`Server listening on port ${port}`);
produces this output in a web browser
Item 0: dir1, extension = none, desc = none or undefined
Item 1: file-noext, extension = none, desc = none or undefined
Item 2: listfiles.js, extension = js, desc = JavaScript
Item 3: note.txt, extension = txt, desc = text file