Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@
**Vulnerability:** The application used a hardcoded string ('ffui-webui-2025') as a salt for HMAC signatures on session tokens. This makes session tokens predictable if the password is known or weak, and allows rainbow table attacks if the source code is public.
**Learning:** Hardcoded salts in open-source projects defeat the purpose of salting. Even if combined with a password, they don't provide per-installation uniqueness.
**Prevention:** Use a random secret generated at runtime (or installation time) and persist it in the application configuration.

## 2026-01-23 - Missing Security Headers
**Vulnerability:** The WebUI server was missing standard HTTP security headers (X-Frame-Options, X-Content-Type-Options, etc.), potentially exposing it to clickjacking and MIME-type confusion attacks.
**Learning:** Express.js does not include security headers by default. Explicit middleware is required to set them.
**Prevention:** Always include the `createSecurityHeadersMiddleware` (or `helmet`) in the Express app setup pipeline.
4 changes: 4 additions & 0 deletions src/main/webui/server/WebUIManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
createLoginRateLimiter,
createRequestLogger,
} from './auth-middleware.js';
import { createSecurityHeadersMiddleware } from './security-middleware.js';
import { registerPublicThemeRoutes } from './routes/theme-routes.js';
import { getWebSocketManager } from './WebSocketManager.js';

Expand Down Expand Up @@ -156,6 +157,9 @@ export class WebUIManager extends EventEmitter {
// Request logging
this.expressApp.use(createRequestLogger());

// Security headers
this.expressApp.use(createSecurityHeadersMiddleware());

// JSON body parsing
this.expressApp.use(express.json());

Expand Down
31 changes: 31 additions & 0 deletions src/main/webui/server/security-middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @fileoverview Middleware for adding security headers to HTTP responses.
*
* Implements "Defense in Depth" by adding standard security headers to all WebUI responses.
* These headers help prevent common attacks such as XSS, clickjacking, and MIME sniffing.
*/

import { NextFunction, Request, Response } from 'express';

/**
* Creates middleware that adds security headers to the response.
*/
export function createSecurityHeadersMiddleware() {
return (_req: Request, res: Response, next: NextFunction): void => {
// Prevent MIME sniffing
res.setHeader('X-Content-Type-Options', 'nosniff');

// Prevent clickjacking by denying framing (or allowing sameorigin)
// We use SAMEORIGIN to allow the UI to potentially frame itself if needed,
// though typically it's better to verify if this is needed.
res.setHeader('X-Frame-Options', 'SAMEORIGIN');

// Control referrer information
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');

// Enable XSS filtering in browsers that support it (mostly legacy, but good for depth)
res.setHeader('X-XSS-Protection', '1; mode=block');

next();
};
}