Skip to content

Commit 3939730

Browse files
committed
feat(security): Harden application with multiple security features
This commit implements several key security improvements: - Adds automatic session timeouts for inactive users. - Implements a dynamic, auto-generating SECRET_KEY to prevent exposure. - Enforces a stronger password policy for all user accounts.
1 parent 502196d commit 3939730

File tree

4 files changed

+46
-16
lines changed

4 files changed

+46
-16
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ dist/
2828
#*.spec
2929

3030
# Django Production / Build Artifacts
31-
staticfiles/
31+
staticfiles/
32+
33+
# Secret key file
34+
.secret_key_file

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ qrcode==8.2
1111
setuptools==80.9.0
1212
sqlparse==0.5.3
1313
waitress==3.0.2
14-
whitenoise==6.11.0
14+
whitenoise==6.11.0

sherlock/settings.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
"""
1414

1515
import socket
16+
import os
1617
from pathlib import Path
18+
from django.core.management.utils import get_random_secret_key
19+
from django.core.exceptions import ImproperlyConfigured
1720

1821
# Build paths inside the project like this: BASE_DIR / 'subdir'.
1922
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -22,11 +25,34 @@
2225
# Quick-start development settings - unsuitable for production
2326
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
2427

25-
# SECURITY WARNING: keep the secret key used in production secret!
26-
SECRET_KEY = 'django-insecure-gspzj&@$^rf!^erfwwj_2zm@thy@q-4sag4xip^8gdm5b-&e6s'
27-
28-
# SECURITY WARNING: don't run with debug turned on in production!
29-
DEBUG = False
28+
# DEBUG mode should be True for local development and False for production.
29+
30+
DEBUG = os.environ.get('DEBUG', 'False').lower() in ('true', '1', 't')
31+
32+
33+
try:
34+
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
35+
if SECRET_KEY is None:
36+
secret_key_file = BASE_DIR / '.secret_key_file'
37+
38+
if secret_key_file.exists():
39+
with open(secret_key_file, 'r') as f:
40+
SECRET_KEY = f.read().strip()
41+
else:
42+
print("INFO: No secret key file found. Generating a new one.")
43+
SECRET_KEY = get_random_secret_key()
44+
with open(secret_key_file, 'w') as f:
45+
f.write(SECRET_KEY)
46+
print(f"INFO: New secret key has been saved to {secret_key_file}")
47+
48+
if not SECRET_KEY:
49+
raise ValueError("Secret key is empty after trying all methods.")
50+
51+
except Exception as e:
52+
raise ImproperlyConfigured(
53+
f"CRITICAL ERROR: Could not find or create a SECRET_KEY. "
54+
f"Ensure the directory is writable. Original error: {e}"
55+
)
3056

3157
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
3258
if not DEBUG:
@@ -108,6 +134,9 @@
108134
},
109135
{
110136
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
137+
'OPTIONS': {
138+
'min_length': 8,
139+
}
111140
},
112141
{
113142
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
@@ -147,4 +176,9 @@
147176

148177
LOGIN_REDIRECT_URL = "/dashboard/"
149178

150-
LOGOUT_REDIRECT_URL = "/"
179+
LOGOUT_REDIRECT_URL = "/"
180+
181+
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
182+
183+
SESSION_COOKIE_AGE = 1800
184+

sherlock/urls.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
# sherlock-python/sherlock/urls.py
2-
32
"""
43
Main URL Configuration for the Sherlock project.
5-
6-
This file routes URLs at the project level. It handles:
7-
- The admin site.
8-
- The public-facing landing page (homepage).
9-
- The user authentication URLs (login, logout, signup).
10-
- Delegates all other application-specific URLs to the `inventory` app's urls.py.
4+
...
115
"""
12-
136
from django.contrib import admin
147
from django.urls import path, include
158
from inventory import views as inventory_views

0 commit comments

Comments
 (0)