Server hardening: nginx origin locked to ArvanCloud + CSP, demo logins removed, docs
- ops/nginx/: the two nginx sites as they now run on 249. Only ArvanCloud edges reach the app (direct hits on the IP get 403, so Arvan's DDoS/WAF can't be skipped); the frontend gets CSP (own sources only, the one inline script by hash), X-Frame-Options, nosniff, Referrer-Policy, Permissions-Policy, HSTS; API body limit 100M -> 20M plus HSTS. Checked from outside and in Chrome (all tabs and an island quiz, logged in): no CSP errors. - Demo accounts (users 11-15, 25) and TEST_LOGIN_PHONES removed from the server; the health warning for fixed-code logins now has a test and says how to test instead (an OTPCode made in the admin). - SMS daily cap on the server is 2000 (launch of ~600 users). - CLAUDE.md: never run tests with --parallel on macOS, always --noinput (both hang forever without an error). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -316,8 +316,8 @@ def _warnings() -> list[str]:
|
||||
# تعداد عمداً گفته نمیشود: این صفحه عمومی است و «۷ حسابِ کدِ ثابت» برای
|
||||
# مهاجم یعنی هدفِ مشخص برای حدس زدن.
|
||||
out.append(
|
||||
'شمارههای تستِ ورود با کدِ ثابت فعالاند (TEST_LOGIN_PHONES). '
|
||||
'برای توسعه لازم است؛ پیش از تحویلِ نهایی به کاربرانِ واقعی حذفشان کنید.'
|
||||
'شمارههای تستِ ورود با کدِ ثابت فعالاند (TEST_LOGIN_PHONES). روی سرور باید خالی باشد: '
|
||||
'هر کس کد را دیده باشد وارد میشود. برای آزمون یک OTPCode در پنلِ ادمین بسازید.'
|
||||
)
|
||||
if not settings.DEBUG and settings.SECRET_KEY.startswith('django-insecure'):
|
||||
# بزرگترین ریسکِ باز (docs/security-before-production.md): این کلید در گیت است و هر
|
||||
|
||||
20
config/tests_no_fixed_logins.py
Normal file
20
config/tests_no_fixed_logins.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""
|
||||
روی سرور هیچ شمارهای با کدِ ورودِ ثابت نباید باشد (حسابهای دمو ۲۰۲۶-۱۰-۱۳ پاک شدند). اگر کسی
|
||||
TEST_LOGIN_PHONES را دوباره پر کند، /api/health (با کلید) باید بگوید، نه بیصدا بپذیرد.
|
||||
"""
|
||||
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
|
||||
@override_settings(INTERNAL_SERVICE_KEY='k')
|
||||
class FixedCodeLoginsAreFlaggedTests(TestCase):
|
||||
def _warnings(self):
|
||||
return self.client.get('/api/health', HTTP_X_INTERNAL_KEY='k').json()['warnings']
|
||||
|
||||
@override_settings(TEST_LOGIN_PHONES={'09120000001': '834512'})
|
||||
def test_a_fixed_code_phone_raises_a_warning(self):
|
||||
self.assertTrue(any('TEST_LOGIN_PHONES' in w for w in self._warnings()))
|
||||
|
||||
@override_settings(TEST_LOGIN_PHONES={})
|
||||
def test_empty_list_is_quiet(self):
|
||||
self.assertFalse(any('TEST_LOGIN_PHONES' in w for w in self._warnings()))
|
||||
Reference in New Issue
Block a user