[object Object]

← back to Jill Website

security: 404-guard snapshot/backup paths in both server entrypoints

5f718fed5d088199018ecee7462606268b417f52 · 2026-05-19 21:16:33 -0700 · SteveStudio2

Adds a defense-in-depth Express middleware (runs BEFORE express.static)
that returns 404 for any request path ending in .bak / .bak.* / .pre-* /
.orig / .rej / .swp / ~. Applied to both:

- server.js (standalone fallback)
- src/server.ts (PM2 production entrypoint via dist/server.js)

Pairs with the .gitignore broadening in 6087759 — even if a snapshot
file slips into public/ via a sloppy edit, it never serves over HTTP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 5f718fed5d088199018ecee7462606268b417f52
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Tue May 19 21:16:33 2026 -0700

    security: 404-guard snapshot/backup paths in both server entrypoints
    
    Adds a defense-in-depth Express middleware (runs BEFORE express.static)
    that returns 404 for any request path ending in .bak / .bak.* / .pre-* /
    .orig / .rej / .swp / ~. Applied to both:
    
    - server.js (standalone fallback)
    - src/server.ts (PM2 production entrypoint via dist/server.js)
    
    Pairs with the .gitignore broadening in 6087759 — even if a snapshot
    file slips into public/ via a sloppy edit, it never serves over HTTP.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 server.js     | 11 +++++++++++
 src/server.ts | 11 +++++++++++
 2 files changed, 22 insertions(+)

diff --git a/server.js b/server.js
index 6923d35..e250c2e 100755
--- a/server.js
+++ b/server.js
@@ -765,6 +765,17 @@ app.use(helmet({ contentSecurityPolicy: false }));
 // Middleware
 app.use(express.json());
 app.use(express.urlencoded({ extended: true }));
+
+// SECURITY: 404-guard for snapshot/backup paths. Even if a .bak / .pre-* /
+// .orig / .rej / .swp / ~ file ever slips into public/ via a sloppy edit,
+// it must NEVER be servable over HTTP. Block before static handler runs.
+app.use((req, res, next) => {
+  if (/(\.bak(\.[^/]+)?|\.pre-[^/]+|\.orig|\.rej|\.swp|~)$/i.test(req.path)) {
+    return res.status(404).send('Not Found');
+  }
+  next();
+});
+
 app.use(express.static('public'));
 // SECURITY: removed `app.use(express.static('.'))` — was exposing .env, server.js, node_modules, etc.
 // over HTTP. Anything in project root that needs to be public must move to public/ instead.
diff --git a/src/server.ts b/src/server.ts
index 3dfcec3..8ea94f2 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -83,6 +83,17 @@ app.use(siteAuth);
 app.use(express.json());
 app.use(express.urlencoded({ extended: true }));
 
+// SECURITY: 404-guard for snapshot/backup paths. Even if a .bak / .pre-* /
+// .orig / .rej / .swp / ~ file ever slips into public/ via a sloppy edit,
+// it must NEVER be servable over HTTP. Block before static handler runs.
+app.use((req: Request, res: Response, next: NextFunction) => {
+  if (/(\.bak(\.[^/]+)?|\.pre-[^/]+|\.orig|\.rej|\.swp|~)$/i.test(req.path)) {
+    res.status(404).send('Not Found');
+    return;
+  }
+  next();
+});
+
 // Static files
 app.use(express.static(path.join(__dirname, '../public')));
 

← 6087759 .gitignore: broaden to exclude snapshot/backup/swap files  ·  back to Jill Website  ·  security: upgrade rel=noopener to rel=noopener noreferrer on e405522 →