fix(metrics): маскировать секреты из query-строки в Alloy до отправки в Loki
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
Скруббер #3115 знал одну форму — пароль в DSN (scheme://user:pass@host). Секрет в query-строке (`?secret=<64 hex>` вебхука GlitchTip, #3154) проходил насквозь и оседал в Loki на 30 суток ретенции. Приложение чистит это у себя (#3353), но фильтр стоит на логгере ОДНОГО процесса. Второй слой на сборщике закрывает всё, что придёт мимо: sidecar, чужой процесс, будущий логгер без фильтра. Множество имён параметров взято из log_scrub.py дословно, включая суффиксные client_secret/refresh_token. Группа захвата стоит на значении, а не на имени параметра: Alloy заменяет содержимое ГРУПП, а не весь совпавший фрагмент. Группа вокруг `?secret=` затёрла бы имя и оставила сам секрет — то есть ровно наоборот. Стадия добавлена и в alloy-infra.alloy: на инфра-хосте Forgejo и GlitchTip с их `?token=` в адресах пишут в тот же Loki, дефект там тот же. Closes #3354
This commit is contained in:
parent
357c4348ac
commit
ed71292f03
2 changed files with 32 additions and 0 deletions
|
|
@ -172,6 +172,26 @@ loki.process "scrub_credentials" {
|
|||
expression = "://[^:@/ ]+:([^@ ]+)@"
|
||||
replace = "***"
|
||||
}
|
||||
|
||||
// ── Секреты в query-строке (#3354) ─────────────────────────────────────────
|
||||
// Прод-факт (#3154): uvicorn пишет в access-log ПОЛНЫЙ путь с query, и туда
|
||||
// уезжал `?secret=<64 hex>` вебхука GlitchTip. Приложение чистит это у себя
|
||||
// (tradein-mvp/backend/app/core/log_scrub.py), здесь — второй слой на случай
|
||||
// строки, пришедшей мимо фильтра: другой процесс, sidecar, будущий логгер.
|
||||
//
|
||||
// Множество имён держим ОДИНАКОВЫМ с log_scrub.py. Префикс `[\w.-]*` перед
|
||||
// альтернацией — ради суффиксных имён (`client_secret`, `refresh_token`,
|
||||
// `webhook_secret`); значение обрывается на `&`, пробеле или кавычке, потому
|
||||
// что access-строка uvicorn обрамляет запрос кавычками.
|
||||
//
|
||||
// Группа захвата стоит на ЗНАЧЕНИИ, а не на имени параметра: Alloy заменяет
|
||||
// содержимое групп, а не весь совпавший фрагмент (ровно как у DSN выше — там
|
||||
// группа на пароле, поэтому пользователь и хост уцелевают). Обернуть группой
|
||||
// `?secret=` значило бы затереть имя и оставить сам секрет.
|
||||
stage.replace {
|
||||
expression = "(?i)[?&][\\w.-]*(?:secret|token|api[-_]?key|apikey|access[-_]?token|password|signature|sig)=([^&\\s\"'<>]+)"
|
||||
replace = "***"
|
||||
}
|
||||
}
|
||||
|
||||
loki.relabel "journal" {
|
||||
|
|
|
|||
|
|
@ -131,6 +131,18 @@ loki.process "scrub_credentials" {
|
|||
expression = "://[^:@/ ]+:([^@ ]+)@"
|
||||
replace = "***"
|
||||
}
|
||||
|
||||
// ── Секреты в query-строке (#3354) ─────────────────────────────────────────
|
||||
// То же выражение, что в alloy-apps.alloy, и по той же причине — подробности
|
||||
// там. Здесь оно нужно не меньше: на инфра-хосте живут Forgejo и GlitchTip,
|
||||
// у обоих есть ручки с `?token=` в адресе, и их логи идут в тот же Loki.
|
||||
//
|
||||
// Группа захвата — на ЗНАЧЕНИИ: Alloy заменяет содержимое групп, а не весь
|
||||
// совпавший фрагмент (как у DSN выше, где группа на пароле).
|
||||
stage.replace {
|
||||
expression = "(?i)[?&][\\w.-]*(?:secret|token|api[-_]?key|apikey|access[-_]?token|password|signature|sig)=([^&\\s\"'<>]+)"
|
||||
replace = "***"
|
||||
}
|
||||
}
|
||||
|
||||
loki.relabel "journal" {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue