fix: improve production security and cross-platform compatibility#958
fix: improve production security and cross-platform compatibility#958Ananya44444 wants to merge 7 commits intoalphaonelabs:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds early ENVIRONMENT handling and production-time SECRET_KEY validation in Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant App as Application
participant OS as Host/OS
participant Log as Logger
Client->>App: trigger action that may restart service
App->>App: determine platform (is_linux?)
alt Linux
App->>OS: resolve `/bin/systemctl` or other known paths
App->>OS: run `systemctl restart education-website` (with timeout)
OS-->>App: exit code or raise FileNotFoundError / TimeoutExpired
alt success (exit code 0)
App->>Log: log success
App-->>Client: continue flow
else failure (non-zero / exception)
App->>Log: log error, rc, and exception details
App-->>Client: continue flow (restart flagged failed)
end
else Non-Linux
App->>Log: log "restart skipped on non-Linux"
App-->>Client: continue flow without restart
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #957 by hardening production configuration and making the GitHub webhook deploy flow safer on non-Linux platforms, reducing crashes and preventing insecure production startups.
Changes:
- Add a production-only validation requiring
SECRET_KEYto be set via environment variable. - Move
ENVIRONMENTinitialization earlier to avoid use-before-definition during settings evaluation. - Gate
systemctl restartto Linux and add basic exception/timeout handling for the restart step.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
web/views.py |
Adds OS detection and exception handling around systemctl restart during webhook-driven deploys. |
web/settings.py |
Adds production validation for SECRET_KEY and reorders ENVIRONMENT definition to support that validation safely. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/settings.py`:
- Around line 53-57: In production, tighten SECRET_KEY validation: when
ENVIRONMENT == "production" read SECRET_KEY via env.str (avoid silently falling
back to the insecure default), trim and reject empty or whitespace-only values
and also explicitly reject the known insecure fallback string currently used; if
invalid, raise ValueError. Update the check around ENVIRONMENT, SECRET_KEY and
env.str to validate the trimmed value against "" and the insecure default
constant and raise an error so the app cannot start with an unsafe key.
In `@web/views.py`:
- Around line 1120-1127: The subprocess.run call currently uses check=False so
non-zero exit codes are ignored; update the logic around the subprocess.run(...)
that restarts the service to detect non-zero return codes (either set check=True
or inspect the CompletedProcess.returncode) and treat failures as deployment
errors by setting the ok flag to False and appending a descriptive message to
log_lines (include stdout/stderr from the CompletedProcess for diagnostics);
also keep existing except handlers for FileNotFoundError and TimeoutExpired but
ensure any non-zero returncode is logged and causes the handler to return a
failure response instead of marking deployment successful.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
web/settings.py (1)
53-61:⚠️ Potential issue | 🟠 MajorHarden production
SECRET_KEYvalidation to reject insecure default and normalize environment.At Line [51], Line [57], and Line [61], production safety can still be bypassed:
ENVIRONMENTis not normalized (e.g.,"Production"/" production "), and the known insecure fallback key is still accepted if explicitly provided.🔐 Proposed fix
+# Constants for reuse and lint compliance +INSECURE_DEFAULT_SECRET_KEY = "django-insecure-5kyff0s@l_##j3jawec5@b%!^^e(j7v)ouj4b7q6kru#o#a)o3" +PRODUCTION_SECRET_KEY_ERROR = "SECRET_KEY must be configured to a strong non-default value in production." + # Debug settings - must be defined before SECRET_KEY validation -ENVIRONMENT = env.str("ENVIRONMENT", default="development") +ENVIRONMENT = env.str("ENVIRONMENT", default="development").strip().lower() # Read and validate SECRET_KEY with proper whitespace handling raw_secret_key = env.str("SECRET_KEY", default="") SECRET_KEY = raw_secret_key.strip() if raw_secret_key else "" -if ENVIRONMENT == "production" and not SECRET_KEY: - raise ValueError("SECRET_KEY environment variable must be set in production") +if ENVIRONMENT == "production" and (not SECRET_KEY or SECRET_KEY == INSECURE_DEFAULT_SECRET_KEY): + raise ValueError(PRODUCTION_SECRET_KEY_ERROR) if not SECRET_KEY: - SECRET_KEY = "django-insecure-5kyff0s@l_##j3jawec5@b%!^^e(j7v)ouj4b7q6kru#o#a)o3" + SECRET_KEY = INSECURE_DEFAULT_SECRET_KEYAs per coding guidelines
**/*.py: Fix linting errors in code.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/settings.py` around lines 53 - 61, Normalize ENVIRONMENT and SECRET_KEY by stripping whitespace and using a case-insensitive check, and disallow the known insecure fallback value: trim raw_secret_key into SECRET_KEY (SECRET_KEY = raw_secret_key.strip() if raw_secret_key else ""), normalize ENVIRONMENT for checks (e.g., env_normalized = ENVIRONMENT.strip().lower()), then when env_normalized == "production" raise ValueError if not SECRET_KEY or if SECRET_KEY equals the insecure default string (compare exact value after strip), and finally avoid assigning the insecure default as a fallback when SECRET_KEY is empty so the insecure literal is never accepted even if provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@web/settings.py`:
- Around line 53-61: Normalize ENVIRONMENT and SECRET_KEY by stripping
whitespace and using a case-insensitive check, and disallow the known insecure
fallback value: trim raw_secret_key into SECRET_KEY (SECRET_KEY =
raw_secret_key.strip() if raw_secret_key else ""), normalize ENVIRONMENT for
checks (e.g., env_normalized = ENVIRONMENT.strip().lower()), then when
env_normalized == "production" raise ValueError if not SECRET_KEY or if
SECRET_KEY equals the insecure default string (compare exact value after strip),
and finally avoid assigning the insecure default as a fallback when SECRET_KEY
is empty so the insecure literal is never accepted even if provided.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
web/settings.py (1)
51-61:⚠️ Potential issue | 🟠 MajorHarden production
SECRET_KEYvalidation to reject unsafe defaults and normalizeENVIRONMENT.At Line [51]-Line [61], production can still start with the known insecure default
SECRET_KEY, andENVIRONMENTcasing/whitespace can bypass the production guard. This also keeps the TRY003 lint violation at Line [58].As per coding guidelines `**/*.py`: Fix linting errors in code.🔐 Proposed fix
+# Keep message as a named constant (Ruff TRY003) and centralize insecure fallback. +PRODUCTION_SECRET_KEY_ERROR = "SECRET_KEY must be configured to a strong non-default value in production." +INSECURE_DEFAULT_SECRET_KEY = "django-insecure-5kyff0s@l_##j3jawec5@b%!^^e(j7v)ouj4b7q6kru#o#a)o3" + # Debug settings - must be defined before SECRET_KEY validation -ENVIRONMENT = env.str("ENVIRONMENT", default="development") +ENVIRONMENT = env.str("ENVIRONMENT", default="development").strip().lower() # Read and validate SECRET_KEY with proper whitespace handling -raw_secret_key = env.str("SECRET_KEY", default="") -SECRET_KEY = raw_secret_key.strip() if raw_secret_key else "" +raw_secret_key = env.str("SECRET_KEY", default="").strip() +SECRET_KEY = raw_secret_key -if ENVIRONMENT == "production" and not SECRET_KEY: - raise ValueError("SECRET_KEY environment variable must be set in production") +if ENVIRONMENT == "production" and (not SECRET_KEY or SECRET_KEY == INSECURE_DEFAULT_SECRET_KEY): + raise ValueError(PRODUCTION_SECRET_KEY_ERROR) if not SECRET_KEY: - SECRET_KEY = "django-insecure-5kyff0s@l_##j3jawec5@b%!^^e(j7v)ouj4b7q6kru#o#a)o3" + SECRET_KEY = INSECURE_DEFAULT_SECRET_KEY🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/settings.py` around lines 51 - 61, Normalize ENVIRONMENT (strip and lower) and harden SECRET_KEY checks: trim raw_secret_key into SECRET_KEY, then if ENVIRONMENT == "production" ensure SECRET_KEY is non-empty and not equal to the known insecure default string (reject that value and raise ValueError); do not fall back to the insecure default in production. Update references to ENVIRONMENT, raw_secret_key, and SECRET_KEY accordingly so production cannot be bypassed by casing/whitespace and the insecure default is never accepted.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@web/settings.py`:
- Around line 51-61: Normalize ENVIRONMENT (strip and lower) and harden
SECRET_KEY checks: trim raw_secret_key into SECRET_KEY, then if ENVIRONMENT ==
"production" ensure SECRET_KEY is non-empty and not equal to the known insecure
default string (reject that value and raise ValueError); do not fall back to the
insecure default in production. Update references to ENVIRONMENT,
raw_secret_key, and SECRET_KEY accordingly so production cannot be bypassed by
casing/whitespace and the insecure default is never accepted.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/views.py`:
- Around line 1123-1138: Replace the unsafe shutil.which("systemctl") usage and
narrow PATH trust by validating systemctl_path against a whitelist of trusted
absolute locations (e.g., /bin/systemctl, /usr/bin/systemctl) and fallback to a
safe default only if the file exists and is executable before calling
subprocess.run (the call that restarts "education-website"); also broaden the
except clause around the subprocess.run invocation to catch OSError (or
Exception subclasses like PermissionError) instead of only FileNotFoundError and
subprocess.TimeoutExpired, and ensure you still append the error to log_lines
and set ok = False on failure.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/views.py`:
- Line 1133: The call to subprocess.run in the proc = subprocess.run(...)
expression is triggering Ruff S603; since this invocation uses trusted absolute
paths and constant args, add an inline Ruff noqa suppression on that expression
(e.g., append "# noqa: S603 - uses trusted absolute path and constant args" to
the line) so the linter is satisfied and include the brief rationale in the
comment; locate the subprocess.run usage in the web/views.py view and add the
inline suppression directly on that line.
Related issues
Fixes #957
Checklist
Changes Made
Security Improvements
SECRET_KEY Validation: Added production environment validation to prevent the use of insecure default SECRET_KEY
Variable Declaration Order: Fixed undefined variable error by moving ENVIRONMENT definition before its usage
2.Cross-Platform Compatibility
systemctl Restart Fix: Added platform detection to only attempt systemctl restart on Linux systems
Error Handling: Added proper exception handling and timeout for subprocess operations
Graceful Fallback: Non-Linux systems now log appropriate messages instead of crashing
Summary by CodeRabbit
Bug Fixes
Improvements