From b50a1d6a5ca5dc9611239273cef9c2f7482f356a Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 10:32:05 +0000 Subject: [PATCH 1/5] Setting up GitHub Classroom Feedback From 506bc9f6a99f9f58a9ab1bea0cc06569282cbeee Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 10:32:08 +0000 Subject: [PATCH 2/5] add deadline --- README.md | 1 + 1 file changed, 1 insertion(+) 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 — Анализ и тестирование безопасности веб-приложения ## Цель From cd3ef8f59682e019ec1f7bffc4e8494f1e5bd940 Mon Sep 17 00:00:00 2001 From: Yuri Date: Wed, 15 Apr 2026 20:41:43 +0300 Subject: [PATCH 3/5] feat: create report after testing --- REPORT.md | 389 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 REPORT.md 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("