← back to Labj Cre Banks
chore: lint (URL-decode guard, tighten path containment, drop pw from log) (session close)
8cba39256c35043137a24e4ded9cc7389ea36dc3 · 2026-08-10 21:16:25 -0700 · steve
Files touched
Diff
commit 8cba39256c35043137a24e4ded9cc7389ea36dc3
Author: steve <steve@designerwallcoverings.com>
Date: Mon Aug 10 21:16:25 2026 -0700
chore: lint (URL-decode guard, tighten path containment, drop pw from log) (session close)
---
server.js | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/server.js b/server.js
index 1950b8b..91c74a9 100644
--- a/server.js
+++ b/server.js
@@ -39,10 +39,16 @@ const server = http.createServer((req, res) => {
res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="labj-viewer"' });
return res.end('Auth required');
}
- let rel = decodeURIComponent(new URL(req.url, 'http://x').pathname);
+ let rel;
+ try {
+ rel = decodeURIComponent(new URL(req.url, 'http://x').pathname);
+ } catch (_) {
+ res.writeHead(400);
+ return res.end('Bad request');
+ }
if (rel === '/' || rel === '') rel = '/index.html';
const full = path.normalize(path.join(ROOT, rel));
- if (!full.startsWith(ROOT)) { res.writeHead(403); return res.end('Forbidden'); }
+ if (!full.startsWith(ROOT + path.sep) && full !== ROOT) { res.writeHead(403); return res.end('Forbidden'); }
fs.readFile(full, (err, buf) => {
if (err) { res.writeHead(404); return res.end('Not found'); }
res.writeHead(200, { 'Content-Type': TYPES[path.extname(full)] || 'application/octet-stream', 'Cache-Control': 'no-store' });
@@ -51,5 +57,5 @@ const server = http.createServer((req, res) => {
});
server.listen(PORT, HOST, () => {
- console.log(`LABJ viewer live: http://${HOST}:${server.address().port} (login ${USER} / ${PASS})`);
+ console.log(`LABJ viewer live: http://${HOST}:${server.address().port} (login ${USER})`);
});
← efaae19 Contrarian verify pass on 83 new LABJ firms: 0 refuted, 6 co
·
back to Labj Cre Banks
·
Add CRE prospect-DB expansion-resources research (Muse + Cod ec301aa →