# Канонический локальный стенд OWASP Juice Shop

Это единственный поддерживаемый способ запуска Juice Shop для материалов AppSec.
Стенд предназначен только для собственного учебного компьютера и не должен
подключаться к сети аудитории, корпоративной сети или внешним целям.

## Зафиксированная среда

- образ закреплён по digest, а не по плавающему тегу;
- минимальный TCP-прокси Alpine также закреплён по digest;
- Compose не скачивает образ (`pull_policy: never`): его заранее проверяет и
  загружает преподаватель;
- у уязвимого приложения нет опубликованного порта: порт
  `127.0.0.1:3000` принадлежит только минимальному TCP-прокси;
- приложение подключено только к Docker-сети с `internal: true`, поэтому не
  получает внешний egress; режим gateway `isolated` также убирает адрес bridge
  и доступ приложения к сервисам Docker-хоста; прокси одновременно подключён к
  входной и внутренней сетям и передаёт трафик только на фиксированный адрес
  `juice-shop:3000`;
- удалены Linux capabilities, запрещено получение новых привилегий, установлены
  лимиты PID, памяти и CPU;
- автоматический перезапуск отключён, состояние удаляется штатным `down`.

Перед раздачей комплекта преподаватель сверяет digest с официальным релизом
[OWASP Juice Shop](https://github.com/juice-shop/juice-shop/releases) и выполняет
контрольный прогон. Если upstream выпустил новую версию, сначала обновляются
compose, задания и регрессионный тест; менять образ прямо перед занятием нельзя.

## Preflight

Docker Engine 28.0.0 или новее и Compose v2 должны быть установлены
администратором заранее. На более старых версиях Docker loopback-публикация не
обеспечивает требуемую защиту от доступа из того же L2-сегмента, поэтому запуск
запрещён.
Материал не устанавливает Docker, не добавляет пользователя в привилегированную
группу и не выполняет `curl | shell`.

Из этой папки запускайте только проверенный wrapper. Он сверяет Docker Engine,
Compose-конфигурацию, точные digest образов, свободный loopback-порт и метки
владения всех ранее оставшихся объектов проекта. Если проект с таким же именем
создан не этим комплектом, выполнение останавливается **до** изменения или
удаления контейнеров, сетей и volumes.

```powershell
.\start.ps1
```

Compose содержит bounded healthcheck и запускает loopback-прокси только после
готовности Juice Shop. Если образ отсутствует или healthcheck не проходит,
слушатель останавливается и обращается к преподавателю.
Самостоятельный `pull latest` не является частью практикума.

## Запуск и проверка границы

`start.ps1` сам выполняет bounded readiness-loop и завершает работу только
после HTTP 200 от `http://127.0.0.1:3000/`.

Ожидаемая публикация — только `127.0.0.1:3000`. Откройте
<http://127.0.0.1:3000/>. Не меняйте bind на `0.0.0.0`, не подключайте сервис к
другой сети и не добавляйте привилегии.

## Завершение

```powershell
.\stop.ps1
```

Wrapper сначала проверяет метки `expert.pikov.lab` и `expert.pikov.config` у
каждого объекта Compose-проекта, и только затем выполняет удаление. Чужой или
неоднозначный объект означает STOP без `down`. После удаления wrapper повторно
проверяет отсутствие контейнеров, сетей и volumes. Образы не удаляются: их
digest нужен для воспроизводимого повторного занятия.
