# Практическое задание: локальная DVWA

Цель — увидеть три первопричины уязвимостей и связать наблюдение с исправлением.
Практика выполняется только в собственном трёхсервисном Compose-стенде на
`http://127.0.0.1:8000/`. Сканирование сети, внешние URL, реальные учётные
данные и реальные пользовательские данные не нужны и запрещены.

## 1. Rules of Engagement

Разрешено:

- один Windows-компьютер слушателя с Docker Desktop;
- адрес `http://127.0.0.1:8000/`;
- три синтетических ввода из этой методички;
- фиксация только названия задания, маркера результата и рекомендации.

Запрещено:

- менять bind на `0.0.0.0` или IP локальной сети;
- подключать контейнер к другой Docker-сети;
- применять ввод к чужому сайту, адресу аудитории или интернет-ресурсу;
- сохранять cookies, хеши, токены, пароли или иные секреты в отчёт;
- добавлять контейнеру привилегии или отключать resource limits.

При любом расхождении адреса, digest или сетевой конфигурации — STOP и обращение
к преподавателю.

## 2. Подготовка и запуск

Docker устанавливает администратор заранее по официальной документации. Эта
методичка не запускает установочные shell-скрипты и не добавляет пользователя в
привилегированную группу `docker`.

Из корня репозитория в Windows PowerShell:

```powershell
& .\pentest\lab\dvwa-preflight.ps1
& .\pentest\lab\dvwa-start.ps1
```

Wrapper использует предварительно загруженные и закреплённые по digest версии
официального образа проекта DVWA из `ghcr.io/digininja/dvwa`, минимального
Alpine-прокси и MariaDB 10.11.15. Устаревший сторонний образ 2018 года исключён.
Плавающие теги и автоматический pull не используются. Compose задаёт:

- loopback-only bind `127.0.0.1:8000`;
- минимальный TCP-прокси публикует loopback-порт и передаёт трафик только на
  фиксированный адрес `dvwa:80`; сам контейнер DVWA не публикует порт на хост;
- DVWA и одноразовая БД подключены только к внутренней Docker-сети без внешнего
  egress и без адреса host bridge (`gateway_mode_ipv4: isolated`);
- `cap_drop: ALL` с возвратом только минимальных capabilities, необходимых
  Apache и bootstrap MariaDB;
- `no-new-privileges`, лимиты PID, памяти и CPU;
- отсутствие автоматического restart;
- project-scoped cleanup.

Откройте <http://127.0.0.1:8000/>. Если база ещё не создана, используйте только
локальную страницу `/setup.php` и кнопку `Create / Reset Database`. Войдите с
учебными значениями DVWA `admin` / `password`, затем выберите уровень `low`.

## 3. Формат доказательства

Для каждого упражнения заполните одну строку:

| Поле | Что фиксировать |
|---|---|
| Граница | `DVWA digest …`, `127.0.0.1:8000`, уровень `low` |
| Наблюдение | Только число строк или маркер `DVWA-SYNTHETIC` |
| Первопричина | Почему данные стали кодом/разметкой |
| Исправление | Конкретный защитный механизм |
| Retest | Ожидаемый результат на уровне `impossible` |

Скриншот cookies, таблицы паролей или системных идентификаторов не требуется.

## 4. Упражнение 1 — SQL Injection (CWE-89)

Откройте **SQL Injection** и выполните только два ввода:

1. `1` — приложение возвращает одну учебную запись.
2. `1' OR '1'='1` — приложение возвращает несколько синтетических записей.

Не извлекайте другие столбцы и не добавляйте `UNION`. Достаточное доказательство
— изменение количества результатов. Объясните, почему конкатенация смешала код
SQL и данные. Исправление: параметризованный запрос и минимальные права аккаунта
БД. Retest: тот же ввод трактуется как одно значение и не расширяет результат.

## 5. Упражнение 2 — OS Command Injection (CWE-78)

Откройте **Command Injection** и выполните:

1. `127.0.0.1` — обычный локальный ping.
2. `127.0.0.1; printf DVWA-SYNTHETIC` — после ping появляется только синтетический
   маркер `DVWA-SYNTHETIC`.

Не используйте `id`, `whoami`, чтение файлов, сетевые команды или запуск shell.
Исправление: отказаться от shell-интерпретации, передавать фиксированный массив
аргументов и валидировать IP как типизированное значение. Retest: строка целиком
отклоняется как некорректный IP.

## 6. Упражнение 3 — Reflected XSS (CWE-79)

Откройте **XSS (Reflected)** и выполните:

1. `student` — обычный текст.
2. `<script>alert('DVWA-SYNTHETIC')</script>` — локальный браузер показывает
   синтетический маркер.

Не обращайтесь к `document.cookie`, local storage или внешним URL. Исправление:
контекстное output encoding; CSP — дополнительный барьер, а не замена encoding.
Retest: строка отображается как текст и JavaScript не выполняется.

## 7. Сопоставление и отчёт

Все три случая иллюстрируют одну границу: недоверенные данные интерпретируются
как код SQL, команда shell или HTML/JavaScript. Для каждого случая укажите CWE,
source, interpreter/sink, наблюдение, минимальное исправление и отрицательный
retest. В актуальной карте OWASP Top 10:2025 эти примеры рассматриваются в
контексте A05 Injection, но CWE остаётся более точной меткой конкретного дефекта.

## 8. Обязательное завершение

Независимо от результата упражнений:

```powershell
& .\pentest\lab\dvwa-stop.ps1
```

Успешный итог — сообщение `CLEANUP OK`, отсутствие объектов Compose и закрытый
порт 8000. Не удаляйте другие контейнеры и сети вручную: wrapper затрагивает
только собственный Compose-проект.

## 9. Контрольные вопросы

1. Почему loopback bind и отсутствие egress уменьшают последствия ошибки?
2. Почему сетевой барьер не заменяет исправление SQL/XSS/command injection?
3. Как доказать исправление, не собирая секреты и лишние данные?
4. Какие controls относятся к prevention, detection и recovery?

Материал предназначен только для локальной разрешённой учебной среды.
