промпт для фикса уязвимостей
This commit is contained in:
193
BUG_FIX_PROMPT.md
Normal file
193
BUG_FIX_PROMPT.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Промпт для исправления ошибок из `BUG_REPORT.md`
|
||||
|
||||
Ты работаешь как ведущий full-stack инженер, специалист по безопасности и DevOps в репозитории системы университетского расписания Magistr.
|
||||
|
||||
Твоя задача — не просто составить план, а последовательно реализовать, протестировать и документировать исправления всех проблем из корневого файла `BUG_REPORT.md`, **кроме проблемы № 2**.
|
||||
|
||||
## Обязательная область работ
|
||||
|
||||
Исправь проблемы **№ 1 и № 3–34**. Проблема **№ 2 полностью исключена из задачи**:
|
||||
|
||||
`[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]`
|
||||
|
||||
Это ровно 33 проблемы: одна критическая № 1, десять высокого приоритета № 3–12, девятнадцать среднего приоритета № 13–31 и три низкого приоритета № 32–34.
|
||||
|
||||
- не исправляй её;
|
||||
- не изменяй ради неё демонстрационные данные или учётные записи;
|
||||
- не добавляй миграцию для отключения demo-аккаунтов;
|
||||
- не меняй существующие Flyway-миграции, включая `V1__init.sql` и `V2__subgroups_active_unique_name.sql`;
|
||||
- не включай проблему № 2 в итоговый список выполненных исправлений.
|
||||
|
||||
Если изменение для другого пункта пересекается с проблемой № 2, реализуй только часть, необходимую для другого пункта, и не затрагивай seed/demo-данные.
|
||||
|
||||
## Проектный контекст и обязательные правила
|
||||
|
||||
1. Сначала полностью прочитай:
|
||||
- корневой `AGENTS.md` — это главный проектный регламент;
|
||||
- `BUG_REPORT.md`;
|
||||
- относящиеся к изменениям документы из `docs/`;
|
||||
- фактический код и тесты в затронутых подсистемах;
|
||||
- production-манифесты в `../k8s/`, которые входят в область проекта согласно `AGENTS.md`.
|
||||
2. При конфликте любых инструкций проекта с `AGENTS.md` следуй `AGENTS.md`.
|
||||
3. Используй проектные навыки из `.agents/skills`, когда задача соответствует их описанию. Для навигации по проекту сначала используй существующий `graphify-out/graph.json`, если он актуален. После изменений в коде примени `AutoUpdateDocs`.
|
||||
4. Соблюдай стек проекта: Java 17, Spring Boot 3.2.5, PostgreSQL/Flyway, Vanilla JavaScript, HTML и CSS без frontend-фреймворков.
|
||||
5. Все ответы, комментарии, UI-тексты, пользовательские ошибки и проектные логи должны быть на русском языке. Технические идентификаторы допустимы в структурированных полях логов.
|
||||
6. Сохраняй мультитенантную модель: отдельная PostgreSQL БД для каждого tenant. Проверяй, что миграции и фоновые задачи корректно работают для всех tenant-БД.
|
||||
7. Не изменяй существующие Flyway-миграции. Любые новые ограничения схемы оформляй новыми последовательно пронумерованными миграциями, начиная со следующей свободной версии. Сначала проверь фактическую максимальную версию в `backend/src/main/resources/db/migration/`.
|
||||
8. Сохраняй уже имеющиеся пользовательские изменения в рабочем дереве. Не откатывай и не перезаписывай несвязанные правки.
|
||||
9. Не выполняй `commit`, `push`, deployment, ротацию production-секретов, переписывание истории Git или иные внешние необратимые действия без отдельного разрешения. Репозиторную часть исправлений реализуй полностью, а необходимые production-действия оформи отдельным точным runbook.
|
||||
10. Не придумывай и не коммить реальные секреты. Не выводи секреты, пароли, токены, cookie или строки подключения в ответах, тестах и логах.
|
||||
11. Не скрывай ошибки пустыми `catch`, не ослабляй проверки безопасности ради прохождения тестов и не отмечай проблему исправленной только за счёт комментария или документации.
|
||||
12. Если замечание из отчёта уже исправлено в текущем коде, проверь это по реализации, добавь или уточни регрессионный тест и укажи доказательство. Не делай лишнюю повторную правку.
|
||||
13. Не редактируй `BUG_REPORT.md`: он остаётся исходным реестром требований и основанием для итоговой проверки.
|
||||
14. Учитывай, что `../k8s/` находится вне Git-корня `magistr`: отдельно перечисляй и проверяй каждый изменённый там файл. `git diff` текущего репозитория не подтверждает состояние `../k8s/`.
|
||||
|
||||
## Режим выполнения
|
||||
|
||||
Задача большая, поэтому веди явный чек-лист по номерам проблем: `1, 3, 4, …, 34`. Для каждого пункта зафиксируй:
|
||||
|
||||
- подтверждённую первопричину;
|
||||
- изменяемые файлы и выбранное решение;
|
||||
- автоматические тесты или иную воспроизводимую проверку;
|
||||
- статус: `не начато`, `в работе`, `исправлено и проверено` либо `требуется внешнее действие`.
|
||||
|
||||
Раздели работу на независимые потоки и используй субагентов, если платформа это поддерживает, но координируй общие файлы, номера Flyway-миграций, API-контракты и role matrix централизованно. Не останавливайся после анализа или первой группы исправлений. Продолжай, пока все пункты из области работ не будут реализованы и проверены либо пока не останется объективный блокер, требующий внешних полномочий.
|
||||
|
||||
Перед редактированием:
|
||||
|
||||
1. Выполни `git status --short` и сохрани понимание исходных пользовательских изменений.
|
||||
2. Зафиксируй список и контрольные суммы всех существующих Flyway-миграций, чтобы доказать их неизменность в финале.
|
||||
3. Проверь каждое утверждение отчёта по актуальному коду.
|
||||
4. Составь краткий порядок правок с учётом зависимостей.
|
||||
5. Запусти доступный базовый набор тестов, чтобы отличать исходные сбои от внесённых регрессий.
|
||||
|
||||
## Требуемый результат по каждому пункту
|
||||
|
||||
### Безопасность и аутентификация
|
||||
|
||||
- **№ 1 — секреты в production-конфигурации.** Удали фиксированные, дефолтные и placeholder-секреты из отслеживаемой конфигурации; перенеси чувствительные значения из ConfigMap в подходящий механизм Secret/External Secrets/SOPS/Sealed Secrets либо подготовь безопасные ссылки на секреты без самих значений. На production-профиле приложение должно завершать запуск при отсутствующем, дефолтном или известном placeholder `JWT_SECRET`, а также при небезопасном refresh-cookie. Не переписывай историю Git и не ротируй реальные секреты самостоятельно — подготовь отдельный runbook ротации и очистки истории. При secret scan не трактуй неизменяемые demo-значения из `V1__init.sql`, относящиеся к исключённой проблеме № 2, как разрешение менять V1 или решать пункт № 2.
|
||||
- **№ 3 — конкурентная ротация refresh-токена.** Обеспечь атомарную single-use семантику через блокировку строки или условный `UPDATE`; только один из параллельных запросов может создать следующий токен. Добавь конкурентный интеграционный тест с реальным PostgreSQL/Testcontainers.
|
||||
- **№ 4 — утечка `AuthContext`.** Очищай контекст в начале обработки и на всех отказах, а пользователя устанавливай только после успешной аутентификации и авторизации. Добавь тест последовательных запросов на одном servlet-потоке.
|
||||
- **№ 12 — access JWT и удалённый JavaScript в одном origin.** Убери исполнение неприкреплённых удалённых модулей, зафиксируй зависимости lockfile и раздавай их локально. Убери долговременное хранение access token в `localStorage` и `sessionStorage`: выбери и последовательно реализуй безопасную схему с access token в памяти и HttpOnly refresh-cookie либо полноценной защищённой cookie-сессией. Добавь строгий CSP без `unsafe-inline`/`unsafe-eval`, устрани несовместимые inline-скрипты и проверь все сценарии входа, refresh, logout и безопасного восстановления сессии после перезагрузки страницы.
|
||||
- **№ 14 — отключённая TLS-проверка Kubernetes API.** Удали доверие любому сертификату. Используй service-account CA `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`, стандартную проверку цепочки и hostname; ошибки должны быть явными и безопасными.
|
||||
- **№ 24 — бесконечный рост refresh-токенов.** Добавь tenant-aware cleanup с настраиваемым сроком хранения отозванных/истёкших записей, безопасным расписанием и тестами. Очистка должна сохранять активные и свежие audit-записи, быть идемпотентной и безопасной при двух pod.
|
||||
- **№ 25 — утечка DB/JDBC-ошибок.** Централизованно преобразуй `DataIntegrityViolationException` и известные constraints в корректные `400`/`409` с русскими сообщениями. Внутренние тексты исключений не должны попадать клиенту.
|
||||
- **№ 28 — отсутствие ограничения входа.** Реализуй общий для нескольких backend-pod rate limit по tenant + IP + нормализованному username, прогрессивную задержку или временную блокировку и аудит неудачных попыток без логирования пароля. Учти корректное определение клиентского IP только за доверенным proxy, не допускай user enumeration, возвращай `429 Too Many Requests` и корректный `Retry-After`. Не выдавай локальный in-memory limiter одного pod за production-решение.
|
||||
- **№ 33 — DOM XSS и видимые пароли.** Замени небезопасные вставки ошибок через `innerHTML` на `textContent` или проверенное экранирование. Поля пароля должны иметь `type="password"` и корректные `autocomplete`.
|
||||
- **№ 34 — языковой регламент.** Приведи затронутые UI-тексты, ошибки и production-логи к русскому языку, не отдавая пользователю сырой JDBC/HTTP exception text.
|
||||
|
||||
### Расписание, календарь и бизнес-инварианты
|
||||
|
||||
- **№ 5 — невалидные schedule overrides.** До сохранения построй фактическую исходную пару на дату, проверь обязательные поля для каждого action, существование пары и конфликты преподавателя, аудитории и всех групп в результирующем расписании. Конфликт должен давать `409 Conflict` с русским сообщением.
|
||||
- **№ 6 — замена преподавателя не видна в его расписании.** Учитывай overrides с `newTeacher` за период, достраивай относящиеся базовые пары и выполняй окончательную фильтрацию после применения overrides. Покрой исходного и нового преподавателя тестами.
|
||||
- **№ 7 — неполная валидация правил.** Проверяй конфликты и дубли внутри нового правила, роль `TEACHER`, допустимый enum формата и чётное положительное количество академических часов. Где уместно, продублируй инварианты новой Flyway-миграцией.
|
||||
- **№ 8 — частичный commit календарной сетки.** Сначала валидируй весь payload и уникальность ключей, затем атомарно заменяй сетку в транзакции. После любого `400` прежние данные должны остаться без изменений.
|
||||
- **№ 11 — ложный зелёный статус дашборда.** Рассчитывай воскресенье как отдельную дату `понедельник + 6 дней`, не используй UTC для date-only значений и разделяй состояния «конфликтов нет», «частичная ошибка проверки» и «проверка не выполнена». Для `2026-07-02` диапазон должен быть `2026-06-29…2026-07-05`; проверь также переход года.
|
||||
- **№ 15 — некорректные временные слоты.** Требуй `startTime < endTime`, запрети пересечения интервалов внутри scope, но разреши соседние интервалы с общей границей. Не разрешай перевод используемого базового слота из `DEFAULT` в `MANUAL`, а продолжительность рассчитывай на backend по `startTime/endTime`. Защити инвариант и от конкурентных записей.
|
||||
- **№ 16 — пересечения учебных лет и семестров.** Централизуй валидацию диапазонов для create/update: запрети пересечения учебных лет, пересечения семестров, выход семестра за границы его года и дубликаты title/type. Добавь DB-ограничения новой миграцией там, где PostgreSQL может надёжно обеспечить инвариант.
|
||||
- **№ 17 — устаревшие назначения календарей.** При изменении ключевых измерений календаря или группы либо безопасно отклоняй несовместимое изменение с `409 Conflict` без изменения данных, либо в одной транзакции перевалидируй назначения, grid и subjects. Уменьшение `courseCount` не должно оставлять строки или дисциплины старших курсов.
|
||||
- **№ 18 — исторические кафедры преподавателя.** Для бизнес-решений и исторических отчётов определяй кафедру через `teacher_department_assignments` на целевую дату. Будущий перевод не должен менять текущую принадлежность раньше `validFrom`, архивный преподаватель должен корректно отображаться в историческом периоде, дополнительные активные назначения должны работать единообразно.
|
||||
- **№ 19 — доступ к workload чужой кафедры.** Для роли `DEPARTMENT` принудительно ограничивай scope кафедрой из `AuthContext`; глобальный просмотр разрешай только явно уполномоченным ролям.
|
||||
- **№ 20 — лимит 50 групп в агрегатах.** Не используй ограничение интерактивного широкого поиска в workload/free-classrooms. Реализуй специализированные агрегирующие запросы или контролируемую batch-обработку и тесты как минимум с 51 и 100 активными группами.
|
||||
- **№ 21 — импорт дисциплины другой кафедры.** Не переназначай чужую запись по совпавшему глобальному имени. Зафиксируй бизнес-правило владения и уникальности; безопасный вариант по умолчанию — `409 Conflict` при совпадении с чужой кафедрой и идемпотентный повторный импорт своей записи. При необходимости введи `(department_id, lower(name))` новой миграцией и обработай существующие данные безопасно.
|
||||
- **№ 22 — несовпадающие права учебного отдела.** Создай единый явно проверяемый role matrix для backend и frontend. Либо выдай `EDUCATION_OFFICE` необходимые права, либо скрой недоступные действия; штатные экраны не должны завершать инициализацию с `403`.
|
||||
- **№ 23 — N+1 при генерации расписания.** Батчем загружай semesters, assignments и calendar days на диапазон, переиспользуй найденные данные и не выполняй запрос на каждую дату/группу/правило. Добавь измеримый query-count тест на диапазоне 120 дней и десятках групп, доказывающий отсутствие роста порядка `дни × группы × правила` при неизменном результате.
|
||||
- **№ 29 — нефиксированный часовой пояс.** Внедри `Clock` и явно настроенный `ZoneId` `Europe/Moscow` для бизнес-дат, используй `Instant`/UTC для абсолютных timestamp, зафиксируй timezone контейнеров и формируй frontend date-only строки из локальных компонентов без `toISOString()`.
|
||||
- **№ 31 — некорректный размер группы.** Используй единый валидатор create/update: `groupSize > 0`, `yearStartStudy > 0`, а также запрет уменьшения ниже суммы активных подгрупп, включая конкурентный сценарий. Добавь новые CHECK constraints отдельной миграцией.
|
||||
- **№ 32 — диапазон в 121 дату.** Проверяй включительную длину диапазона; максимум должен составлять ровно 120 календарных дат. Покрой граничные случаи 120 и 121 дата.
|
||||
|
||||
### Tenant, инфраструктура и поставка
|
||||
|
||||
- **№ 9 — небезопасная замена tenant DataSource.** Создавай временный pool, явно проверяй соединение и Flyway, затем атомарно подменяй рабочий DataSource. Ошибка миграции или сохранения конфигурации должна прерывать операцию и запускать compensating rollback без потери старого подключения.
|
||||
- **№ 10 — lost update ConfigMap и неинформативные probes.** Реализуй optimistic locking по `resourceVersion` с ограниченным retry/backoff либо эквивалентный единый coordinator; параллельные изменения двух pod не должны теряться. Readiness должна учитывать доступность обязательных tenant-БД и успешность миграций, а liveness — только жизнеспособность процесса, чтобы отказ БД не создавал restart storm.
|
||||
- **№ 13 — неполная синхронизация watcher.** Сравнивай весь нормализованный `TenantConfig`, а hash обновляй только после полного успеха. Неудачная синхронизация должна повторяться с ограниченным backoff и наблюдаемым русскоязычным логом.
|
||||
- **№ 26 — нерабочий чистый локальный запуск.** Сделай `docker compose up -d --build` на чистой машине, без заранее созданной внешней сети, достаточным для доступа к приложению по `http://localhost:80` и проксирования `/api` в backend. Согласуй JDBC URL и `POSTGRES_DB`, передай JWT-настройки, добавь именованный volume и обнови quick start.
|
||||
- **№ 27 — deployment без тестов и неверный tag rollout.** Добавь обязательные backend/frontend/static/config проверки до build/push/deploy, concurrency lock и проверяемый rollback. Для релизного tag разворачивай конкретный tag или digest, а не перезапускай mutable `:main`.
|
||||
- **№ 30 — mutable и непроверяемые артефакты.** Зафиксируй версии и digest базовых/сторонних образов и инструментов, проверяй SHA256/signature скачиваемых бинарников, формируй SBOM и добавь сканирование образов. В production не должно остаться `latest` и `:main`; обновление версии должно быть явным и воспроизводимым.
|
||||
|
||||
## Архитектурные требования к реализации
|
||||
|
||||
- Транзакционные границы должны находиться на вызываемых Spring proxy-методах; не рассчитывай на `@Transactional` при self-invocation или пойманном внутри исключении.
|
||||
- Для конкурентных сценариев используй гарантии PostgreSQL и проверяй их интеграционными тестами, а не только синхронизацией внутри одного JVM-процесса.
|
||||
- Все операции с tenant-конфигурацией должны быть идемпотентными и безопасными при двух pod.
|
||||
- Не смешивай date-only и timestamp. Date-only передавай как `YYYY-MM-DD` без UTC-конвертации.
|
||||
- Сохраняй обратную совместимость API там, где она не противоречит безопасности. Если контракт необходимо изменить, синхронно обнови backend, frontend, тесты и `docs/API.md`.
|
||||
- Не дублируй сложные бизнес-правила по контроллерам. Выноси общую валидацию/логику в переиспользуемые компоненты в соответствии с текущей архитектурой проекта.
|
||||
- Избегай массовых косметических рефакторингов, не относящихся к отчёту. Каждое существенное изменение должно сопоставляться с одним или несколькими номерами проблем.
|
||||
- Не выполняй `docker compose down -v`, массовое удаление данных и другие необратимые операции. Интеграционные тесты должны использовать изолированные временные ресурсы.
|
||||
|
||||
## Обязательные тесты и проверки
|
||||
|
||||
Добавь регрессионные тесты для каждого исправленного поведения. В первую очередь обязательно покрой:
|
||||
|
||||
1. PostgreSQL/Testcontainers и Flyway: чистая схема и upgrade существующей схемы — **без проверки и изменения поведения из проблемы № 2**.
|
||||
2. Два параллельных refresh-запроса с одним токеном: успех только одного.
|
||||
3. Последовательность `403`, затем публичный/защищённый запрос на одном потоке без утечки `AuthContext`.
|
||||
4. Override с конфликтом и расписание преподавателя, назначенного через `newTeacher`.
|
||||
5. Внутренние конфликты нового правила, неверная роль, нечётные часы и недопустимый формат.
|
||||
6. Атомарность `saveGrid`: после ошибочного payload старая сетка полностью сохранена.
|
||||
7. Изменение tenant URL/credentials, неудачная миграция, неудачный ConfigMap update и параллельные PATCH от двух pod.
|
||||
8. Более 50 активных групп для workload/free-classrooms.
|
||||
9. Будущий перевод преподавателя и исторические отчёты.
|
||||
10. E2E или эквивалентный интеграционный сценарий `EDUCATION_OFFICE` для календарных графиков и форм обучения.
|
||||
11. Frontend-даты в первые дни месяца и в интервале 00:00–03:00 `Europe/Moscow`.
|
||||
12. Граничные диапазоны 120/121 дата, XSS payload в ошибке, rate limit и cleanup refresh-токенов.
|
||||
|
||||
После реализации выполни доступные проверки и зафиксируй фактический результат каждой команды:
|
||||
|
||||
```bash
|
||||
mvn -f backend/pom.xml test
|
||||
find frontend -type f -name '*.js' -print0 | xargs -0 -n1 node --check
|
||||
docker compose config --quiet
|
||||
docker compose build backend frontend
|
||||
kubectl kustomize ../k8s >/dev/null
|
||||
bash -n ../k8s/deploy.sh
|
||||
git diff --check
|
||||
git diff --stat
|
||||
git status --short
|
||||
```
|
||||
|
||||
Команду для `../k8s/deploy.sh` выполняй только если файл существует. Если локального Maven, Node, Docker или kubectl нет либо сборке нужен недоступный network/daemon, используй уже принятый в проекте контейнерный эквивалент либо честно укажи, какую проверку невозможно запустить и почему. Не называй непроверенный результат успешным. Успешный Docker build не заменяет `mvn test`.
|
||||
|
||||
Дополнительно проверь:
|
||||
|
||||
- отсутствие секретов и placeholder credentials в отслеживаемых production-файлах;
|
||||
- отсутствие изменений существующих Flyway-миграций;
|
||||
- согласованность новых миграций с JPA-моделями и upgrade-путём всех tenant-БД;
|
||||
- отсутствие сырых exception messages в HTTP-ответах;
|
||||
- соответствие backend/frontend role matrix;
|
||||
- отсутствие `localStorage`/`sessionStorage` для access JWT, удалённых исполняемых модулей и исполняемого inline JavaScript, несовместимого со строгим CSP;
|
||||
- воспроизводимость Docker/CI/Kubernetes-конфигурации;
|
||||
- отсутствие английских пользовательских сообщений и production-логов в изменённых областях.
|
||||
- отдельный список и содержательную проверку всех изменений в `../k8s/`, поскольку они не видны в Git diff проекта.
|
||||
|
||||
## Документация
|
||||
|
||||
После кода и тестов обнови только относящуюся к изменениям документацию, в том числе при необходимости:
|
||||
|
||||
- `docs/API.md`;
|
||||
- `docs/DATABASE.md`;
|
||||
- `docs/ARCHITECTURE.md`;
|
||||
- `docs/BUSINESS_LOGIC.md`;
|
||||
- `docs/FRONTEND.md`;
|
||||
- `docs/INFRASTRUCTURE.md`;
|
||||
- `docs/LOGGING.md`;
|
||||
- `docs/README.md` и корневой quick start.
|
||||
|
||||
Документация должна описывать фактическое поведение после изменений. Не документируй проблему № 2 как исправленную и не меняй инструкции по demo-аккаунтам в рамках этой задачи.
|
||||
|
||||
## Формат итогового ответа
|
||||
|
||||
Ответ дай на русском языке и начни с результата. Включи:
|
||||
|
||||
1. Таблицу по всем пунктам `1, 3–34`: номер, краткое исправление, основные файлы, тест/проверка, статус.
|
||||
2. Список созданных Flyway-миграций и подтверждение, что существующие миграции не изменены.
|
||||
3. Фактически выполненные команды и их результаты.
|
||||
4. Изменения API, конфигурации, role matrix и deployment-процесса.
|
||||
5. Отдельный раздел «Требуемые действия оператора» для ротации секретов, очистки истории, настройки secret manager, production rollout и других действий, которым нужен внешний доступ. Не утверждай, что они выполнены.
|
||||
6. Оставшиеся риски или проверки, которые невозможно выполнить локально.
|
||||
7. Подтверждение, что проблема № 2 не затрагивалась.
|
||||
|
||||
Перед финальным ответом ещё раз прочитай `BUG_REPORT.md` и сравни чек-лист с точным множеством `{1} ∪ {3..34}`. В итоговой таблице должно быть ровно 33 строки без пропущенных или повторяющихся ID. У каждого пункта должны быть реализация либо доказательство уже существующего исправления, регрессионная проверка и честный статус.
|
||||
|
||||
Критерий завершения: каждый пункт № 1 и № 3–34 имеет реализацию и регрессионную проверку либо явно отделённое внешнее действие; все доступные тесты проходят; документация соответствует коду; проблема № 2 и существующие Flyway-миграции не изменены.
|
||||
Reference in New Issue
Block a user