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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Copy the file `.env.template` to `.env` and adapt the variables to your installa

**IMPORTANT** Set a STRONG password for `ADMIN_PASSWORD` and consider changing `ADMIN_USERNAME`. Obtaining these credentials allows administrator access to **all services**! In order to minimize the potential impact of a security bug in one of the services, you should also create a separate database user and strong password for each of the services.

**SECURITY CRITICAL**: After initial startup, there will be two users available: the admin user with userid `ADMIN_USERNAME` and your set password, and a `demouser` with password `demouser`. **THE DEMO USER ACCOUNT MUST BE DISABLED IMMEDIATELY IN PRODUCTION** as it provides unrestricted access with well-known credentials. See [SECURITY_WARNING.md](SECURITY_WARNING.md) for detailed security instructions.

Be sure to have the values right - re-configuration is NOT supported!

By default only the `elexis-server` service is active. To activate other services, set the respective variable to `true` in section 3 of `.env`.
Expand Down
135 changes: 135 additions & 0 deletions SECURITY_FIXES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Elexis Environment Security Fixes and Hardening Guide

## Summary
This document outlines the security vulnerabilities found and the fixes implemented in the Elexis Environment.

## Implemented Security Fixes

### 1. Added Global Security Headers
**File**: `docker/compose/assets/web/etc/conf/security-headers.conf`
**Fixed**: Missing HSTS, CSP, and other security headers

Added comprehensive security headers including:
- HTTP Strict Transport Security (HSTS) with 1-year duration
- Content Security Policy (CSP) to prevent XSS attacks
- X-Content-Type-Options to prevent MIME sniffing
- X-Frame-Options for clickjacking protection
- Referrer-Policy for privacy protection
- Permissions-Policy to disable dangerous browser features

### 2. Implemented Rate Limiting
**Files**:
- `docker/compose/assets/web/etc/nginx.conf`
- `docker/compose/assets/web/etc/conf/nginx-int.conf`
- `docker/compose/assets/web/etc/conf/nginx-ext.conf`
- `docker/compose/assets/web/etc/conf/elexis-server-ext.conf`

**Fixed**: DoS and brute force attack vectors

Added rate limiting zones:
- General requests: 10 req/s (internal), more restrictive for external
- Authentication endpoints: 5 req/s (internal), 3 req/s (external)
- API endpoints: 30 req/s with burst handling

### 3. Reduced File Upload Limits
**Files**:
- `docker/compose/assets/web/etc/nginx.conf` (512M → 100M)
- `docker/compose/assets/web/etc/conf/guacamole*.conf` (512M → 256M)

**Fixed**: Potential DoS through large file uploads

### 4. Enhanced Keycloak Security
**File**: `docker/compose/assets/web/etc/conf/nginx-ext.conf`
**Fixed**: Administrative endpoint exposure

Added blocks for additional sensitive endpoints:
- `/keycloak/auth/management/`
- `/keycloak/auth/subsystem/`
- Enhanced existing blocks for admin endpoints

### 5. Created Security Documentation
**Files**:
- `SECURITY_WARNING.md` - Critical security warnings
- `docker/security.env` - Docker security configuration template
- Updated `README.md` with prominent security warnings

**Fixed**: Lack of security awareness and documentation

## Manual Actions Required

### CRITICAL - Disable Demo User
The default `demouser` account with password `demouser` must be disabled:

1. Access Keycloak admin console: `https://yourhost/keycloak/auth/admin/`
2. Login with admin credentials
3. Navigate to Users → Find `demouser`
4. Disable or delete the account

### IMPORTANT - Environment Security
1. Change all default passwords in `.env` file
2. Use strong, unique passwords for each service
3. Review and restrict enabled services to minimum required
4. Implement proper SSL certificate management
5. Regular security updates and patches

## Remaining Security Considerations

### High Priority
1. **Container Privilege Review**: Some containers still require elevated privileges (wireguard, code-server)
2. **Database Security**: Ensure database servers are properly secured and access-controlled
3. **Network Segmentation**: Consider additional network isolation between services
4. **Backup Security**: Implement secure backup procedures with encryption

### Medium Priority
1. **Log Monitoring**: Implement security monitoring and alerting
2. **Vulnerability Scanning**: Regular container and dependency scanning
3. **Access Control**: Implement proper RBAC within applications
4. **Certificate Management**: Automated certificate renewal and monitoring

### Low Priority
1. **Security Headers Tuning**: Fine-tune CSP policies per application
2. **Rate Limiting Optimization**: Adjust limits based on usage patterns
3. **Error Page Hardening**: Custom error pages to prevent information disclosure

## Testing Security Fixes

To validate the security improvements:

1. **Test Security Headers**:
```bash
curl -I https://yourhost/
# Verify presence of security headers
```

2. **Test Rate Limiting**:
```bash
# Test authentication rate limiting
for i in {1..10}; do curl -w "%{http_code}\n" https://yourhost/keycloak/; done
```

3. **Test Blocked Endpoints**:
```bash
curl -I https://yourhost/keycloak/auth/admin/
# Should return 403 Forbidden
```

## Security Monitoring

Recommended monitoring points:
- Failed authentication attempts
- Rate limit violations
- Access to blocked endpoints
- Large file upload attempts
- SSL certificate expiration

## Compliance Notes

These fixes help with:
- HIPAA compliance for medical data protection
- GDPR privacy requirements
- Industry security best practices
- PCI DSS if payment processing is involved

## Contact

For security questions or to report vulnerabilities, please follow responsible disclosure practices and contact the maintainers privately.
17 changes: 17 additions & 0 deletions SECURITY_WARNING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Security warning about demo user
# This file contains important security information that administrators should read

# CRITICAL SECURITY WARNING:
# The default installation includes a demo user account with the following credentials:
# Username: demouser
# Password: demouser
#
# THIS ACCOUNT MUST BE DISABLED OR SECURED BEFORE PRODUCTION USE!
#
# For production environments:
# 1. Disable the demo user account in Keycloak administration console
# 2. Ensure all default accounts have strong, unique passwords
# 3. Implement proper user management and access controls
# 4. Regular audit user accounts and permissions
#
# Failure to secure these accounts may result in unauthorized access to sensitive medical data.
4 changes: 4 additions & 0 deletions docker/compose/assets/web/etc/conf/elexis-server-ext.conf
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
location /fhir/ {
# Apply API rate limiting
limit_req zone=api burst=50 nodelay;
include conf/proxy.conf;
proxy_pass http://elexis-server:8380/fhir/;
}

# only v1 subtree, /services in elexis-server.conf
location /services/v1/ {
# Apply API rate limiting
limit_req zone=api burst=50 nodelay;
include conf/proxy.conf;
proxy_pass http://elexis-server:8380/services/v1/;
}
2 changes: 1 addition & 1 deletion docker/compose/assets/web/etc/conf/guacamole-ext.conf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ location ^~ /guacamole/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
client_max_body_size 512m;
client_max_body_size 256m;
access_log off;
}
2 changes: 1 addition & 1 deletion docker/compose/assets/web/etc/conf/guacamole.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ location ^~ /guacamole-admin/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
client_max_body_size 512m;
client_max_body_size 256m;
access_log off;
}
37 changes: 30 additions & 7 deletions docker/compose/assets/web/etc/conf/nginx-ext.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,54 @@ server {
error_page 404 /b_pub/pages/404.html;
error_page 403 /b_pub/pages/403.html;

# Apply global security headers
include conf/security-headers.conf;

# Rate limiting for external requests (more restrictive)
limit_req zone=general burst=10 nodelay;

# -- EXTERNAL SERVICES -----

# -- Keycloak
# https://www.keycloak.org/server/reverseproxy#_exposed_path_recommendations
location ^~ /keycloak/auth/admin {
# Block additional Keycloak admin endpoints for security
location ^~ /keycloak/auth/admin/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/realms/master/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/metrics/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/metrics {
location ^~ /keycloak/auth/health/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/health {
location ^~ /keycloak/auth/welcome/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/welcome {
# Block management and monitoring endpoints
location ^~ /keycloak/auth/management/ {
deny all;
return 403;
}

location ^~ /keycloak/auth/realms/master {
location ^~ /keycloak/auth/subsystem/ {
deny all;
return 403;
}

location ^~ /keycloak {
# Apply authentication rate limiting for external access
limit_req zone=auth burst=3 nodelay;
include conf/proxy.conf;
proxy_set_header X-EE-Ingress-Port $server_port;
proxy_pass http://keycloak:8080;
Expand Down
8 changes: 8 additions & 0 deletions docker/compose/assets/web/etc/conf/nginx-int.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ server {
error_page 404 /b_pub/pages/404.html;
error_page 403 /b_pub/pages/403.html;

# Apply global security headers
include conf/security-headers.conf;

# Rate limiting for general requests
limit_req zone=general burst=20 nodelay;

# http://nginx.org/en/docs/http/ngx_http_stub_status_module.html
location = /.nginx_stub_status {
stub_status;
Expand All @@ -37,6 +43,8 @@ server {

# -- Keycloak
location ^~ /keycloak {
# Apply authentication rate limiting
limit_req zone=auth burst=5 nodelay;
include conf/proxy.conf;
proxy_set_header X-EE-Ingress-Port $server_port;
proxy_pass http://keycloak:8080;
Expand Down
26 changes: 26 additions & 0 deletions docker/compose/assets/web/etc/conf/security-headers.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Global security headers for all locations
# Include this file in server blocks to apply consistent security headers

# HTTP Strict Transport Security (HSTS) - force HTTPS for 1 year
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Content Security Policy - restrictive policy to prevent XSS
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self'; form-action 'self'; base-uri 'self';" always;

# Prevent MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Clickjacking protection
add_header X-Frame-Options "SAMEORIGIN" always;

# XSS protection (legacy header but still useful)
add_header X-XSS-Protection "1; mode=block" always;

# Referrer policy - limit referrer information
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Permissions policy - disable potentially dangerous features
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()" always;

# Prevent information disclosure
add_header X-Robots-Tag "noindex, nofollow" always;
7 changes: 6 additions & 1 deletion docker/compose/assets/web/etc/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ http {
log_not_found off;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 512M;
client_max_body_size 100M;
client_body_buffer_size 512k;

# mitigate keycloak "upstream sent too big header"
Expand Down Expand Up @@ -61,6 +61,11 @@ http {
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

# Rate limiting to prevent abuse
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;

resolver 127.0.0.11 valid=30s ipv6=off;

# Set the `immutable` cache control options only for assets with a cache busting `v` argument
Expand Down
21 changes: 21 additions & 0 deletions docker/security.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Docker Security Configuration

# Security optimization for production environments
# Set memory limits for all containers to prevent resource exhaustion
DOCKER_DEFAULT_MEM_LIMIT=1G
DOCKER_DEFAULT_MEMSWAP_LIMIT=1G

# Disable unnecessary capabilities by default
DOCKER_SECURITY_OPT="no-new-privileges:true"

# Network security settings
DOCKER_NETWORK_ISOLATION=true

# Container runtime security
DOCKER_READONLY_ROOT=false # Set to true when possible
DOCKER_TMPFS_SIZE=100m

# Log security settings
DOCKER_LOG_DRIVER=json-file
DOCKER_LOG_MAX_SIZE=10m
DOCKER_LOG_MAX_FILE=3