# 🔍 АНАЛИЗ БЕЗОПАСНОСТИ РАЗДЕЛОВ С ОДИНАКОВЫМИ НАЗВАНИЯМИ В КАБИНЕТАХ
> **Дата:** 2025-09-19
> **Контекст:** 4 типа кабинетов (SELLER, FULFILLMENT, WHOLESALE, LOGIST) с одинаковыми названиями разделов
---
## 🚨 КЛЮЧЕВЫЕ ПРОБЛЕМЫ
### 1. ДУБЛИРОВАНИЕ МАРШРУТОВ БЕЗ ЗАЩИТЫ
**Текущая структура:**
```
ГЛОБАЛЬНЫЕ (БЕЗ ЗАЩИТЫ) КАБИНЕТНЫЕ (С ЗАЩИТОЙ)
/economics/ → /seller/economics/
/partners/ → /fulfillment/partners/
/messenger/ → /wholesale/messenger/
/market/ → /logistics/market/
```
**Проблема:** Глобальные маршруты доступны ВСЕМ авторизованным пользователям независимо от их роли.
### 2. WRAPPER-КОМПОНЕНТЫ С ДИНАМИЧЕСКИМ РЕНДЕРИНГОМ
**Пример: EconomicsPageWrapper**
```typescript
export function EconomicsPageWrapper() {
const { user } = useAuthContext()
// Роутинг по типу организации
switch (user.organization.type) {
case 'SELLER': return
case 'FULFILLMENT': return
case 'WHOLESALE': return
case 'LOGIST': return
}
}
```
**Риски:**
- ❌ Пользователь может получить доступ к чужим компонентам через глобальный маршрут `/economics/`
- ❌ Нет проверки прав доступа на уровне маршрута
- ❌ Логика безопасности размазана между маршрутами и компонентами
### 3. ОБЩИЕ КОМПОНЕНТЫ ДЛЯ ВСЕХ РОЛЕЙ
**Примеры проблемных компонентов:**
- `PartnersDashboard` - используется всеми ролями без дифференциации
- `MessengerDashboard` - единый компонент для всех типов организаций
- `MarketDashboard` - общий маркет для всех
**Что происходит внутри:**
```typescript
// MessengerDashboard использует GET_MY_COUNTERPARTIES
const counterparties = counterpartiesData?.myCounterparties || []
```
**Проблема:** Один компонент пытается обслужить разные бизнес-логики для разных типов организаций.
### 4. ИЗОЛЯЦИЯ ДАННЫХ НА УРОВНЕ API
**Хорошо:** API возвращает только `myCounterparties` - контрагентов текущей организации
**Плохо:** Но доступ к компонентам не ограничен по ролям на уровне UI
---
## ⚠️ КОНКРЕТНЫЕ РИСКИ
### СЦЕНАРИЙ АТАКИ 1: Обход защиты через глобальные маршруты
```
1. Пользователь SELLER авторизован
2. Заходит на /economics/ (вместо /seller/economics/)
3. EconomicsPageWrapper показывает SellerEconomicsPage
4. Но через манипуляции может получить доступ к данным других ролей
```
### СЦЕНАРИЙ АТАКИ 2: Доступ к функционалу других ролей
```
1. Логист заходит на /partners/
2. Видит PartnersDashboard со своими данными
3. Но интерфейс может содержать функции для других ролей
4. Потенциальная утечка бизнес-логики
```
### СЦЕНАРИЙ АТАКИ 3: Путаница в данных
```
1. Пользователь с несколькими ролями (если такое возможно)
2. Заходит на глобальный маршрут
3. Непредсказуемое поведение wrapper-компонентов
4. Отображение некорректных данных
```
---
## ✅ ПРАВИЛЬНОЕ РЕШЕНИЕ
### ВАРИАНТ 1: УДАЛИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ
**Преимущества:**
- ✅ Невозможно обойти защиту
- ✅ Четкая изоляция кабинетов
- ✅ Простота понимания структуры
**Недостатки:**
- ❌ Нужно обновить все ссылки в приложении
- ❌ Может сломать закладки пользователей
### ВАРИАНТ 2: ЗАЩИТИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ
```typescript
// /app/economics/page.tsx
export default function EconomicsPage() {
const { user } = useAuthContext()
// Автоматический редирект на правильный кабинет
if (user?.organization?.type) {
redirect(`/${user.organization.type.toLowerCase()}/economics/`)
}
return
Загрузка...
}
```
**Преимущества:**
- ✅ Обратная совместимость
- ✅ Автоматическая навигация
- ✅ Защита от неавторизованного доступа
### ВАРИАНТ 3: РОЛЬ-СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ
Вместо общих компонентов создать специфичные для каждой роли:
```
PartnersDashboard → SellerPartnersDashboard
→ FulfillmentPartnersDashboard
→ WholesalePartnersDashboard
→ LogistPartnersDashboard
```
**Преимущества:**
- ✅ Четкая бизнес-логика для каждой роли
- ✅ Невозможно показать чужой функционал
- ✅ Легче тестировать и поддерживать
---
## 🛡️ РЕКОМЕНДУЕМАЯ АРХИТЕКТУРА
### 1. СТРУКТУРА МАРШРУТОВ
```
/seller/
├── home/ (✅ protected with useRoleGuard)
├── economics/ (✅ protected with useRoleGuard)
├── partners/ (✅ protected with useRoleGuard)
└── messenger/ (✅ protected with useRoleGuard)
/fulfillment/
├── home/ (✅ protected with useRoleGuard)
├── economics/ (✅ protected with useRoleGuard)
├── partners/ (✅ protected with useRoleGuard)
└── messenger/ (✅ protected with useRoleGuard)
❌ УДАЛИТЬ ИЛИ ЗАЩИТИТЬ:
/economics/
/partners/
/messenger/
/market/
```
### 2. ЗАЩИТА НА УРОВНЕ LAYOUT
```typescript
// /app/seller/layout.tsx
export default function SellerLayout({ children }) {
useRoleGuard('SELLER') // Защита всего кабинета
return (
{children}
)
}
```
### 3. СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ
```typescript
// Вместо общего PartnersDashboard
export function SellerPartnersDashboard() {
// Логика только для селлеров
}
export function FulfillmentPartnersDashboard() {
// Логика только для фулфилмента
}
```
---
## 📋 ПЛАН ДЕЙСТВИЙ
### ЭТАП 1: НЕМЕДЛЕННО (Сегодня)
1. **Добавить редиректы в глобальные страницы:**
```typescript
// /app/economics/page.tsx
if (user?.organization?.type) {
redirect(`/${user.organization.type.toLowerCase()}/economics/`)
}
```
2. **Добавить useRoleGuard в wrapper-компоненты:**
```typescript
export function EconomicsPageWrapper() {
// Добавить проверку перед switch
if (!user?.organization?.type) {
redirect('/login')
}
}
```
### ЭТАП 2: КРАТКОСРОЧНО (1-3 дня)
1. **Создать layout-защиту для каждого кабинета**
2. **Провести аудит всех ссылок на глобальные маршруты**
3. **Создать карту редиректов для обратной совместимости**
### ЭТАП 3: ДОЛГОСРОЧНО (1-2 недели)
1. **Разделить общие компоненты на роль-специфичные**
2. **Удалить глобальные маршруты после миграции**
3. **Создать автоматические тесты для проверки доступа**
---
## 🎯 ИТОГ
**Текущая ситуация:** Опасная архитектура с возможностью обхода защиты через глобальные маршруты.
**Решение:** Либо полностью удалить глобальные маршруты, либо добавить автоматические редиректы на роль-специфичные страницы.
**Приоритет:** 🔴 КРИТИЧЕСКИЙ - исправить в течение 1-2 дней