fix: security hardening — self-hosted JS, XSS protection, SSRF blocking
- Replace all CDN script tags (marked, plotly) with self-hosted static files - Add DOMPurify for sanitizing markdown-rendered HTML - Add escapeHtml() helper to base.html for all innerHTML operations - Sanitize dynamic data in innerHTML across 13 templates - Add security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) - Add SSRF protection to proposal intake URL fetcher (block private/loopback IPs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -150,7 +150,7 @@ function runIntake() {
|
||||
|
||||
data.proposals.forEach((p, i) => {
|
||||
const gapPills = (p.gap_ids || []).map(gid =>
|
||||
`<a href="/gaps/${gid}" class="px-2 py-0.5 rounded text-[10px] bg-slate-800 text-slate-400 hover:text-blue-400 transition">#${gid}</a>`
|
||||
`<a href="/gaps/${parseInt(gid)}" class="px-2 py-0.5 rounded text-[10px] bg-slate-800 text-slate-400 hover:text-blue-400 transition">#${parseInt(gid)}</a>`
|
||||
).join(' ');
|
||||
|
||||
const card = document.createElement('div');
|
||||
@@ -158,10 +158,10 @@ function runIntake() {
|
||||
card.style.animationDelay = `${i * 0.1}s`;
|
||||
card.innerHTML = `
|
||||
<div class="flex items-start justify-between gap-3 mb-2">
|
||||
<a href="/proposals/${p.id}" class="text-base font-semibold text-white hover:text-blue-400 transition">${p.title}</a>
|
||||
<a href="/proposals/${parseInt(p.id)}" class="text-base font-semibold text-white hover:text-blue-400 transition">${escapeHtml(p.title)}</a>
|
||||
<span class="px-2.5 py-0.5 rounded-full text-xs font-semibold bg-purple-500/20 text-purple-400 ring-1 ring-purple-500/30 whitespace-nowrap">IDEA</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-400 mb-3">${p.description}</p>
|
||||
<p class="text-sm text-slate-400 mb-3">${escapeHtml(p.description)}</p>
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<span class="text-[10px] text-slate-500">Gaps:</span>
|
||||
${gapPills || '<span class="text-[10px] text-slate-600">none linked</span>'}
|
||||
|
||||
Reference in New Issue
Block a user