Files
docs.a2v.space/public/guides/leadera-audit/index.html
T

494 lines
25 KiB
HTML
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.
<!DOCTYPE html>
<html lang="ru-ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Аудит Leadera — docs.a2v.space</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../css/custom.css">
</head>
<body>
<header class="site-header">
<nav class="navbar navbar-expand-lg">
<div class="container-fluid">
<a class="navbar-brand" href="../../">docs.a2v.space</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarMain" aria-controls="navbarMain" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarMain">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="../../diary/">Дневник</a>
</li>
<li class="nav-item">
<a class="nav-link" href="../../kb/">База знаний</a>
</li>
<li class="nav-item">
<a class="nav-link" href="../../plans/">Планы</a>
</li>
<li class="nav-item">
<a class="nav-link" href="../../guides/">Инструкции</a>
</li>
<li class="nav-item">
<a class="nav-link" href="../../creds/">Креды</a>
</li>
</ul>
<form class="d-flex search-form" role="search">
<input class="form-control me-2" type="search" placeholder="Поиск..." aria-label="Search" id="search-input">
<button class="btn btn-outline-light" type="submit">Найти</button>
</form>
</div>
<button class="btn btn-outline-light d-md-none ms-2" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar" aria-expanded="false" aria-controls="sidebar">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
</svg>
</button>
</div>
</nav>
<div id="search-results" class="search-results" style="display: none;">
<div class="search-results-content">
<button type="button" class="btn-close float-end" id="close-search"></button>
<h5>Результаты поиска</h5>
<ul id="results-list"></ul>
</div>
</div>
</header>
<div class="container-fluid">
<div class="row">
<aside class="col-md-3 col-lg-2 d-md-block sidebar collapse" id="sidebar">
<div class="sidebar-content">
<h6>Фильтры</h6>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" href="../../guides/">Все инструкции</a></li>
</ul>
<h6 class="mt-3">Теги</h6>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" href="../../tags/audit/">audit</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/leadera/">leadera</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/security/">security</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/ux/">ux</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/ssh/">ssh</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/tunnel/">tunnel</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/vps/">vps</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/reverse-proxy/">reverse-proxy</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/nginx/">nginx</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/devops/">devops</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/openclaw/">openclaw</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/opencode/">opencode</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/angular/">angular</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/go/">go</a></li>
<li class="nav-item"><a class="nav-link" href="../../tags/docker/">docker</a></li>
</ul>
</div>
</aside>
<main class="col-md-9 col-lg-10 main-content">
<div class="article-content">
<h1>Аудит Leadera</h1>
<div class="tags mb-3">
<a href="../../tags/audit/" class="tag">audit</a>
<a href="../../tags/leadera/" class="tag">leadera</a>
<a href="../../tags/security/" class="tag">security</a>
<a href="../../tags/ux/" class="tag">ux</a>
</div>
<h2 id="обзор-проекта">Обзор проекта</h2>
<p>Leadera — это SaaS-платформа для управления IT-ландшафтом с поддержкой диаграмм Ганта. Проект состоит из двух основных компонентов:</p>
<p><strong>Стек технологий:</strong></p>
<ul>
<li><strong>Бэкенд:</strong> Go 1.21+, GIN framework, PostgreSQL 16+, pgx v5 + sqlx</li>
<li><strong>Фронтенд:</strong> Angular (версия не указана), HttpClient</li>
<li><strong>Инфраструктура:</strong> Docker, PM2, Hugo для документации</li>
</ul>
<p><strong>Архитектура:</strong></p>
<ul>
<li>Clean Architecture с разделением на слои (handlers, service, repository)</li>
<li>RESTful API с использованием JWT для аутентификации</li>
<li>Управление правами доступа через RBAC (Role-Based Access Control)</li>
<li>Поддержка пространств (spaces) как основной изоляции данных</li>
<li>PostgreSQL с миграциями через golang-migrate</li>
</ul>
<p><strong>Основные сущности:</strong></p>
<ul>
<li>Пользователи (Users)</li>
<li>Пространства (Spaces)</li>
<li>Диаграммы Ганта (Gantt Charts)</li>
<li>Секции диаграмм (Gantt Sections)</li>
<li>Задачи (Gantt Tasks)</li>
</ul>
<h2 id="бекенд--найденные-проблемы">Бекенд — найденные проблемы</h2>
<h3 id="1-критичные-уязвимости">1. Критичные уязвимости</h3>
<h4 id="11-отсутствие-валидации-ввода-данных">1.1 Отсутствие валидации ввода данных</h4>
<p><strong>Критичность:</strong> Critical<br>
<strong>Файл:</strong> internal/dto/auth/login_request.go:5-6<br>
<strong>Описание:</strong> В DTO используются базовые теги валидации (<code>binding:&quot;required,email&quot;</code>), но они не применяются в handlers. В handlers используется только <code>c.ShouldBindJSON()</code> без дополнительной валидации.<br>
<strong>Рекомендация:</strong> Добавить ручную валидацию в handlers или использовать специализированную библиотеку для валидации (validator/v10).</p>
<h4 id="12-риск-sql-инъекций">1.2 Риск SQL-инъекций</h4>
<p><strong>Критичность:</strong> High<br>
<strong>Файл:</strong> internal/repository/space_repository.go:68-73<br>
<strong>Описание:</strong> В методе <code>GetBySlug</code> используется параметризованный запрос, что хорошо. Однако нет проверки валидности slug перед запросом.<br>
<strong>Рекомендация:</strong> Добавить регулярную валидацию slug для предотвращения SQL инъекций и других атак.</p>
<h4 id="13-небезопасное-хранение-секретов">1.3 Небезопасное хранение секретов</h4>
<p><strong>Критичность:</strong> High<br>
<strong>Файл:</strong> internal/config/config.go:13-15<br>
<strong>Описание:</strong> JWT секрет хранится в структуре Config и может быть логирован. Нет отладочных данных в логах.<br>
<strong>Рекомендация:</strong> Исключить JWT секрет из логов, добавить маскирование секретов в конфигурации.</p>
<h4 id="14-отсутствие-ограничений-на-частоту-запросов">1.4 Отсутствие ограничений на частоту запросов</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Описание:</strong> Нет защиты от brute force атак на аутентификацию.<br>
<strong>Рекомендация:</strong> Реализовать rate limiting для эндпоинтов аутентификации.</p>
<h3 id="2-проблемы-безопасности">2. Проблемы безопасности</h3>
<h4 id="21-xss-валидация">2.1 XSS валидация</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> internal/handlers/space_handler.go<br>
<strong>Описание:</strong> Нет очистки пользовательского ввода перед сохранением в базу данных.<br>
<strong>Рекомендация:</strong> Добавить HTML экранирование пользовательских данных.</p>
<h4 id="22-отсутствие-csrf-защиты">2.2 Отсутствие CSRF защиты</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> internal/middleware/cors_middleware.go<br>
<strong>Описание:</strong> Нет CSRF токенов или других механизмов защиты.<br>
<strong>Рекомендация:</strong> Реализовать CSRF защиту для изменяющих операций.</p>
<h4 id="23-небезопасная-обработка-ошибок">2.3 Небезопасная обработка ошибок</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong>/internal/utils/response.go<br>
<strong>Описание:</strong> Возвращаемые ошибки могут содержать внутренние детали реализации.<br>
<strong>Рекомендация:</strong> Стандартизировать формат ошибок, скрывать внутренние детали от пользователей.</p>
<h3 id="3-архитектурные-проблемы">3. Архитектурные проблемы</h3>
<h4 id="31-отсутствие-тестов">3.1 Отсутствие тестов</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> Отсутствие тестовых файлов<br>
<strong>Описание:</strong> Найден только один тестовый helper файл, нет unit и интеграционных тестов.<br>
<strong>Рекомендация:</strong> Добавить покрытие тестами, особенно для критичных бизнес-логик.</p>
<h4 id="32-отсутствие-индексов-в-бд">3.2 Отсутствие индексов в БД</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> migrations/000001_create_users_table.up.sql:15-16<br>
<strong>Описание:</strong> Есть базовые индексы, но отсутствуют составные индексы для сложных запросов.<br>
<strong>Рекомендация:</strong> Добавить индексы для часто используемых запросов.</p>
<h4 id="33-плохая-обработка-пагинации">3.3 Плохая обработка пагинации</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> internal/repository/space_repository.go:39-45<br>
<strong>Описание:</strong> Пагинация реализована, но нет валидации параметров page и per_page.<br>
<strong>Рекомендация:</strong> Добавить валидацию и ограничение на максимальное количество элементов на страницу.</p>
<h3 id="4-проблемы-конфигурации">4. Проблемы конфигурации</h3>
<h4 id="41-слабые-настройки-по-умолчанию">4.1 Слабые настройки по умолчанию</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> .env.example<br>
<strong>Описание:</strong> JWT секрет по умолчанию слишком короткий, пароль БД предсказуем.<br>
<strong>Рекомендация:</strong> Увеличить длину JWT секрета до 64+ символов, сгенерировать сложные пароли по умолчанию.</p>
<h4 id="42-небезопасные-настройки-cors">4.2 Небезопасные настройки CORS</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> .env.example<br>
<strong>Описание:</strong> CORS разрешает любые origin в development.<br>
<strong>Рекомендация:</strong> В продакшене использовать конкретные домены.</p>
<h2 id="фронтенд--найденные-проблемы">Фронтенд — найденные проблемы</h2>
<h3 id="1-критичные-уязвимости-1">1. Критичные уязвимости</h3>
<h4 id="11-небезопасное-хранение-токенов">1.1 Небезопасное хранение токенов</h4>
<p><strong>Критичность:</strong> Critical<br>
<strong>Файл:</strong> src/app/core/auth/auth.service.ts:19-21<br>
<strong>Описание:</strong> Access токены хранятся в localStorage, что делает их уязвимыми для XSS атак.<br>
<strong>Рекомендация:</strong> Перенести токены в httpOnly cookie или secure storage.</p>
<h4 id="12-отсутствие-валидации-на-клиенте">1.2 Отсутствие валидации на клиенте</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Файл:</strong> src/app/core/auth/auth.models.ts<br>
<strong>Описание:</strong> Нет валидации email, пароля и других полей на клиенте.<br>
<strong>Рекомендация:</strong> Добавить клиентскую валидацию форм перед отправкой запросов.</p>
<h3 id="2-проблемы-безопасности-1">2. Проблемы безопасности</h3>
<h4 id="21-отсутствие-csp">2.1 Отсутствие CSP</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Описание:</strong> Нет Content Security Policy для защиты от XSS и других атак.<br>
<strong>Рекомендация:</strong> Добавить заголовки CSP с разрешенными источниками.</p>
<h4 id="22-нет-ограничений-на-длину-ввода">2.2 Нет ограничений на длину ввода</h4>
<p><strong>Критичность:</strong> Medium<br>
<strong>Описание:</strong> Нет ограничения максимальной длины вводимых данных.<br>
<strong>Рекомендация:</strong> Добавить maxlength атрибуты к input полям.</p>
<h3 id="3-ux-проблемы">3. UX проблемы</h3>
<h4 id="31-нет-индикации-загрузки">3.1 Нет индикации загрузки</h4>
<p><strong>Критичность:</strong> Low<br>
<strong>Файл:</strong> src/app/core/auth/auth.service.ts:45-47<br>
<strong>Описание:</strong> Для некоторых операций нет индикации загрузки.<br>
<strong>Рекомендация:</strong> Добавить skeleton loaders или spinners для всех асинхронных операций.</p>
<h4 id="32-плохая-обработка-ошибок">3.2 Плохая обработка ошибок</h4>
<p><strong>Критичность:</strong> Low<br>
<strong>Файл:</strong> src/app/core/auth/auth.interceptor.ts:28-32<br>
<strong>Описание:</strong> Обработка ошибок 401 не всегда приводит к корректному перенаправлению.<br>
<strong>Рекомендация:</strong> Стандартизовать обработку ошибок и отображение пользователю.</p>
<h2 id="безопасность">Безопасность</h2>
<h3 id="текущие-меры-безопасности">Текущие меры безопасности</h3>
<ul>
<li>Использование JWT токенов для аутентификации</li>
<li>Параметризованные SQL запросы (защита от SQL инъекций)</li>
<li>CORS настройка</li>
<li>RBAC система через пространства и роли</li>
<li>Пароли хранятся в виде хешей</li>
<li>Refresh токены для управления сессиями</li>
</ul>
<h3 id="отсутствующие-меры">Отсутствующие меры</h3>
<ul>
<li>Rate limiting</li>
<li>CSRF protection</li>
<li>Content Security Policy</li>
<li>Input validation middleware</li>
<li>SQL injection protection for dynamic queries</li>
<li>XSS protection</li>
<li>Secure cookie storage</li>
<li>Brute force protection</li>
</ul>
<h3 id="рекомендации-по-безопасности">Рекомендации по безопасности</h3>
<ol>
<li>Реализовать rate limiting для аутентификации</li>
<li>Добавить CSRF защиту</li>
<li>Перенести JWT токены в httpOnly cookies</li>
<li>Реализовать систему мониторинга и оповещений о подозрительной активности</li>
<li>Добавить валидацию на всех уровнях (фронтенд, бэкенд, БД)</li>
<li>Реализовать ротацию секретов</li>
<li>Добавить тесты безопасности</li>
</ol>
<h2 id="ux-улучшения">UX улучшения</h2>
<h3 id="фронтенд">Фронтенд</h3>
<ol>
<li><strong>Улучшить валидацию форм</strong>: Добавить реальную-time валидацию и подсказки</li>
<li><strong>Добавить индикацию загрузки</strong>: Skeleton loaders для всех асинхронных операций</li>
<li><strong>Улучшить обработку ошибок</strong>: Пользовательские сообщения об ошибках с возможностью повторной попытки</li>
<li><strong>Добавить отключенные состояния</strong>: Кнопки должны быть disabled во время загрузки</li>
<li><strong>Мобильная адаптация</strong>: Проверка и улучшение мобильного UI</li>
<li><strong>Доступность</strong>: Добавить ARIA labels и проверить доступность</li>
</ol>
<h3 id="бэкенд">Бэкенд</h3>
<ol>
<li><strong>Улучшить пагинацию</strong>: Добавить валидацию и лимиты</li>
<li><strong>Добавить bulk операции</strong>: Оптимизировать массовые операции</li>
<li><strong>Улучшить обработку ошибок</strong>: Более информативные сообщения</li>
<li><strong>Добавить метрики</strong>: Время выполнения запросов, количество запросов</li>
<li><strong>Оптимизировать запросы</strong>: Проверка на N+1 запросы</li>
</ol>
<h2 id="приоритизированный-план-исправления">Приоритизированный план исправления</h2>
<table>
<thead>
<tr>
<th>Приоритет</th>
<th>Проблема</th>
<th>Файлы</th>
<th>Трудоёмкость</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Critical</strong></td>
<td>Хранение JWT токенов в localStorage</td>
<td>frontend/src/app/core/auth/auth.service.ts</td>
<td>2 часа</td>
</tr>
<tr>
<td><strong>Critical</strong></td>
<td>Отсутствие валидации ввода данных</td>
<td>backend/internal/handlers/*.go</td>
<td>4 часа</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>Небезопасные настройки JWT</td>
<td>backend/internal/config/config.go</td>
<td>1 час</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>Rate limiting для аутентификации</td>
<td>backend/internal/middleware/</td>
<td>3 часа</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>Отсутствие тестов</td>
<td>backend/internal/</td>
<td>8 часов</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>XSS валидация</td>
<td>backend/internal/handlers/*.go</td>
<td>2 часа</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>CSRF защита</td>
<td>backend/internal/middleware/</td>
<td>2 часа</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>UX улучшения (индикация загрузки)</td>
<td>frontend/src/app/</td>
<td>3 часа</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>Оптимизация запросов</td>
<td>backend/internal/repository/</td>
<td>4 часа</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>Документация API</td>
<td>backend/api/</td>
<td>2 часа</td>
</tr>
</tbody>
</table>
<p><strong>Общая трудоёмкость:</strong> ~31 час<br>
<strong>Рекомендуемый срок выполнения:</strong> 2-3 недели с учётом приоритетов</p>
</div>
</main>
</div>
</div>
<footer class="site-footer">
<div class="container">
<p class="text-center mb-0">&copy; 2026 docs.a2v.space</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fuse.js@7.0.0/dist/fuse.min.js"></script>
<script src="../../js/search.js"></script>
<script src="../../js/creds.js"></script>
</body>
</html>