Fix Docker blank page when accessing via IP, add iframe support and HTTPS upgrade control (#1027)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
This commit is contained in:
@@ -68,6 +68,8 @@ docker-compose up -d
|
|||||||
| `PORT` | No | `3000` | Port the server listens on |
|
| `PORT` | No | `3000` | Port the server listens on |
|
||||||
| `ALLOWED_ORIGINS` | No | `*` | Comma-separated list of allowed CORS origins |
|
| `ALLOWED_ORIGINS` | No | `*` | Comma-separated list of allowed CORS origins |
|
||||||
| `NODE_ENV` | No | - | Set to `production` for production deployments |
|
| `NODE_ENV` | No | - | Set to `production` for production deployments |
|
||||||
|
| `UPGRADE_INSECURE_REQUESTS` | No | `false` | Set to `true` to enable CSP upgrade-insecure-requests directive. **Only use when deployed behind an HTTPS reverse proxy (nginx, Traefik, etc.) with valid SSL certificates.** This upgrades all HTTP requests to HTTPS and will break direct HTTP access. |
|
||||||
|
| `X_FRAME_OPTIONS` | No | `false` | Set to `true` to enable X-Frame-Options: SAMEORIGIN header to prevent clickjacking. **Disables iframe embedding when enabled.** |
|
||||||
|
|
||||||
### Authentication Modes
|
### Authentication Modes
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ const CREDENTIALS_PATH = path.join(process.cwd(), 'data', 'credentials.json')
|
|||||||
const MAX_FILE_SIZE = 16 * 1024 * 1024 // 16MB limit for file uploads
|
const MAX_FILE_SIZE = 16 * 1024 * 1024 // 16MB limit for file uploads
|
||||||
const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : ['*']
|
const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : ['*']
|
||||||
const isProduction = process.env.NODE_ENV === 'production'
|
const isProduction = process.env.NODE_ENV === 'production'
|
||||||
|
// Enable upgrade-insecure-requests only when behind HTTPS reverse proxy
|
||||||
|
const enableUpgradeInsecure = process.env.UPGRADE_INSECURE_REQUESTS === 'true'
|
||||||
|
// Enable X-Frame-Options header to prevent iframe embedding (disabled by default)
|
||||||
|
const enableXFrameOptions = process.env.X_FRAME_OPTIONS === 'true'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and sanitizes file paths to prevent path traversal attacks
|
* Validates and sanitizes file paths to prevent path traversal attacks
|
||||||
@@ -83,6 +87,7 @@ async function startServer() {
|
|||||||
styleSrc: ["'self'", "'unsafe-inline'"], // Required for Material-UI
|
styleSrc: ["'self'", "'unsafe-inline'"], // Required for Material-UI
|
||||||
connectSrc: ["'self'", 'ws:', 'wss:'], // Allow WebSocket connections
|
connectSrc: ["'self'", 'ws:', 'wss:'], // Allow WebSocket connections
|
||||||
imgSrc: ["'self'", 'data:', 'blob:'],
|
imgSrc: ["'self'", 'data:', 'blob:'],
|
||||||
|
upgradeInsecureRequests: enableUpgradeInsecure ? [] : null, // Only enable when behind HTTPS reverse proxy
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hsts: isProduction
|
hsts: isProduction
|
||||||
@@ -92,6 +97,7 @@ async function startServer() {
|
|||||||
preload: true,
|
preload: true,
|
||||||
}
|
}
|
||||||
: false,
|
: false,
|
||||||
|
frameguard: enableXFrameOptions ? { action: 'sameorigin' } : false, // Disabled by default to allow iframe embedding
|
||||||
// Disable cross-origin policies that cause blank pages when accessing via IP vs localhost
|
// Disable cross-origin policies that cause blank pages when accessing via IP vs localhost
|
||||||
// These headers can block resources and cause rendering issues on HTTP-only deployments
|
// These headers can block resources and cause rendering issues on HTTP-only deployments
|
||||||
crossOriginEmbedderPolicy: false, // Can block resources without proper CORP headers
|
crossOriginEmbedderPolicy: false, // Can block resources without proper CORP headers
|
||||||
|
|||||||
Reference in New Issue
Block a user