docs: move the accepted security risks into docs/security.md

The plan holds undone work; an accepted risk is a decision, not a task
— it has no place in a queue, only a condition for revisiting it. Both
risks (POST with neither Sec-Fetch-Site nor Origin, no session-bound
CSRF tokens) move verbatim into a new docs/security.md, which also
states where D.5 findings land. Section letters and item numbering in
the plan stay as they were, since progress.md and the commit history
reference them; a note in their place points at the new file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 23:12:50 +03:00
parent a1160e0fb8
commit 750a65d5ee
4 changed files with 51 additions and 27 deletions
+5 -22
View File
@@ -17,27 +17,10 @@
пункт — решение «делаем в v1.x / откладываем в 2.x / оставляем как есть»,
принимается пользователем.
### A. Безопасность — принятые риски
Hardening сверх обязательного 7.6 закрыт. Здесь остаётся только то, что закрыто
**сознательно не было**, чтобы это не потерялось:
- **Принятый риск: `POST` без `Sec-Fetch-Site` и без `Origin` пропускается.**
Клиент, не посылающий ни одного из двух — по-настоящему старый браузер или
webview с замороженным движком, — остаётся уязвим к CSRF с любого сайта.
Принято сознательно: панель однопользовательская, админ выбирает браузер
сам, а строгий режим не «защитил бы» такой клиент, а просто сломал бы в нём
панель. Ужесточение — одна строка в `originAllowed`
([internal/web/security.go](../internal/web/security.go)): вернуть `false`
вместо `true` в ветке «нет обоих заголовков».
- **CSRF-токены, привязанные к сессии, не делаются.** Проверка origin
закрывает соседний поддомен, но зависит от поведения браузера; токен — нет.
Цена — скрытое поле примерно в двух десятках форм. Триггером вернуться к
вопросу считать появление требования «устойчиво независимо от браузера».
От XSS внутри самой панели не спас бы и токен: код, исполняющийся в origin
панели, отправит запрос сам — против этого работают автоэкранирование
`html/template` (7.6.7) и CSP, поэтому шаблоны не должны содержать
inline-скриптов и inline-стилей.
**Раздел A (принятые риски безопасности) переехал в
[security.md](security.md)** — риск не задача, а решение, и в плане несделанной
работы ему делать нечего. Буквы разделов и сквозная нумерация пунктов ниже
оставлены как были: на них ссылаются `progress.md`, коммиты и обсуждения.
### B. Надёжность и эксплуатация
@@ -132,7 +115,7 @@ Hardening сверх обязательного 7.6 закрыт. Здесь о
**Модель — Fable, и это сознательно не Opus:** B и C пишет Opus, а проверка собственной работы систематически слабее независимой. Правило progress.md «безопасность/инфра → Opus» этим не отменяется — оно про написание кода, здесь речь про ревизию. Форма прогона: `/security-review` по изменениям, пока они ещё в ветке (скилл смотрит диф), плюс отдельный ручной проход по 7.6 целиком.
**Что с находками.** Каждая закрывается явно: правка до тега либо запись в раздел A как принятый риск с обоснованием (там уже два таких). «Посмотрели и ладно» закрытием не считается. **Гейт:** вместе с e2e из C.4 — до тега; находка класса «эксплуатируется снаружи» тег откладывает.
**Что с находками.** Каждая закрывается явно: правка до тега либо запись в [security.md](security.md) как принятый риск с обоснованием (там уже два таких). «Посмотрели и ладно» закрытием не считается. **Гейт:** вместе с e2e из C.4 — до тега; находка класса «эксплуатируется снаружи» тег откладывает.
### E. Указатель на объём 2.x