fix: security hardening, SSE robustness, and API consistency

Security:
- Add sanitizeHookData() to whitelist/truncate hook event fields before SSE broadcast
- Add MAX_INPUT_LENGTH (64KB) validation on session input endpoint
- Add MAX_TERMINAL_COLS/ROWS bounds on resize endpoint
- Add MAX_SESSION_NAME_LENGTH on rename endpoint
- Remove Access-Control-Allow-Origin: * from SSE (same-origin only)
- Add X-Accel-Buffering: no header for nginx proxy compatibility

Robustness:
- Add SSE keep-alive comments in health check cycle (prevents proxy timeouts)
- Guard broadcast() against JSON.stringify failures (circular refs, BigInt)
- Prevent concurrent cleanup races with cleaningUp guard set
- Clear stateUpdatePending on session cleanup

API consistency:
- Normalize error responses to use createErrorResponse() with error codes
- Remove dead (session as any).ralphConfig assignment + unused destructuring

Performance:
- Pre-compile CLAUDE_BANNER_PATTERN, CTRL_L_PATTERN, LEADING_WHITESPACE_PATTERN

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-01-24 04:35:58 +01:00
co-authored by Claude Opus 4.5
parent 2e4320fee7
commit 0ea7a21df2
2 changed files with 128 additions and 48 deletions
+1 -3
View File
@@ -2197,11 +2197,9 @@ class ClaudemanApp {
// Populate Ralph Wiggum form with current session values
const ralphState = this.ralphStates.get(sessionId);
this.populateRalphForm({
enabled: ralphState?.loop?.enabled ?? session.ralphConfig?.enabled ?? false,
enabled: ralphState?.loop?.enabled ?? session.ralphLoop?.enabled ?? false,
completionPhrase: ralphState?.loop?.completionPhrase || session.ralphLoop?.completionPhrase || '',
maxIterations: ralphState?.loop?.maxIterations || session.ralphLoop?.maxIterations || 0,
maxTodos: session.ralphConfig?.maxTodos || 50,
todoExpirationMinutes: session.ralphConfig?.todoExpirationMinutes || 60
});
document.getElementById('sessionOptionsModal').classList.add('active');