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:
2026-03-09 04:47:32 +01:00
parent d1a20fa02e
commit f8ed2b83e9
18 changed files with 94 additions and 42 deletions

View File

@@ -5,8 +5,23 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}IETF Draft Analyzer{% endblock %}</title>
<script src="/static/js/tailwind.js"></script>
<script src="/static/js/purify.min.js"></script>
<link rel="stylesheet" href="/static/css/fonts.css">
<script>
// Global HTML escape helper for safe innerHTML usage
function escapeHtml(str) {
if (!str) return '';
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
// Safe markdown rendering: marked + DOMPurify
function safeMarkdown(md) {
if (typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
return DOMPurify.sanitize(marked.parse(md || ''));
}
return escapeHtml(md || '');
}
tailwind.config = {
darkMode: 'class',
theme: {