Files
docs.a2v.space/public/guides/leadera-audit/index.html
T
Агальцов Антон b36056a690 leadera audit
2026-03-30 07:51:20 +03:00

554 lines
27 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>
<h3 id="бекенд">Бекенд</h3>
<ul>
<li><strong>Стек:</strong> Go 1.21+, GIN, PostgreSQL 16+, pgx v5 + sqlx, JWT</li>
<li><strong>Архитектура:</strong> Clean Architecture с разделением на слои</li>
<li><strong>Особенности:</strong> RESTful API, автоматические миграции, система ролей через spaces</li>
</ul>
<h3 id="фронтенд">Фронтенд</h3>
<ul>
<li><strong>Стек:</strong> Angular 21.1.3, Bootstrap 5, RxJS</li>
<li><strong>Особенности:</strong> JWT-аутентификация, перехватчики HTTP, lazy loading</li>
</ul>
<h2 id="бекенд--найденные-проблемы">Бекенд — найденные проблемы</h2>
<h3 id="критические-проблемы">Критические проблемы</h3>
<h4 id="1-уязвимость-xss-в-сериализации-dom">1. Уязвимость XSS в сериализации DOM</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/handlers/space_handler.go:47-63</code></li>
<li><strong>Критичность:</strong> <strong>critical</strong></li>
<li><strong>Описание:</strong> В методе <code>GetSpaceMembers</code> используется <code>c.BindJSON(&amp;req)</code> без валидации, что может привести к XSS при сериализации данных в JSON</li>
<li><strong>Рекомендация:</strong> Добавить валидацию DTO и использование HTML sanitizer</li>
</ul>
<h4 id="2-небезопасное-хранение-токенов">2. Небезопасное хранение токенов</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/utils/password.go:19-21</code></li>
<li><strong>Критичность:</strong> <strong>critical</strong></li>
<li><strong>Описание:</strong> Refresh токены хэшируются с помощью SHA256 вместо bcrypt, что делает их уязвимыми для перебора</li>
<li><strong>Рекомендация:</strong> Перейти на bcrypt для хэширования refresh токенов</li>
</ul>
<h4 id="3-отсутствие-rate-limiting">3. Отсутствие Rate Limiting</h4>
<ul>
<li><strong>Файл:</strong> Нет реализации</li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Нет ограничений на количество запросов к API, что делает систему уязвимой для brute-force атак</li>
<li><strong>Рекомендация:</strong> Реализовать middleware для rate limiting</li>
</ul>
<h3 id="высокие-проблемы">Высокие проблемы</h3>
<h4 id="4-отсутствие-валидации-входных-данных">4. Отсутствие валидации входных данных</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/handlers/auth_handler.go:26-32, 52-58</code></li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Нет строгой валидации email, длинны строк и других параметров запросов</li>
<li><strong>Рекомендация:</strong> Внедрить библиотеку для валидации (go-playground/validator)</li>
</ul>
<h4 id="5-отсутствие-защиты-от-csrf">5. Отсутствие защиты от CSRF</h4>
<ul>
<li><strong>Файл:</strong> Нет реализации</li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Нет CSRF-токенов для POST/PUT/DELETE запросов</li>
<li><strong>Рекомендация:</strong> Реализовать CSRF middleware</li>
</ul>
<h4 id="6-потенциальные-n1-запросы">6. Потенциальные N+1 запросы</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/repository/space_repository.go</code></li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Нет индексов и оптимизации для запросов с JOIN при получении членов spaces</li>
<li><strong>Рекомендация:</strong> Добавить правильные индексы и использовать eager loading</li>
</ul>
<h3 id="средние-проблемы">Средние проблемы</h3>
<h4 id="7-отсутствие-логирования-ошибок">7. Отсутствие логирования ошибок</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/handlers/gantt_handler.go:78-95</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Ошибки валидации не логируются, что затрудняет отладку</li>
<li><strong>Рекомендация:</strong> Структурированное логирование всех ошибок</li>
</ul>
<h4 id="8-жестко-закодированные-настройки">8. Жестко закодированные настройки</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/middleware/space_middleware.go:121-128</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Статическая проверка subscription status без гибкой конфигурации</li>
<li><strong>Рекомендация:</strong> Вынести в конфигурацию возможные статусы подписки</li>
</ul>
<h4 id="9-отсутствие-ограничений-на-количество-записей">9. Отсутствие ограничений на количество записей</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/handlers/gantt_handler.go</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Нет ограничений на количество задач, разделов или диаграмм на пользователя</li>
<li><strong>Рекомендация:</strong> Добавить лимиты через middleware</li>
</ul>
<h3 id="низкие-проблемы">Низкие проблемы</h3>
<h4 id="10-отсутствие-валидации-для-special-символов">10. Отсутствие валидации для special символов</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/utils/validation.go:21-24</code></li>
<li><strong>Критичность:</strong> <strong>low</strong></li>
<li><strong>Описание:</strong> Валидация паролей не включает некоторые специальные символы</li>
<li><strong>Рекомендация:</strong> Расширить список разрешенных символов</li>
</ul>
<h4 id="11-отсутствие-health-check-для-базы-данных">11. Отсутствие Health Check для базы данных</h4>
<ul>
<li><strong>Файл:</strong> <code>internal/handlers/handler.go</code></li>
<li><strong>Критичность:</strong> <strong>low</strong></li>
<li><strong>Описание:</strong> Health endpoint не проверяет доступность базы данных</li>
<li><strong>Рекомендация:</strong> Добавить ping к базе данных в health check</li>
</ul>
<h2 id="фронтенд--найденные-проблемы">Фронтенд — найденные проблемы</h2>
<h3 id="критические-проблемы-1">Критические проблемы</h3>
<h4 id="1-хранение-jwt-токенов-в-localstorage">1. Хранение JWT токенов в localStorage</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/core/auth/auth.service.ts:25-40</code></li>
<li><strong>Критичность:</strong> <strong>critical</strong></li>
<li><strong>Описание:</strong> Токены хранятся в localStorage, уязвимом для XSS атак</li>
<li><strong>Рекомендация:</strong> Использовать HTTP-only cookies или secure storage</li>
</ul>
<h4 id="2-отсутствие-content-security-policy-csp">2. Отсутствие Content Security Policy (CSP)</h4>
<ul>
<li><strong>Файл:</strong> <code>src/index.html</code></li>
<li><strong>Критичность:</strong> <strong>critical</strong></li>
<li><strong>Описание:</strong> Нет заголовков CSP для защиты от XSS</li>
<li><strong>Рекомендация:</strong> Добавить заголовки CSP в HTTP ответы</li>
</ul>
<h3 id="высокие-проблемы-1">Высокие проблемы</h3>
<h4 id="3-нет-валидации-форм-на-стороне-клиента">3. Нет валидации форм на стороне клиента</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/pages/auth/components/sign-up/sign-up.component.ts</code></li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Формы не проходят полную валидацию перед отправкой</li>
<li><strong>Рекомендация:</strong> Реализовать полноценную клиентскую валидацию</li>
</ul>
<h4 id="4-отсутствие-обработки-race-conditions">4. Отсутствие обработки race conditions</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/core/auth/auth.interceptor.ts:15-45</code></li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Потенциальные race conditions при обновлении токенов</li>
<li><strong>Рекомендация:</strong> Реализовать очередь запросов при обновлении токенов</li>
</ul>
<h4 id="5-нет-ограничений-на-длину-вводимых-данных">5. Нет ограничений на длину вводимых данных</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/components/forms/gantt-form.component.ts</code></li>
<li><strong>Критичность:</strong> <strong>high</strong></li>
<li><strong>Описание:</strong> Пользователь может вводить очень длинные тексты без ограничений</li>
<li><strong>Рекомендация:</strong> Добавить максимальную длину для полей ввода</li>
</ul>
<h3 id="средние-проблемы-1">Средние проблемы</h3>
<h4 id="6-нет-proper-error-handling-states">6. Нет proper error handling states</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/layouts/components/navbar/navbar.component.ts</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Нет graceful handling ошибок при загрузке данных</li>
<li><strong>Рекомендация:</strong> Реализовать skeleton loaders и error boundaries</li>
</ul>
<h4 id="7-плохая-производительность-при-большом-количестве-данных">7. Плохая производительность при большом количестве данных</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/pages/dashboard/gantt/gantt-page.component.ts</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Нет virtual scrolling для больших списков задач</li>
<li><strong>Рекомендация:</strong> Реализовать virtual scrolling и lazy loading</li>
</ul>
<h4 id="8-отсутствие-a11y-для-некоторых-компонентов">8. Отсутствие a11y для некоторых компонентов</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/components/charts/gantt-chart/gantt-chart.component.ts</code></li>
<li><strong>Критичность:</strong> <strong>medium</strong></li>
<li><strong>Описание:</strong> Гант-диаграмма не имеет proper ARIA labels</li>
<li><strong>Рекомендация:</strong> Добавить ARIA атрибуты и keyboard navigation</li>
</ul>
<h3 id="низкие-проблемы-1">Низкие проблемы</h3>
<h4 id="9-нет-csrf-protection">9. Нет CSRF protection</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/core/auth/auth.interceptor.ts</code></li>
<li><strong>Критичность:</strong> <strong>low</strong></li>
<li><strong>Описание:</strong> Отсутствие CSRF токенов для чувствительных операций</li>
<li><strong>Рекомендация:</strong> Добавить CSRF токены в заголовки</li>
</ul>
<h4 id="10-плохая-мобильная-адаптация">10. Плохая мобильная адаптация</h4>
<ul>
<li><strong>Файл:</strong> <code>src/app/styles/gantt.scss</code></li>
<li><strong>Критичность:</strong> <strong>low</strong></li>
<li><strong>Описание:</strong> Нет proper responsive design для мобильных устройств</li>
<li><strong>Рекомендация:</strong> Добавить медиа-запросы и touch-friendly интерфейс</li>
</ul>
<h2 id="безопасность">Безопасность</h2>
<h3 id="обнаруженные-уязвимости">Обнаруженные уязвимости:</h3>
<ol>
<li><strong>XSS уязвимости</strong> - Отсутствие валидации входных данных на бэкенде</li>
<li><strong>Небезопасное хранение токенов</strong> - Refresh токены используют SHA256 вместо bcrypt</li>
<li><strong>Отсутствие rate limiting</strong> - Уязвимость для brute-force атак</li>
<li><strong>CSRF уязвимости</strong> - Отсутствие CSRF-токенов</li>
<li><strong>Storage vulnerabilities</strong> - localStorage используется для хранения JWT</li>
</ol>
<h3 id="рекомендации-по-безопасности">Рекомендации по безопасности:</h3>
<ol>
<li>Реализовать Input Validation на всех уровнях</li>
<li>Перейти на HTTP-only cookies для токенов</li>
<li>Реализовать rate limiting middleware</li>
<li>Добавить CSRF protection</li>
<li>Внедрить заголовки безопасности (CSP, HSTS, X-Frame-Options)</li>
<li>Реализовать proper logging и мониторинг</li>
<li>Добавить автоматические тесты безопасности</li>
</ol>
<h2 id="ux-улучшения">UX улучшения</h2>
<h3 id="критические-улучшения">Критические улучшения:</h3>
<ol>
<li><strong>Надежность аутентификации</strong> - Реализовать MFA</li>
<li><strong>Уведомления об ошибках</strong> - Лучшее error messaging</li>
<li><strong>Прогресс-бары</strong> - Для долгих операций</li>
</ol>
<h3 id="высокие-улучшения">Высокие улучшения:</h3>
<ol>
<li><strong>Поиск по проекту</strong> - Быстрый поиск across spaces</li>
<li><strong>Drag &amp; Drop</strong> - Для задач и диаграмм</li>
<li><strong>Keyboard shortcuts</strong> - Повышение продуктивности</li>
<li><strong>Темная тема</strong> - Улучшение UX при длительной работе</li>
</ol>
<h3 id="средние-улучшения">Средние улучшения:</h3>
<ol>
<li><strong>Экспорт данных</strong> -多种 форматы</li>
<li><strong>Коллаборация в реальном времени</strong> - WebSocket для live updates</li>
<li><strong>Шаблоны диаграмм</strong> - Pre-built templates</li>
<li><strong>Аналитика и отчеты</strong> - Insights по проектам</li>
</ol>
<h3 id="низкие-улучшения">Низкие улучшения:</h3>
<ol>
<li><strong>Mobile app</strong> - iOS/Android приложения</li>
<li><strong>Интеграции</strong> - Slack, Teams, Jira и др.</li>
<li><strong>API для плагинов</strong> - Расширяемость системы</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>XSS уязвимости</td>
<td><code>internal/handlers/*.go</code></td>
<td>3 дня</td>
</tr>
<tr>
<td><strong>Critical</strong></td>
<td>Хранение JWT в localStorage</td>
<td><code>src/app/core/auth/*.ts</code></td>
<td>1 день</td>
</tr>
<tr>
<td><strong>Critical</strong></td>
<td>Небезопасное хранение refresh токенов</td>
<td><code>internal/utils/password.go</code></td>
<td>1 день</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>Rate limiting middleware</td>
<td><code>internal/middleware/</code></td>
<td>2 дня</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>CSRF protection</td>
<td><code>internal/middleware/</code>, <code>src/app/core/auth/</code></td>
<td>2 дня</td>
</tr>
<tr>
<td><strong>High</strong></td>
<td>Валидация входных данных</td>
<td><code>internal/handlers/</code>, <code>internal/utils/</code></td>
<td>3 дня</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>Оптимизация запросов БД</td>
<td><code>internal/repository/</code></td>
<td>2 дня</td>
</tr>
<tr>
<td><strong>Medium</strong></td>
<td>Структурированное логирование</td>
<td><code>internal/handlers/</code></td>
<td>1 день</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>CSP заголовки</td>
<td><code>src/index.html</code>, конфигурация сервера</td>
<td>1 день</td>
</tr>
<tr>
<td><strong>Low</strong></td>
<td>A11y улучшения</td>
<td><code>src/app/components/</code></td>
<td>3 дня</td>
</tr>
</tbody>
</table>
<h3 id="общая-оценка">Общая оценка:</h3>
<ul>
<li><strong>Critical issues:</strong> 6 задач, 8 дней</li>
<li><strong>High issues:</strong> 5 задач, 7 дней</li>
<li><strong>Medium issues:</strong> 3 задачи, 6 дней</li>
<li><strong>Low issues:</strong> 4 задачи, 5 дней</li>
</ul>
<p><strong>Общая трудоёмкость:</strong> 26 дней разработки + 3 дня на тестирование = 29 дней</p>
<h3 id="рекомендуемый-порядок-работы">Рекомендуемый порядок работы:</h3>
<ol>
<li><strong>Неделя 1:</strong> Решение всех critical проблем (безопасность)</li>
<li><strong>Неделя 2:</strong> High приоритетные улучшения (защита)</li>
<li><strong>Неделя 3:</strong> Medium и Low улучшения (качество и UX)</li>
</ol>
<p><strong>Примечание:</strong> Этот аудит содержит только анализ и рекомендации. Не следует вносить изменения в код без дополнительных тестов и проверок безопасности.</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>