← back to Sister Parish Onboarding
add noopener noreferrer to external _blank links + .bak/.pre snapshot 404-guard
92e3f856101e2447aa357066ed6443386e44fbe0 · 2026-05-19 15:20:15 -0700 · Steve
Code-health fleet sweep pass: closes the reverse-tabnabbing vector on
the two external target=_blank anchors (vendor source PDP, PD-corpus
source link in the inspirations modal). Also adds an Express middleware
404-guard so .bak / .bak.* / .pre-* / .pre.* snapshot paths can never
be served via static even if one slips into the tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 92e3f856101e2447aa357066ed6443386e44fbe0
Author: Steve <steve@designerwallcoverings.com>
Date: Tue May 19 15:20:15 2026 -0700
add noopener noreferrer to external _blank links + .bak/.pre snapshot 404-guard
Code-health fleet sweep pass: closes the reverse-tabnabbing vector on
the two external target=_blank anchors (vendor source PDP, PD-corpus
source link in the inspirations modal). Also adds an Express middleware
404-guard so .bak / .bak.* / .pre-* / .pre.* snapshot paths can never
be served via static even if one slips into the tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/server.js b/server.js
index 06af2a8..2a4d071 100644
--- a/server.js
+++ b/server.js
@@ -18,6 +18,13 @@ function psqlJson(sql) {
return execSync(`psql dw_unified -At -q`, { input: sql, encoding: 'utf8' }).trim();
}
+// Block any .bak / .bak.* / .pre-* / .pre.* snapshot paths from ever serving via static.
+// Fleet-wide hygiene: snapshot files must never be reachable from the web root.
+app.use((req, _res, next) => {
+ if (/\.(bak|pre)(\.|$|-)/i.test(req.path)) return next({ status: 404 });
+ next();
+});
+
// Proxy PD-corpus images from wallco-ai's data dir so the SP viewer can render them
const WALLCO_IMG_DIR = path.join(process.env.HOME, 'Projects', 'wallco-ai', 'data', 'images');
app.use('/pd-img', express.static(WALLCO_IMG_DIR, { maxAge: '7d' }));
@@ -194,7 +201,7 @@ function render() {
: '';
return \`
<div class="card">
- <a href="\${p.source_url}" target="_blank">
+ <a href="\${p.source_url}" target="_blank" rel="noopener noreferrer">
<div class="img" style="background-image:url('\${p.primary_image || ''}')"></div>
</a>
<div class="meta">
@@ -239,7 +246,7 @@ async function showPdModal(spId, title) {
const imgPath = fname ? '/pd-img/' + m.pd_source + '/' + fname : '';
return \`
<div class="pd-item">
- <a href="\${m.pd_source_url}" target="_blank">
+ <a href="\${m.pd_source_url}" target="_blank" rel="noopener noreferrer">
<img src="\${imgPath}" alt="\${m.pd_title}">
</a>
<div class="pd-meta">
← 4280d5a sp: set_variants.js — flatten 72 products to 2 variants (Rol
·
back to Sister Parish Onboarding
·
broaden .gitignore to exclude .bak/.pre-* snapshot files and f1ec46d →