Harden security across frontend and backend
All checks were successful
Build & Push Container Image / build (push) Successful in 11s

1. AdfRenderer: validate href starts with https?:// before rendering links
2. Logout route: add requireAuth middleware
3. Jira API params: validate sprintId, boardId, issueIdOrKey are alphanumeric
4. CSP header: add Content-Security-Policy with restrictive defaults
5. OAuth callback: align frontendUrl fallback with index.js
6. Rate limiting: express-rate-limit on API routes + Socket.IO event throttling
7. Session KV keys: prefix with cloudId for tenant isolation defense-in-depth
8. saveScopedEstimate: use withSessionCas for atomic read-update-delete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jan Willem Mannaerts 2026-02-28 16:05:48 +01:00
parent 3ab584e2ab
commit 03ba19042d
8 changed files with 127 additions and 47 deletions

View file

@ -79,7 +79,11 @@ function parseWikiInline(text) {
} else if (match[5] != null) {
parts.push(<code key={match.index} className="bg-slate-100 dark:bg-slate-700 text-red-600 dark:text-red-400 px-1.5 py-0.5 rounded text-sm font-mono">{match[5]}</code>);
} else if (match[6] != null && match[7] != null) {
parts.push(<a key={match.index} href={match[7]} target="_blank" rel="noopener noreferrer" className="text-emerald-600 dark:text-emerald-400 hover:underline">{match[6]}</a>);
if (/^https?:\/\//i.test(match[7])) {
parts.push(<a key={match.index} href={match[7]} target="_blank" rel="noopener noreferrer" className="text-emerald-600 dark:text-emerald-400 hover:underline">{match[6]}</a>);
} else {
parts.push(<span key={match.index}>{match[6]}</span>);
}
} else if (match[8] != null) {
parts.push(<a key={match.index} href={match[8]} target="_blank" rel="noopener noreferrer" className="text-emerald-600 dark:text-emerald-400 hover:underline">{match[8]}</a>);
}