docs/chore: Phase 1 doc/code hygiene (code-review.md § Phase 1)
Removes ~30 stale "Phase N" / historical-staging comment references from code and shell scripts now that v1.0 is done; fixes a stale dashboard comment claiming applications/send-log were unimplemented; adds a CSRF ADR to security.md documenting the Origin-check-over-tokens decision; resolves docs/logo in roadmap.md (directory doesn't exist, criterion already met); adds a gofmt -l check to CI so unformatted Go fails the build. The known-limitations write-up for the log-tailer offset gap (the other Phase 1 item) was already present in architecture.md § Log tailer, so no change was needed there. gofmt/go vet/go test clean on both Go modules (main + test/e2e), verified on the dev server. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,36 @@ Hardening сверх обязательного (security-заголовки, п
|
||||
`/data` и теряется при recreate. Rename-ротация это не лечит. См. [architecture.md](architecture.md)
|
||||
§ Log tailer — known gaps.
|
||||
|
||||
## ADR: CSRF через проверку Origin, без токенов
|
||||
|
||||
**Контекст.** Панель — формы (`POST`) с cookie-сессией; классическая CSRF-
|
||||
поверхность. Нужен способ отличить запрос со страницы панели от запроса,
|
||||
инициированного сторонним сайтом в браузере залогиненного админа.
|
||||
|
||||
**Решение.** `originAllowed` в
|
||||
[internal/web/security.go](../internal/web/security.go) сверяет `Sec-Fetch-Site`
|
||||
(если браузер его шлёт) либо `Origin` (fallback) с хостом панели; запрос без
|
||||
обоих заголовков **пропускается**, а не отклоняется. Токенов, привязанных к
|
||||
сессии и встроенных в формы, нет.
|
||||
|
||||
**Почему не токены.** Панель однопользовательская (один администратор на
|
||||
инстанс) — модель угроз не включает межпользовательский CSRF внутри самой
|
||||
панели, только внешний сайт, заставляющий браузер админа отправить запрос.
|
||||
Origin-проверка закрывает это без изменения ни одного шаблона: токен потребовал
|
||||
бы скрытого поля примерно в двух десятках форм и синхронизации при каждой
|
||||
новой форме, а от XSS внутри панели токен всё равно не защищает — код,
|
||||
исполняющийся в origin панели, читает токен и отправляет запрос сам. От XSS
|
||||
защищают автоэкранирование `html/template` и CSP, поэтому это отдельная линия
|
||||
обороны, не CSRF-токен.
|
||||
|
||||
**Компромисс.** Клиент, не посылающий ни `Sec-Fetch-Site`, ни `Origin`
|
||||
(по-настоящему старый браузер или webview с замороженным движком), остаётся
|
||||
уязвим — см. «Принятые риски» выше. Это осознанный выбор в пользу не ломать
|
||||
панель в таком клиенте ценой узкой остаточной поверхности.
|
||||
|
||||
**Пересмотр, если:** появится требование защиты, не зависящей от поведения
|
||||
браузера, или панель станет многопользовательской.
|
||||
|
||||
## Как этот список пополняется
|
||||
|
||||
Предрелизная проверка на уязвимости ([implementation-plan.md](implementation-plan.md)
|
||||
|
||||
Reference in New Issue
Block a user