Files
octopus/myproject/myproject/admin_access_middleware.py
Andrey Smakotin 0d3f07ad25 SECURITY: Ограничен доступ владельцев тенантов к админке Django
Исправлена критическая уязвимость безопасности, которая потенциально позволяла
владельцам тенантов получить доступ к админ-панели Django.

Изменения:
- Добавлены явные setdefault для is_staff=False и is_superuser=False в CustomUserManager.create_user()
- Добавлены явные флаги безопасности при создании владельца тенанта
- Добавлены явные флаги безопасности при создании пользователей через систему ролей
- Создан TenantAdminAccessMiddleware для защиты /admin/ на уровне middleware
- Создана миграция данных для исправления флагов у существующих пользователей

Реализована трёхуровневая защита (Defense-in-Depth):
1. Уровень модели: явные дефолты в create_user()
2. Уровень views: явные флаги при создании
3. Уровень middleware: runtime блокировка доступа

Файлы:
- accounts/models.py: явные флаги в create_user()
- tenants/admin.py: явные флаги при создании владельца
- user_roles/views.py: явные флаги при создании через роли
- myproject/admin_access_middleware.py: новый middleware
- myproject/settings.py: регистрация middleware
- accounts/migrations/0002_fix_owner_staff_flags.py: миграция данных

ВАЖНО: После применения этого коммита необходимо выполнить:
1. python manage.py migrate accounts
2. python manage.py migrate_schemas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:57:39 +03:00

45 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
Middleware для ограничения доступа к админке Django на поддоменах тенантов.
SECURITY: Этот middleware обеспечивает дополнительный слой защиты,
блокируя доступ владельцев тенантов к /admin/ даже если у них
случайно установлен is_staff=True.
Правила доступа:
- На tenant поддоменах (shop1.localhost): только is_superuser=True может входить в /admin/
- На public схеме (localhost): обычные правила Django (is_staff=True достаточно)
- Суперпользователи имеют доступ везде
"""
from django.http import HttpResponseForbidden
class TenantAdminAccessMiddleware:
"""
Дополнительный слой безопасности: блокирует доступ владельцев тенантов к /admin/
даже если у них случайно установлен is_staff=True.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Проверяем, это admin URL?
if request.path.startswith('/admin/'):
from django.db import connection
# Если мы в tenant схеме (не public)
if hasattr(connection, 'tenant') and connection.tenant:
# Проверяем: это не public схема?
if connection.tenant.schema_name != 'public':
# Если пользователь авторизован, но НЕ суперпользователь - блокируем
if request.user.is_authenticated and not request.user.is_superuser:
return HttpResponseForbidden(
"Доступ запрещен. Только системные администраторы могут "
"заходить в админ-панель на поддоменах тенантов. "
"Используйте панель управления тенанта."
)
response = self.get_response(request)
return response