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
BASE_PATH=/
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
# Database Path - Local MaxMind databases location
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",
"**Custom API Keys** - Define multiple API keys with different access levels",
"**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",
"**Base Path Support** - Deploy under custom URL paths for reverse proxy scenarios",
"**Logging Levels** - Adjust verbosity from debug to production",
"**Seq Integration** - Optional structured logging to Seq server",
"**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
BASE_PATH=/
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
# Database Path - Point to your MaxMind databases location
MAXMIND_DB_PATH=D:\tools\maxmind-dbs # Windows
@ -322,22 +323,24 @@ npm run install:all # Install all dependencies (root + backend + frontend)
### Environment Variables
| Variable | Default | Description |
| ------------------------- | ---------------------- | -------------------------------------------- |
| `PORT` | `5172` | Server port |
| `BASE_PATH` | `/` | Application base path |
| `NODE_ENV` | `development` | Environment mode (development/production) |
| `MAXMIND_DB_PATH` | `/usr/share/maxmind` | MaxMind database directory |
| `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key |
| `EXTERNAL_API_KEYS` | `external-default-key` | External API keys (comma-separated) |
| `FRONTEND_RATE_WINDOW_MS` | `60000` | Frontend rate limit window (milliseconds) |
| `FRONTEND_RATE_MAX` | `30` | Frontend rate limit max requests |
| `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) |
| `EXTERNAL_RATE_MAX` | `1000` | External rate limit max requests |
| `BATCH_LIMIT` | `100` | Maximum IPs per batch request |
| `DEBOUNCE_MS` | `2000` | Frontend input debounce delay (milliseconds) |
| `SEQ_URL` | - | Seq logging server URL (optional) |
| `SEQ_API_KEY` | - | Seq API key (optional) |
| Variable | Default | Description |
| -------------------------- | ---------------------- | --------------------------------------------------------------- |
| `PORT` | `5172` | Server port |
| `BASE_PATH` | `/` | Application base path |
| `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 |
| `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key |
| `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_MAX` | `30` | Frontend rate limit max requests |
| `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) |
| `EXTERNAL_RATE_MAX` | `1000` | External rate limit max requests |
| `BATCH_LIMIT` | `100` | Maximum IPs per batch request |
| `DEBOUNCE_MS` | `2000` | Frontend input debounce delay (milliseconds) |
| `SEQ_URL` | - | Seq logging server URL (optional) |
| `SEQ_API_KEY` | - | Seq API key (optional) |
### MaxMind Database Setup
@ -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.
### 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
### Production Setup

View File

@ -84,6 +84,7 @@ FRONTEND_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174,http://loca
PORT=5172
BASE_PATH=/geoip-ui
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
```
**`PORT`**
@ -119,6 +120,22 @@ NODE_ENV=development
- `production` - Optimized for performance, minimal logging
- **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
@ -301,6 +318,7 @@ VITE_DEBOUNCE_MS=2000
PORT=5172
BASE_PATH=/geoip-ui
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
@ -348,6 +366,7 @@ FRONTEND_ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
PORT=5172
BASE_PATH=/
NODE_ENV=production
ENABLE_HTTPS_SECURITY=true
MAXMIND_DB_PATH=/usr/share/maxmind
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30

View File

@ -21,10 +21,24 @@ const app = express();
// Security middleware
app.use(
helmet({
contentSecurityPolicy: false, // Disable CSP to allow HTTP access
strictTransportSecurity: false, // Disable HSTS to allow HTTP access
crossOriginOpenerPolicy: false, // Disable COOP to allow HTTP access
crossOriginResourcePolicy: false, // Disable CORP to allow HTTP access
contentSecurityPolicy: config.enableHttpsSecurity
? {
directives: {
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',
seqUrl: process.env.SEQ_URL,
seqApiKey: process.env.SEQ_API_KEY,
enableHttpsSecurity: process.env.ENABLE_HTTPS_SECURITY === 'true',
apiKeys: {
frontend: process.env.FRONTEND_API_KEY || 'frontend-default-key',
external: (process.env.EXTERNAL_API_KEYS || 'external-default-key')

View File

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