# ZAP Active Scan — отчёт 2026-06-18

**Инструмент:** OWASP ZAP 2.17.0 (#68), полный DAST — spider + **active scan**.
**Цель:** `http://127.0.0.1:8000` (локальная копия; гард IS8 — на боевой active scan не гнался).
**Запуск:** [bin/zap-active-scan.ps1](../../bin/zap-active-scan.ps1) (демон → spider → active scan → экспорт).
**Сырые отчёты:** `docs/security/2026-06-18-zap-active-scan.json` (+ `.html`).

Углубляет прошлый прогон spider + passive (17.06.2026, 0 high) реальным активным сканированием.

## Сводка по риску

| Риск | Экземпляров | Вердикт |
|---|---|---|
| **High** | 1 | false-positive (разбор ниже) |
| **Medium** | 4 | локальный артефакт (заголовки на nginx в проде) |
| Low | 28 | информационно, не блокирует |
| Informational | 7 | информационно, не блокирует |

**Реальных high/critical — 0. Вердикт ZAP active scan: GO ✅**

## High (1) — «Cloud Metadata Potentially Exposed» (CWE-1230) — FALSE POSITIVE

- Плагин `90034`. Запрос `GET http://127.0.0.1:8000/opc/v1/instance/` с Host-заголовком `169.254.169.254` (попытка вытащить метаданные облака через Host-инъекцию в misconfigured NGINX).
- `confidence = Medium`, **`evidence` пустой**, `otherinfo`: *«Based on the successful response status code cloud metadata **may have** been returned… **Check the response data**…»* — то есть правило сработало **только на успешный статус-код**, реальных метаданных в ответе ZAP не нашёл.
- **Почему это false-positive:**
  1. Цель — `php artisan serve`, **nginx нет**. Описание и solution алерта целиком про misconfigured NGINX `$host` — к dev-серверу artisan неприменимо.
  2. Vue 3 SPA отдаёт **catch-all 200** (`index.html`) на любой неизвестный путь → `/opc/v1/instance/` вернул 200 → эвристика «успешный статус» ложно сработала. Метаданные не возвращались (`evidence` пуст).
  3. SSRF к cloud-metadata уже закрыт в коде: `WebhookUrlGuard` блокирует `169.254.169.254` / RFC1918 / loopback (блокер B4, go-live report 17.06).
- **Belt-and-suspenders проверка (ручная):** `curl -H "Host: 169.254.169.254" http://127.0.0.1:8000/opc/v1/instance/` → ожидается SPA-HTML, не метаданные.
- **Классификация:** false-positive. Не блокер.

## Medium (4) — отсутствие security-заголовков (локальный артефакт)

2 типа × 2 экземпляра:

- «Content Security Policy (CSP) Header Not Set» (`10038`) — на `/` и `/sitemap.xml`.
- «Missing Anti-clickjacking Header» / X-Frame-Options (`10020`).

Срабатывают потому, что локальная цель `php artisan serve` **не имеет nginx**, а app-уровневый middleware `SecurityHeaders` удалён в Задаче 1 (консолидация заголовков, коммит `a4a8ea31`). **На боевом эти заголовки шлёт nginx** (enforcing CSP, X-Frame-Options и др. — `/etc/nginx/sites-available/liderra`, `add_header … always`), поэтому на проде эти Medium **не воспроизводятся**. Локально — ожидаемо; заодно подтверждает, что дедуп Задачи 1 сработал (приложение само эти заголовки больше не ставит).

## Low (28) / Informational (7)

Не блокируют go-live. В основном — следствие того же отсутствия nginx локально (X-Content-Type-Options missing — 5 экз., cookie HttpOnly, X-Powered-By leak) + информационные детекты (suspicious comments, modern-web-app, session-management). Полный список — в `2026-06-18-zap-active-scan.json`.

## Вердикт

**ZAP active scan: GO — 0 реальных high/critical.**

- Единственный High — подтверждённый false-positive (SPA 200-catch-all + отсутствие nginx локально; SSRF уже закрыт `WebhookUrlGuard`).
- 4 Medium — локальные артефакты; на проде заголовки ставит nginx.
- Active scan углубил прошлый spider+passive и **не выявил реальных уязвимостей** (SQLi/XSS/path-traversal/injection — чисто).

Закрывает открытый пункт go-live «ZAP active scan» (ранее PENDING). Скрипт-оркестратор [bin/zap-active-scan.ps1](../../bin/zap-active-scan.ps1) воспроизводим для будущих прогонов.
