← back to Stars of Design
Static-bak guard returns plain text, not EJS template
8fc1daa177f2442398081cd08665b480bd28cb3c · 2026-05-19 15:20:35 -0700 · Steve Abrams
The previous version of this guard tried to render public/404.ejs, which
in turn includes partials/head.ejs that depends on res.locals.meta_desc.
That local is wired inside the publicRoutes router-level middleware —
later in the stack than this guard runs — so a request for a .bak/.pre-
path threw "meta_desc is not defined" and surfaced a 500 instead of a
404, defeating the point.
Plain-text response sidesteps the template chain entirely. Verified with
a smoke run: /test.html.bak / /test.bak / /something.pre-refactor.html
all return 404, regular routes still 200.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 8fc1daa177f2442398081cd08665b480bd28cb3c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 15:20:35 2026 -0700
Static-bak guard returns plain text, not EJS template
The previous version of this guard tried to render public/404.ejs, which
in turn includes partials/head.ejs that depends on res.locals.meta_desc.
That local is wired inside the publicRoutes router-level middleware —
later in the stack than this guard runs — so a request for a .bak/.pre-
path threw "meta_desc is not defined" and surfaced a 500 instead of a
404, defeating the point.
Plain-text response sidesteps the template chain entirely. Verified with
a smoke run: /test.html.bak / /test.bak / /something.pre-refactor.html
all return 404, regular routes still 200.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/server.js b/server.js
index bf1babc..ecc3d51 100644
--- a/server.js
+++ b/server.js
@@ -69,11 +69,14 @@ app.use(cookieParser());
// Static-bak guard — refuse to serve any URL path that looks like a snapshot
// or rollback artifact (foo.html.bak, foo.pre-refactor.js, etc.) even if
// someone accidentally leaves one in public/. Pair with the .gitignore rules
-// for *.bak / *.bak.* / *.pre-*. Returns 404 (not 403) so an attacker can't
-// confirm a snapshot exists by path-probing.
+// for *.bak / *.bak.* / *.pre-*. Returns plain-text 404 (not 403) so an
+// attacker can't confirm a snapshot exists by path-probing, and bypasses
+// the EJS 404 template since the meta-locals it expects aren't wired yet
+// at this point in the middleware stack.
app.use((req, res, next) => {
if (/\.bak(?:\.|$)|\.pre-/.test(req.path)) {
- return res.status(404).render('public/404', { title: 'Not found — Stars of Design' });
+ res.setHeader('Cache-Control', 'no-store');
+ return res.status(404).type('text/plain').send('Not found');
}
next();
});
← e2ee6aa Guard against serving .bak / .pre- snapshot artifacts from p
·
back to Stars of Design
·
Add per-site favicon (kills /favicon.ico 404) 06be86b →