Fix 7 frontend security vulnerabilities (4 critical, 3 high)

- Escape all innerHTML assignments with user/external data across 12 JS files
- Upgrade credential encryption: per-value IV, key moved to sessionStorage
- Fix open redirect in TOTP auth via proper URL hostname validation
- Remove sensitive DNS topology data from localStorage cache
- Add security regression test suite (51 tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 01:29:04 -08:00
parent 59b6d7d360
commit 52577b11ed
13 changed files with 874 additions and 96 deletions

View File

@@ -104,8 +104,21 @@
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('auth') === 'required') {
const returnUrl = urlParams.get('return');
if (returnUrl && returnUrl.includes(SITE.tld)) {
safeSessionSet('totp_redirect', returnUrl);
if (returnUrl) {
// Validate redirect URL: must be same-origin or hostname must end with our TLD
// (prevents open redirect via includes() bypass like evil.com?q=.sami)
try {
const parsed = new URL(returnUrl, window.location.origin);
const hostname = parsed.hostname;
const isSameOrigin = parsed.origin === window.location.origin;
const tldSuffix = SITE.tld.startsWith('.') ? SITE.tld : '.' + SITE.tld;
const isOurTld = hostname.endsWith(tldSuffix) || hostname === tldSuffix.substring(1);
if (isSameOrigin || isOurTld) {
safeSessionSet('totp_redirect', returnUrl);
}
} catch (_) {
// Invalid URL — reject redirect
}
}
// Clean URL
window.history.replaceState({}, '', window.location.pathname);