Security review: staff admin lockdown, unicode-safe login/phone/grade inputs, demo guest not upgradable, home cache not floodable
- accounts admin: phone/is_guest read-only for non-superusers, device_id filter lookups refused, auth.User/Group admin writable only by superusers - campaigns: delivery log needs view permission - phone/OTP/birth date: any Unicode digit normalised or rejected with 400; unknown gradeId is 400 - shared demo guest is never turned into a person's account by logging in - /api/home with unknown gradeId is no longer cached (LocMemCache flood reset throttle counters) - /api/progress/nodes: one query, huge unit is 400 - BazaarCredential token filter lookups refused Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,12 @@ class BazaarCredentialAdmin(admin.ModelAdmin):
|
||||
def connected(self, obj):
|
||||
return bool(obj.refresh_token)
|
||||
|
||||
def lookup_allowed(self, lookup, value, request=None):
|
||||
# فیلترِ querystring (?refresh_token__startswith=a) با شمردنِ نتیجه توکن را حرفبهحرف لو میدهد.
|
||||
if lookup.split('__')[0] in ('refresh_token', 'pending_state'):
|
||||
return False
|
||||
return super().lookup_allowed(lookup, value, request)
|
||||
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
BazaarCredential.objects.get_or_create(pk=1)
|
||||
return super().changelist_view(request, extra_context)
|
||||
|
||||
@@ -227,3 +227,21 @@ class DiscountDuringPaymentRequestTests(_Base):
|
||||
self.assertEqual(order.amount, self.pack.price // 2)
|
||||
self.assertEqual(requested, [self.pack.price, self.pack.price // 2])
|
||||
self.assertEqual(order.gateway_authority, 'A-2')
|
||||
|
||||
|
||||
class BazaarTokenNotGuessableByAdminFilterTests(TestCase):
|
||||
"""فیلترِ querystring روی refresh_token/pending_state توکنِ بازار را حرفبهحرف لو نمیدهد."""
|
||||
|
||||
def test_filter_is_refused(self):
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
from .models import BazaarCredential
|
||||
BazaarCredential.objects.update_or_create(pk=1, defaults={'refresh_token': 'TOPSECRET', 'pending_state': 'st8'})
|
||||
staff = get_user_model().objects.create_user('bz', 'bz@example.com', 'pw-for-tests-only', is_staff=True)
|
||||
staff.user_permissions.add(Permission.objects.get(content_type__app_label='payment', codename='view_bazaarcredential'))
|
||||
self.client.force_login(staff)
|
||||
self.assertEqual(self.client.get('/admin/payment/bazaarcredential/').status_code, 200)
|
||||
for lookup in ('refresh_token__startswith', 'pending_state__startswith', 'refresh_token__regex'):
|
||||
r = self.client.get('/admin/payment/bazaarcredential/', {lookup: 'T'})
|
||||
self.assertEqual(r.status_code, 400, lookup)
|
||||
|
||||
Reference in New Issue
Block a user