← back to Rentv 2026
fix(sitemap): xmlEsc the <loc> (sibling-drift — feed.xml/deals.xml already escape) so the sitemap stays valid XML if a slug carries an '&' and the client-controlled Host header can't inject into it. Defensive: current slugs/ids are all clean
1f840675c83749528266c240a8600382ee48f159 · 2026-08-06 11:53:05 -0700 · Steve
Files touched
Diff
commit 1f840675c83749528266c240a8600382ee48f159
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Aug 6 11:53:05 2026 -0700
fix(sitemap): xmlEsc the <loc> (sibling-drift — feed.xml/deals.xml already escape) so the sitemap stays valid XML if a slug carries an '&' and the client-controlled Host header can't inject into it. Defensive: current slugs/ids are all clean
---
server.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 20b35a8e..1df1057e 100644
--- a/server.js
+++ b/server.js
@@ -1405,7 +1405,9 @@ app.get('/sitemap.xml', (req, r) => {
const addArticle = (a) => { const id = a && a.id; if (id && !seenIds.has(id)) { seenIds.add(id); urls.push('/news/' + id); } };
try { corpus().forEach(addArticle); } catch {}
(Array.isArray(items) ? items : []).forEach(addArticle);
- const body = urls.map(u => ` <url><loc>${base}${u}</loc></url>`).join('\n');
+ // xmlEsc the <loc> (matches feed.xml/deals.xml) — keeps the sitemap valid XML if a slug ever carries
+ // an & and closes the client-controlled Host header (req.get('host') → base) as an injection vector.
+ const body = urls.map(u => ` <url><loc>${xmlEsc(base + u)}</loc></url>`).join('\n');
r.type('application/xml').send(`<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${body}\n</urlset>\n`);
});
← 55129020 nav(services): add CRE Services to shared masthead drawer (r
·
back to Rentv 2026
·
deploy.sh: reload procs separately + retrying health check ( 3cc78886 →