diff --git a/backend/config/settings.py b/backend/config/settings.py index 045444f..01b6298 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -25,7 +25,7 @@ load_dotenv(BASE_DIR.parent / '.env') # See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', 'django-insecure-@8*97xo5!gdi!x*94-%n8$b63%ljy#@&^#7$h!9v-4a2#r+98t') +SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') # Environment setup (development / production) # Reads DEV=True for development, DEV=False for production @@ -41,15 +41,22 @@ if IS_DEV: ] else: DEBUG = os.getenv('DJANGO_DEBUG', 'False').lower() in ('true', '1', 't') - allowed_hosts_raw = os.getenv('ALLOWED_HOSTS', '*') + allowed_hosts_raw = os.getenv('ALLOWED_HOSTS', '') ALLOWED_HOSTS = [host.strip() for host in allowed_hosts_raw.split(',') if host.strip()] - if '*' not in ALLOWED_HOSTS: - ALLOWED_HOSTS.append('*') - CORS_ALLOW_ALL_ORIGINS = True - csrf_origins = os.getenv('CSRF_TRUSTED_ORIGINS', 'https://divar.nwhco.ir,http://divar.nwhco.ir,http://localhost,http://127.0.0.1') + CORS_ALLOW_ALL_ORIGINS = os.getenv('CORS_ALLOW_ALL_ORIGINS', 'False').lower() in ('true', '1', 't') + if not CORS_ALLOW_ALL_ORIGINS: + cors_allowed = os.getenv('CORS_ALLOWED_ORIGINS', '') + CORS_ALLOWED_ORIGINS = [origin.strip() for origin in cors_allowed.split(',') if origin.strip()] + + csrf_origins = os.getenv('CSRF_TRUSTED_ORIGINS', '') CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in csrf_origins.split(',') if origin.strip()] + # Security Headers for production + SECURE_BROWSER_XSS_FILTER = True + SECURE_CONTENT_TYPE_NOSNIFF = True + X_FRAME_OPTIONS = 'DENY' + # Reverse Proxy SSL / Host headers configuration (for Nginx / Docker reverse proxies) SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') USE_X_FORWARDED_HOST = True @@ -190,14 +197,6 @@ STORAGES = { # https://docs.djangoproject.com/en/6.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -# CORS & CSRF Settings -CORS_ALLOW_ALL_ORIGINS = os.getenv('CORS_ALLOW_ALL_ORIGINS', 'True').lower() in ('true', '1', 't') -if not CORS_ALLOW_ALL_ORIGINS: - CORS_ALLOWED_ORIGINS = [origin.strip() for origin in os.getenv('CORS_ALLOWED_ORIGINS', '').split(',') if origin.strip()] - -csrf_origins = os.getenv('CSRF_TRUSTED_ORIGINS', 'http://localhost,http://127.0.0.1,http://localhost:5173,http://localhost:8000') -CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in csrf_origins.split(',') if origin.strip()] - # Django REST Framework Settings REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ diff --git a/docker-compose.yml b/docker-compose.yml index f79d920..9909be9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,8 +7,6 @@ services: POSTGRES_DB: ${POSTGRES_DB:-divar_crawler} POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} - ports: - - "${POSTGRES_HOST_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: @@ -21,8 +19,6 @@ services: image: redis:7-alpine container_name: divar_redis restart: unless-stopped - ports: - - "${REDIS_HOST_PORT:-6379}:6379" healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 5s diff --git a/frontend/nginx.conf b/frontend/nginx.conf index d617d88..f3dccb2 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -9,6 +9,12 @@ server { gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + # Security Headers + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + # Frontend SPA routing location / { try_files $uri $uri/ /index.html;