← back to Shopify Oauth Catcher
feat(server): 404-guard snapshot file paths
26ea6583e0bdeaa6ae7d0b02a5308fd1e3e1adde · 2026-05-19 21:23:55 -0700 · Steve Abrams
Adds Express middleware that rejects any request path matching common
editor/snapshot extensions (.bak, .bak.<x>, .pre-*, .orig, .rej, .swp,
trailing ~) with a 404 before reaching any route or static handler.
Defense-in-depth — if a future static dir is added or a stray snapshot
file is left in the deploy tree (or exposed via a misconfigured proxy),
it cannot leak source / config / token-shaped content over HTTP.
OAuth flow unchanged: /install and /callback handlers untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 26ea6583e0bdeaa6ae7d0b02a5308fd1e3e1adde
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 21:23:55 2026 -0700
feat(server): 404-guard snapshot file paths
Adds Express middleware that rejects any request path matching common
editor/snapshot extensions (.bak, .bak.<x>, .pre-*, .orig, .rej, .swp,
trailing ~) with a 404 before reaching any route or static handler.
Defense-in-depth — if a future static dir is added or a stray snapshot
file is left in the deploy tree (or exposed via a misconfigured proxy),
it cannot leak source / config / token-shaped content over HTTP.
OAuth flow unchanged: /install and /callback handlers untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/server.js b/server.js
index bd85e3b..27b28fa 100644
--- a/server.js
+++ b/server.js
@@ -34,6 +34,15 @@ if (!CLIENT_ID || !CLIENT_SECRET) {
}
const app = express();
+
+// Defense-in-depth: 404 any request for editor/snapshot detritus before it
+// can reach a static handler or be served by a misconfigured proxy.
+const SNAPSHOT_RE = /\.(bak|orig|rej|swp)$|\.bak\.|\.pre-|~$/i;
+app.use((req, res, next) => {
+ if (SNAPSHOT_RE.test(req.path)) return res.status(404).send('not found');
+ next();
+});
+
const states = new Map(); // state → {shop, ts}
app.get('/install', (req, res) => {
← 8d63f76 chore(gitignore): broaden to ignore editor/snapshot detritus
·
back to Shopify Oauth Catcher
·
(newest)