refactor: add ENABLE_HTTPS_SECURITY environment variable and update security middleware to toggle headers based on its value

This commit is contained in:
Tudor Stanciu 2025-10-04 03:24:15 +03:00
parent 9dddf2fa29
commit 1d6eb6e5a6
7 changed files with 70 additions and 20 deletions

1
.env
View File

@ -12,6 +12,7 @@ FRONTEND_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174,http://loca
PORT=5172 PORT=5172
BASE_PATH=/ BASE_PATH=/
NODE_ENV=development NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
# Database Path - Local MaxMind databases location # Database Path - Local MaxMind databases location
MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs

View File

@ -205,7 +205,9 @@
"**Configurable Rate Limits** - Adjust per API key type based on your needs", "**Configurable Rate Limits** - Adjust per API key type based on your needs",
"**Custom API Keys** - Define multiple API keys with different access levels", "**Custom API Keys** - Define multiple API keys with different access levels",
"**Origin Whitelisting** - Control which domains can use frontend API keys", "**Origin Whitelisting** - Control which domains can use frontend API keys",
"**HTTPS Security Headers** - Toggle security headers (CSP, HSTS, COOP, CORP) based on deployment type (HTTP vs HTTPS)",
"**Port Configuration** - Customize backend and frontend ports", "**Port Configuration** - Customize backend and frontend ports",
"**Base Path Support** - Deploy under custom URL paths for reverse proxy scenarios",
"**Logging Levels** - Adjust verbosity from debug to production", "**Logging Levels** - Adjust verbosity from debug to production",
"**Seq Integration** - Optional structured logging to Seq server", "**Seq Integration** - Optional structured logging to Seq server",
"**Database Path** - Configurable GeoLite2 database location" "**Database Path** - Configurable GeoLite2 database location"

View File

@ -50,6 +50,7 @@ EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2
PORT=5172 PORT=5172
BASE_PATH=/ BASE_PATH=/
NODE_ENV=development NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
# Database Path - Point to your MaxMind databases location # Database Path - Point to your MaxMind databases location
MAXMIND_DB_PATH=D:\tools\maxmind-dbs # Windows MAXMIND_DB_PATH=D:\tools\maxmind-dbs # Windows
@ -323,13 +324,15 @@ npm run install:all # Install all dependencies (root + backend + frontend)
### Environment Variables ### Environment Variables
| Variable | Default | Description | | Variable | Default | Description |
| ------------------------- | ---------------------- | -------------------------------------------- | | -------------------------- | ---------------------- | --------------------------------------------------------------- |
| `PORT` | `5172` | Server port | | `PORT` | `5172` | Server port |
| `BASE_PATH` | `/` | Application base path | | `BASE_PATH` | `/` | Application base path |
| `NODE_ENV` | `development` | Environment mode (development/production) | | `NODE_ENV` | `development` | Environment mode (development/production) |
| `ENABLE_HTTPS_SECURITY` | `false` | Enable HTTPS security headers (CSP, HSTS, COOP, CORP) |
| `MAXMIND_DB_PATH` | `/usr/share/maxmind` | MaxMind database directory | | `MAXMIND_DB_PATH` | `/usr/share/maxmind` | MaxMind database directory |
| `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key | | `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key |
| `EXTERNAL_API_KEYS` | `external-default-key` | External API keys (comma-separated) | | `EXTERNAL_API_KEYS` | `external-default-key` | External API keys (comma-separated) |
| `FRONTEND_ALLOWED_ORIGINS` | `http://localhost:*` | Allowed CORS origins for frontend (comma-separated) |
| `FRONTEND_RATE_WINDOW_MS` | `60000` | Frontend rate limit window (milliseconds) | | `FRONTEND_RATE_WINDOW_MS` | `60000` | Frontend rate limit window (milliseconds) |
| `FRONTEND_RATE_MAX` | `30` | Frontend rate limit max requests | | `FRONTEND_RATE_MAX` | `30` | Frontend rate limit max requests |
| `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) | | `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) |
@ -365,6 +368,15 @@ Bitip implements different rate limiting for frontend and external API consumers
Rate limits are fully configurable via environment variables and include standard HTTP headers in responses. Rate limits are fully configurable via environment variables and include standard HTTP headers in responses.
### HTTPS Security Headers
The `ENABLE_HTTPS_SECURITY` variable controls security headers provided by Helmet:
- **`false` (default)**: Disables CSP, HSTS, COOP, and CORP headers - required for HTTP deployments
- **`true`**: Enables all security headers - use when deploying behind HTTPS reverse proxy (nginx, Traefik, etc.)
**Important**: If running on plain HTTP without a reverse proxy, keep this set to `false`. Browser security policies will block resources if HTTPS security headers are enabled on HTTP connections.
## 🐳 Docker Deployment ## 🐳 Docker Deployment
### Production Setup ### Production Setup

View File

@ -84,6 +84,7 @@ FRONTEND_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174,http://loca
PORT=5172 PORT=5172
BASE_PATH=/geoip-ui BASE_PATH=/geoip-ui
NODE_ENV=development NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
``` ```
**`PORT`** **`PORT`**
@ -119,6 +120,22 @@ NODE_ENV=development
- `production` - Optimized for performance, minimal logging - `production` - Optimized for performance, minimal logging
- **Example**: `production` - **Example**: `production`
**`ENABLE_HTTPS_SECURITY`**
- **Purpose**: Enable/disable HTTPS security headers (Helmet middleware)
- **Format**: Boolean string (`true` or `false`)
- **Required**: No
- **Default**: `false`
- **Valid Values**:
- `false` - Disables CSP, HSTS, COOP, and CORP headers (required for plain HTTP)
- `true` - Enables all security headers (use when behind HTTPS reverse proxy)
- **Use Cases**:
- Set to `false` for development on HTTP
- Set to `false` for production HTTP deployments
- Set to `true` when using HTTPS with reverse proxy (nginx, Traefik, Caddy, etc.)
- **Important**: Browser security policies will block resources if HTTPS security headers are enabled on plain HTTP connections. Only enable when serving over HTTPS.
- **Example**: `false`
--- ---
#### MaxMind Database Configuration #### MaxMind Database Configuration
@ -301,6 +318,7 @@ VITE_DEBOUNCE_MS=2000
PORT=5172 PORT=5172
BASE_PATH=/geoip-ui BASE_PATH=/geoip-ui
NODE_ENV=development NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs
FRONTEND_RATE_WINDOW_MS=60000 FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30 FRONTEND_RATE_MAX=30
@ -348,6 +366,7 @@ FRONTEND_ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
PORT=5172 PORT=5172
BASE_PATH=/ BASE_PATH=/
NODE_ENV=production NODE_ENV=production
ENABLE_HTTPS_SECURITY=true
MAXMIND_DB_PATH=/usr/share/maxmind MAXMIND_DB_PATH=/usr/share/maxmind
FRONTEND_RATE_WINDOW_MS=60000 FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30 FRONTEND_RATE_MAX=30

View File

@ -21,10 +21,24 @@ const app = express();
// Security middleware // Security middleware
app.use( app.use(
helmet({ helmet({
contentSecurityPolicy: false, // Disable CSP to allow HTTP access contentSecurityPolicy: config.enableHttpsSecurity
strictTransportSecurity: false, // Disable HSTS to allow HTTP access ? {
crossOriginOpenerPolicy: false, // Disable COOP to allow HTTP access directives: {
crossOriginResourcePolicy: false, // Disable CORP to allow HTTP access defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", 'https://unpkg.com'],
scriptSrc: ["'self'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"],
},
}
: false,
strictTransportSecurity: config.enableHttpsSecurity,
crossOriginOpenerPolicy: config.enableHttpsSecurity,
crossOriginResourcePolicy: config.enableHttpsSecurity,
}) })
); );

View File

@ -16,6 +16,7 @@ export const config: Config = {
maxmindDbPath: process.env.MAXMIND_DB_PATH || '/usr/share/maxmind', maxmindDbPath: process.env.MAXMIND_DB_PATH || '/usr/share/maxmind',
seqUrl: process.env.SEQ_URL, seqUrl: process.env.SEQ_URL,
seqApiKey: process.env.SEQ_API_KEY, seqApiKey: process.env.SEQ_API_KEY,
enableHttpsSecurity: process.env.ENABLE_HTTPS_SECURITY === 'true',
apiKeys: { apiKeys: {
frontend: process.env.FRONTEND_API_KEY || 'frontend-default-key', frontend: process.env.FRONTEND_API_KEY || 'frontend-default-key',
external: (process.env.EXTERNAL_API_KEYS || 'external-default-key') external: (process.env.EXTERNAL_API_KEYS || 'external-default-key')

View File

@ -69,6 +69,7 @@ export interface Config {
maxmindDbPath: string; maxmindDbPath: string;
seqUrl?: string; seqUrl?: string;
seqApiKey?: string; seqApiKey?: string;
enableHttpsSecurity: boolean;
apiKeys: { apiKeys: {
frontend: string; frontend: string;
external: string[]; external: string[];