diff --git a/README.md b/README.md index 18eee9a..21b4d8d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/NSTTkgmb) # Лабораторная работа №4 — Анализ и тестирование безопасности веб-приложения ## Цель diff --git a/REPORT.md b/REPORT.md new file mode 100644 index 0000000..a599e45 --- /dev/null +++ b/REPORT.md @@ -0,0 +1,389 @@ +# Отчёт по безопасности — UserAnalytics REST API + +## Этап 1 — Asset Inventory (инвентаризация активов) + +| Актив | Тип | Ценность | Примечание | +|-------|-----|----------|------------| +| Данные пользователей (userId, userName) | Данные | Высокая | Персональные данные пользователей; утечка может привести к нарушению приватности и использованию в атаках социальной инженерии | +| Данные о сессиях (время входа/выхода) | Данные | Средняя | Содержат поведенческую информацию о пользователях; могут быть использованы для профилирования активности | +| Файловая система сервера | Инфраструктура | Критическая | Через Path Traversal возможна запись произвольных файлов, что может привести к RCE (например, перезапись cron-задач или конфигурации) | +| Внутренняя сеть / метаданные окружения | Инфраструктура | Критическая | Через SSRF возможен доступ к внутренним сервисам (metadata-сервер облака, базы данных, админ-панели), что может привести к полной компрометации инфраструктуры | + +Наиболее критичны файловая система и внутренняя сеть, поскольку их компрометация приводит к контролю над всем сервером и инфраструктурой, а не только к утечке данных приложения. + +--- + +## Этап 2 — Threat Modeling (STRIDE) + +| Категория угрозы | Расшифровка | Применимо? | Источник угрозы | Поверхность атаки | Потенциальный ущерб | +|------------------|-------------|------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| **S**poofing | Подмена идентификации | Да | Любой внешний пользователь | Все эндпоинты, так как нет аутентификации, userId передаётся как query-параметр | Атакующий может действовать от имени любого пользователя: регистрировать, записывать сессии, просматривать данные | +| **T**ampering | Модификация данных | Да | Любой внешний пользователь | POST `/register`, POST `/recordSession`, GET `/exportReport` | Перезапись файлов на сервере через Path Traversal в `/exportReport`; запись произвольных сессий любому пользователю через `/recordSession` | +| **R**epudiation | Отказ от авторства | Да | Любой пользователь системы | Все эндпоинты — нет логирования и аудита действий | Невозможно доказать, кто именно выполнил действие; нет audit trail | +| **I**nformation Disclosure | Утечка данных | Да | Любой внешний пользователь | GET `/userProfile` (XSS, кража cookies), POST `/notify` (сканирование внутренней сети), `/recordSession` (stack trace в ответе) | Кража сессионных данных через XSS, доступ к внутренним сервисам, утечка внутренней структуры через сообщения об ошибках | +| **D**enial of Service | Отказ в обслуживании | Да | Любой внешний пользователь | Все эндпоинты — нет rate limiting; POST `/notify` — можно заставить сервер делать запросы к медленным серверам | Исчерпание ресурсов сервера массовыми запросами; блокировка потоков через медленные webhook-запросы | +| **E**levation of Privilege | Повышение привилегий | Да | Любой внешний пользователь | GET `/exportReport` (Path Traversal, запись в системные файлы), POST `/notify` (доступ к внутренним сервисам) | Запись произвольных файлов на сервере может привести к RCE; SSRF может дать доступ к метаданным, токенам и секретам | + +--- + +## Этап 3 — Ручное тестирование и Этап 5 — Карточки уязвимостей + +--- + +### Finding 1 - XSS через userName + +| Поле | Значение | +|------|--------------------------------------------------------------------| +| **Компонент** | GET `/userProfile` (`UserAnalyticsController`) | +| **Тип** | Reflected XSS (stored) | +| **CWE** | CWE-79 - Improper Neutralization of Input During Web Page Generation | +| **CVSS v3.1** | `6.1 MEDIUM (AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)` | +| **Статус** | Confirmed (ручное тестирование) | + +**Описание:** +> Эндпоинт `/userProfile` возвращает HTML-страницу, в которую значение `userName` подставляется без экранирования. Атакующий регистрирует пользователя с вредоносным именем через `/register`, после чего при открытии `/userProfile?userId=...` браузер жертвы исполняет произвольный JavaScript + +**Шаги воспроизведения:** +``` +1. Зарегистрировать пользователя с XSS: + POST http://localhost:7000/register?userId=user1&userName= + +2. Открыть профиль в браузере: + GET http://localhost:7000/userProfile?userId=user1 + +3. Ожидаемый результат: имя отображается как текст, спецсимволы экранированы + Фактический результат: браузер исполняет JavaScript-код, появляется alert с cookie +``` + +**Влияние:** +> Атакующий может украсть сессионные cookie, выполнить действия от имени жертвы, перенаправить на фишинговый сайт + +**Рекомендации по исправлению:** +> - Экранировать все пользовательские данные перед вставкой в HTML (использовать, например, `StringEscapeUtils.escapeHtml4()` из Apache Commons Text) +> - Выполнять санитизацию HTML + + +**Security Test Case:** +```java +@Test +@DisplayName("[SECURITY] XSS в userName должен быть экранирован в /userProfile") +void xssPayloadShouldBeEscaped() throws Exception { + String payload = ""; + send("POST", "/register?userId=user1&userName=" + enc(payload)); + HttpResponse response = send("GET", "/userProfile?userId=user1"); + assertFalse(response.body().contains("