Перейти до змісту

Zero Trust Architecture — Архітектура Нульової Довіри

"Never trust, always verify" — жодного користувача, пристрою чи мережі не вважати безпечним лише тому, що він "всередині" системи.

Аналогія: Навіть якщо співробітник щодня проходить через турнікет в офіс, кожного разу коли він відкриває двері до серверної кімнати — система знову перевіряє його картку. Це Zero Trust.


Що таке Zero Trust?

Архітектура нульової довіри (Zero Trust Architecture) — це філософія та шаблон проєктування безпеки, яка відмовляється від поняття "неявної довіри" на основі: - Перебування користувача чи пристрою у внутрішній мережі - Попередньої успішної автентифікації

Принцип: "ніколи не довіряй, завжди перевіряй" — явне підтвердження особи та дозволів для кожного запиту до системи.

Важливо: Архітектура Zero Trust — це не продукт, який можна "купити і встановити". Це підхід до проєктування системи, де кожен компонент за замовчуванням не довіряє іншим.

6 ключових принципів Zero Trust

1. Безперервна перевірка (Continuous Verification)

Проста наявність токена чи факту входу в систему не означає, що користувачу можна довіряти постійно. Кожна привілейована дія має проходити перевірку. Сліпа довіра до токена — серйозна вразливість.

2. Принцип найменших привілеїв (Least Privilege)

Кожен користувач, пристрій або скрипт отримує доступ лише до того, що йому абсолютно необхідно. Якщо менеджеру потрібен доступ до меню кафетерію — він не повинен бачити корпоративну базу даних клієнтів.

3. Суворе управління ідентифікацією (IAM)

Система має чітко знати ВСІХ: людей, пристрої, програми. Тактики: - MFA (Багатофакторна автентифікація): пароль + смартфон + біометрія - SSO (Single Sign-On): один надійний провайдер автентифікації

4. Мікросегментація (Micro-segmentation)

Замість загального доступу до всього середовища — суворі правила для кожного відділу, юзера, пристрою. Якщо зловмисник отримає доступ до одного ресурсу — він не може автоматично дістатися до інших.

5. Постійний моніторинг (Continuous Monitoring)

Реєструй і перевіряй весь мережевий трафік. Стеж за всіма сутностями — чи не виходять вони за межі своїх повноважень.

6. Захист на рівні фреймворку

Правильне використання вбудованих механізмів безпеки (CSRF-захист в Django, параметризовані запити ORM) — частина Zero Trust підходу.


1. Безперервна авторизація (Continuous Verification)

Zero Trust вимагає перевірки кожного виклику привілейованої функції, а не лише одноразового входу.

Наявність дійсного токена не означає безумовної довіри — статус користувача міг змінитися.

Django реалізація:

# НЕ достатньо — перевірка тільки при вході:
@login_required
def edit_note(request, pk):
    note = get_object_or_404(Note, pk=pk)  # IDOR вразливість!

# Zero Trust — перевірка на кожному запиті:
@login_required
@permission_required('notes_app.change_note')
def edit_note(request, pk):
    note = get_object_or_404(Note, pk=pk, user=request.user)  # ← явна перевірка


2. Контроль доступу на рівні об'єктів (Object-Level Permissions)

Глобальних дозволів недостатньо для Zero Trust. Необхідна перевірка власності конкретного об'єкта.

Проблема IDOR:

# Аліса знає URL: /notes/42/edit/
# Нотатка 42 належить Бобу. Без перевірки:
note = get_object_or_404(Note, pk=42)   # Аліса отримує доступ!

# Zero Trust — перевірка власника:
note = get_object_or_404(Note, pk=42, user=request.user)  # 404 для Аліси

Для групового доступу:

from django.core.exceptions import PermissionDenied
from django.db.models import Q

def check_note_access(note, user):
    user_groups = user.groups.all()
    has_access = (
        note.user == user or                          # власник
        (note.group and note.group in user_groups)    # член групи
    )
    if not has_access:
        raise PermissionDenied

Рекомендація: Використовуй UUID замість auto-incrementing integer PK для важливих об'єктів — неможливо вгадати наступний ID.


3. Сувора валідація даних (Zero Trust Input)

Жодному вводу з боку клієнта не можна довіряти неявно.

# НЕ достатньо — тільки фронтенд-валідація:
# <input type="number" min="1" max="100">  ← атакер обходить

# Zero Trust — серверна валідація в моделі:
class Note(models.Model):
    priority = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(4)]
    )

    def clean(self):
        if self.priority not in [1, 2, 3, 4]:
            raise ValidationError("Недійсний пріоритет")

# або в формі:
class NoteForm(forms.ModelForm):
    def clean_title(self):
        title = self.cleaned_data['title'].strip()
        if len(title) < 3:
            raise forms.ValidationError("Заголовок занадто короткий.")
        return title

4. Багатофакторна автентифікація (MFA)

Zero Trust значною мірою спирається на MFA — звичайні паролі легко компрометуються.

# Встановлення:
pip install django-two-factor-auth

# settings.py:
INSTALLED_APPS += ['two_factor']
LOGIN_URL = 'two_factor:login'
TWO_FACTOR_PATCH_ADMIN = True

# urls.py:
from two_factor.urls import urlpatterns as tf_urls
urlpatterns = [path('', include(tf_urls)), ...]

Фактори: - Знання — пароль - Посідання — OTP-код (Google Authenticator, SMS) - Притаманне — біометрія (FaceID, відбиток)


5. Мікросегментація та Моніторинг

Zero Trust використовує постійний моніторинг для виявлення аномалій.

# settings.py — розширений security logging:
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'security_file': {
            'class': 'logging.FileHandler',
            'filename': 'logs/security.log',
        },
        'console': {'class': 'logging.StreamHandler'},
    },
    'loggers': {
        'django.security': {
            'handlers': ['security_file', 'console'],
            'level': 'WARNING',
            'propagate': False,
        },
    },
}

# views.py — логування привілейованих дій:
import logging
security_log = logging.getLogger('django.security')

@login_required
def note_delete(request, pk):
    note = get_object_or_404(Note, pk=pk, user=request.user)
    if request.method == 'POST':
        security_log.warning(
            f"User {request.user.pk} deleted note {pk}",
            extra={'request': request}
        )
        note.delete()

6. Continuous Verification — Безперервна перевірка (Деталі)

Continuous Verification — ключовий компонент Zero Trust. Простого факту попередньої автентифікації недостатньо. Система повинна перевіряти кожен виклик привілейованої функції.

6.1 Централізована перевірка доступу

Щоб уникнути ручного додавання перевірок у кожній функції — централізуй логіку:

# DRF: кастомний клас дозволів
from rest_framework.permissions import BasePermission

class IsOwner(BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.user == request.user

# Глобально у settings.py:
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ['notes_app.permissions.IsOwner'],
}

# Для звичайних views — використовуй міксини:
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin

class NoteUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    permission_required = 'notes_app.change_note'
    # Авторизація виконується ДО бізнес-логіки

6.2 Middleware як глобальний щит

Кастомний Middleware, що блокує всі незахищені endpoints:

# notes_app/middleware.py
class RequireAuthMiddleware:
    PUBLIC_URLS = ['/accounts/login/', '/accounts/register/', '/']

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.path not in self.PUBLIC_URLS:
            if not request.user.is_authenticated:
                from django.shortcuts import redirect
                return redirect('login')
        return self.get_response(request)

6.3 Валідація стану JWT-токена (для API)

Проблема JWT: токен дійсний до закінчення терміну, навіть якщо юзера заблоковано.

# Рішення: blacklist + Redis перевірка при кожному запиті
# pip install djangorestframework-simplejwt[crypto]

# settings.py:
INSTALLED_APPS += ['rest_framework_simplejwt.token_blacklist']

# При logout — додаємо токен у blacklist:
from rest_framework_simplejwt.tokens import RefreshToken

def logout_api(request):
    refresh_token = request.data.get('refresh')
    token = RefreshToken(refresh_token)
    token.blacklist()   # Redis: занести в список відкликаних

6.4 Перевірка на рівні об'єктів (IDOR Prevention)

# ПОГАНО — перевіряємо лише "чи є роль":
@login_required
def edit_note(request, pk):
    note = get_object_or_404(Note, pk=pk)   # IDOR! Alice редагує нотатку Bob-а

# ДОБРЕ — перевіряємо право на конкретний об'єкт:
@login_required
def edit_note(request, pk):
    note = get_object_or_404(Note, pk=pk)
    if note.user != request.user:
        raise PermissionDenied   # Continuous verification!
    # ...

6.5 Захист від Mass Assignment

# Атака: POST {'is_admin': True} → зміна ролі

# НЕ безпечно:
class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = '__all__'  # ← атакер може надіслати is_superuser=True!

# БЕЗПЕЧНО — явна whitelist полів:
class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['display_name', 'bio', 'timezone']  # ← тільки ті що дозволено

Zero Trust у нашому проєкті

Принцип ZT Реалізація в crispy_notes_chat_app
Continuous Verification @login_required на кожному view
Object-Level Permissions get_object_or_404(Note, pk=pk, user=request.user)
Input Validation NoteForm.clean_*(), MinValueValidator в моделях
Least Privilege user.groups.all() фільтрація для Group sharing
Audit Logging (для розширення) django.security logger
MFA (для розширення) django-two-factor-auth