Sécurité : purge désactivée par défaut, rôle lecture seule, en-têtes et limites TCP #16

Merged
claude Bot merged 1 commits from feat/securite into main 2026-10-03 16:39:50 +02:00

Requested by Cédric

Before: with AUTH_USER empty (the default), anyone on the network could read every log, change the sources and purge everything (ALLOW_PURGE=true), with no warning in the UI. Every logged-in user had full rights. There were no security headers, a third-party page could send changes from the browser (CSRF), and syslog TCP accepted unlimited connections that never timed out.

After: purge is off unless ALLOW_PURGE=true. Without authentication, the UI shows a warning banner (it can be closed). A read-only role can search, follow the live view and export, but cannot change tags, sources or purge: the API answers 403 and those settings are greyed out. Answers carry a CSP and the usual security headers, and cross-site changes are refused. Syslog TCP keeps at most 512 connections and closes one after 30 minutes of silence.

How:

  • guard.go: secure() adds the headers, rejects non-GET requests whose Sec-Fetch-Site or Origin shows another site (curl and scripts send neither and keep working), and answers /auth/me with mode: none when there is no auth. readOnly() refuses API changes from viewers. The CSP allows the inline scripts of index.html and login.html by hash, computed at startup from the embedded files.
  • Local mode: optional AUTH_VIEWER_USER / AUTH_VIEWER_PASS, also usable with Basic auth. OIDC: OIDC_ADMIN_GROUP (+ OIDC_GROUPS_CLAIM, default groups, Keycloak's leading / ignored). The role is stored in the signed session cookie; existing sessions stay admin.
  • SYSLOG_TCP_MAX_CONNS (512) and SYSLOG_TCP_IDLE (30m, a sliding read deadline); HTTP IdleTimeout of 2 min.
  • .env.example, docker-compose.yml and both READMEs updated.
  • Tests: headers and cross-site cases, CSP hashes, local viewer (session and Basic), OIDC admin group, TCP idle deadline. go test -race passes.

Note: ALLOW_PURGE now defaults to false. A deployment that relied on the old default must set ALLOW_PURGE=true in .env.

🤖 Generated with Claude Code

<!-- ccr-projects-attribution: {"github_login":"vblogio"} --> _Requested by **Cédric**_ Before: with `AUTH_USER` empty (the default), anyone on the network could read every log, change the sources and purge everything (`ALLOW_PURGE=true`), with no warning in the UI. Every logged-in user had full rights. There were no security headers, a third-party page could send changes from the browser (CSRF), and syslog TCP accepted unlimited connections that never timed out. After: purge is off unless `ALLOW_PURGE=true`. Without authentication, the UI shows a warning banner (it can be closed). A read-only role can search, follow the live view and export, but cannot change tags, sources or purge: the API answers 403 and those settings are greyed out. Answers carry a CSP and the usual security headers, and cross-site changes are refused. Syslog TCP keeps at most 512 connections and closes one after 30 minutes of silence. How: - `guard.go`: `secure()` adds the headers, rejects non-GET requests whose `Sec-Fetch-Site` or `Origin` shows another site (curl and scripts send neither and keep working), and answers `/auth/me` with `mode: none` when there is no auth. `readOnly()` refuses API changes from viewers. The CSP allows the inline scripts of `index.html` and `login.html` by hash, computed at startup from the embedded files. - Local mode: optional `AUTH_VIEWER_USER` / `AUTH_VIEWER_PASS`, also usable with Basic auth. OIDC: `OIDC_ADMIN_GROUP` (+ `OIDC_GROUPS_CLAIM`, default `groups`, Keycloak's leading `/` ignored). The role is stored in the signed session cookie; existing sessions stay admin. - `SYSLOG_TCP_MAX_CONNS` (512) and `SYSLOG_TCP_IDLE` (30m, a sliding read deadline); HTTP `IdleTimeout` of 2 min. - `.env.example`, `docker-compose.yml` and both READMEs updated. - Tests: headers and cross-site cases, CSP hashes, local viewer (session and Basic), OIDC admin group, TCP idle deadline. `go test -race` passes. Note: `ALLOW_PURGE` now defaults to false. A deployment that relied on the old default must set `ALLOW_PURGE=true` in `.env`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude Bot added 1 commit 2026-10-03 16:30:51 +02:00
- ALLOW_PURGE is now false by default; the UI shows a banner when there is
  no authentication.
- Read-only role: AUTH_VIEWER_USER/AUTH_VIEWER_PASS in local mode, or
  OIDC_ADMIN_GROUP in OIDC mode; changes get 403 and the admin settings
  are greyed out.
- Content-Security-Policy (inline scripts allowed by hash) and other
  security headers; cross-site changes are refused.
- Syslog TCP: at most SYSLOG_TCP_MAX_CONNS connections, closed after
  SYSLOG_TCP_IDLE of silence; HTTP idle timeout.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
claude Bot marked the pull request as ready for review 2026-10-03 16:39:31 +02:00
claude Bot merged commit 2f84bc8deb into main 2026-10-03 16:39:50 +02:00
claude Bot deleted branch feat/securite 2026-10-03 16:39:50 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vLab-BZH/logstream#16