Skip to content

Commit 756a75d

Browse files
authored
Merge branch 'main' into main
2 parents 2d78331 + 57c8863 commit 756a75d

23 files changed

Lines changed: 32278 additions & 27950 deletions

File tree

core/middleware.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
from django.urls import reverse
88
from django.conf import settings
99
from django.middleware.locale import LocaleMiddleware
10+
from django.http import HttpResponseNotFound
1011
from django.utils import translation
12+
from django.shortcuts import render
13+
1114
logger = logging.getLogger('admin_logout_logger')
15+
Honeypot_logger = logging.getLogger("honeypot_logger")
1216

1317
class AutoLogoutMiddleware(MiddlewareMixin):
1418
"""
@@ -149,16 +153,46 @@ def process_request(self, request):
149153
request.LANGUAGE_CODE = translation.get_language()
150154

151155

156+
152157
class SecurityHeadersMiddleware:
153158
"""
154159
Middleware to add security headers that help mitigate vulnerabilities
155160
in third-party JavaScript libraries and prevent common attacks.
156161
"""
157162

163+
# Honeypot Middleware
164+
165+
class HoneypotMiddleware:
166+
"""
167+
Middleware to detect and log requests to honeypot (fake) paths.
168+
Normal users will never visit these paths.
169+
If triggered, log the attempt and return a 404 page.
170+
"""
171+
172+
# Fake paths attackers often try
173+
HONEYPOT_PATHS = [
174+
"/admin-secret",
175+
"/Main-admin",
176+
"/superuser",
177+
"/dashboard-old",
178+
"/backup.sql",
179+
"/db.dump",
180+
"/config.php",
181+
"/env.bak",
182+
"/administration-login",
183+
"/auth-test",
184+
"/secure-login",
185+
"/test-page",
186+
"/debug/",
187+
"/old-site/"
188+
]
189+
190+
158191
def __init__(self, get_response):
159192
self.get_response = get_response
160193

161194
def __call__(self, request):
195+
162196
response = self.get_response(request)
163197

164198
# Content Security Policy to prevent XSS and code injection
@@ -197,4 +231,30 @@ def __call__(self, request):
197231
'gyroscope=()'
198232
)
199233

200-
return response
234+
return response
235+
236+
path = request.path
237+
238+
# Check if the request path is in honeypot traps
239+
if path in self.HONEYPOT_PATHS:
240+
ip = self.get_client_ip(request)
241+
ua = request.META.get("HTTP_USER_AGENT", "unknown")
242+
243+
Honeypot_logger.warning(
244+
f"HONEYPOT TRIGGERED: Path={path}, IP={ip}, User-Agent={ua}"
245+
)
246+
247+
# Return fake 404 so attacker doesn't know it’s a trap
248+
return render(request, "404.html", status=404)
249+
250+
# Otherwise continue normally
251+
return self.get_response(request)
252+
253+
def get_client_ip(self, request):
254+
"""Extract client IP address from headers"""
255+
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
256+
if x_forwarded_for:
257+
ip = x_forwarded_for.split(",")[0]
258+
else:
259+
ip = request.META.get("REMOTE_ADDR", "")
260+
return ip

core/settings.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
# 'core.middleware.AutoLogoutMiddleware', # TEMPORARILY DISABLED - causing OAuth redirect issues
157157

158158
"django_user_agents.middleware.UserAgentMiddleware",
159+
"core.middleware.HoneypotMiddleware",
159160
# "core.middleware.LogRequestMiddleware", # TEMPORARILY DISABLED - causing OAuth redirect issues
160161
# "home.views.force_oauth_redirect_middleware", # DISABLED - causing redirect loops
161162

@@ -529,6 +530,11 @@
529530
'level': 'INFO',
530531
'propagate': False,
531532
},
533+
"honeypot_logger": {
534+
"handlers": ["console"],
535+
"level": "WARNING",
536+
"propagate": False,
537+
},
532538
},
533539
}
534540

core/urls.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
1. Import the include() function: from django.urls import include, path
1414
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1515
"""
16+
from django.conf import settings
17+
from django.conf.urls.static import static
1618
from django.contrib import admin
1719
from django.conf.urls.i18n import i18n_patterns
1820
from django.urls import include, path
@@ -115,10 +117,18 @@
115117
path("api/tip/today/", views.tip_today, name="tip_today"),
116118

117119

120+
118121
]
119122

120123

121124

122125
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static('/static/assets/', document_root=settings.BASE_DIR / 'custom_static/assets')
123126

124127

128+
129+
]
130+
131+
# Static & media files (served by Django in dev)
132+
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
133+
urlpatterns += static('/static/assets/', document_root=settings.BASE_DIR / 'custom_static/assets')
134+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0 commit comments

Comments
 (0)