Compare commits
1 Commits
b1c66b8227
...
7923146db9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7923146db9 |
64
README.md
64
README.md
@@ -77,24 +77,34 @@ The environment is selected by setting `WEBHOOKER_ENVIRONMENT` to `dev`
|
|||||||
or `prod` (default: `dev`). The setting controls several behaviors:
|
or `prod` (default: `dev`). The setting controls several behaviors:
|
||||||
|
|
||||||
| Behavior | `dev` | `prod` |
|
| Behavior | `dev` | `prod` |
|
||||||
| --------------------- | -------------------------------- | ------------------------------- |
|
| -------- | ----------------------- | ---------------- |
|
||||||
| CORS | Allows any origin (`*`) | Disabled (no-op) |
|
| CORS | Allows any origin (`*`) | Disabled (no-op) |
|
||||||
| Session cookie Secure | `false` (works over plain HTTP) | `true` (requires HTTPS) |
|
|
||||||
|
|
||||||
The CSRF cookie's `Secure` flag and Origin/Referer validation mode are
|
The environment setting does **not** control cookie security. Both the
|
||||||
determined per-request based on the actual transport protocol, not the
|
session cookie and the CSRF cookie get their `Secure` flag, and the
|
||||||
environment setting. The middleware checks `r.TLS` (direct TLS) and the
|
CSRF middleware its Origin/Referer validation mode, from the transport
|
||||||
`X-Forwarded-Proto` header (TLS-terminating reverse proxy) to decide:
|
of each individual request, decided by one predicate —
|
||||||
|
`internal/reqtls.IsTLS`. It reports TLS for a direct TLS connection
|
||||||
|
(`r.TLS`) or for a TLS-terminating reverse proxy that reports one in
|
||||||
|
`X-Forwarded-Proto`:
|
||||||
|
|
||||||
- **Direct TLS or `X-Forwarded-Proto: https`**: Secure cookies, strict
|
- **Direct TLS or `X-Forwarded-Proto: https`**: Secure cookies, strict
|
||||||
Origin/Referer validation.
|
Origin/Referer validation.
|
||||||
- **Plaintext HTTP**: Non-Secure cookies, relaxed Origin/Referer
|
- **Plaintext HTTP**: Non-Secure cookies, relaxed Origin/Referer
|
||||||
checks (token validation still enforced).
|
checks (token validation still enforced).
|
||||||
|
|
||||||
This means CSRF protection works correctly in all deployment scenarios:
|
The `X-Forwarded-Proto` value is matched case-insensitively on its
|
||||||
behind a TLS-terminating reverse proxy, with direct TLS, or over plain
|
first comma-separated element, trimmed, so `HTTPS` and the appended
|
||||||
HTTP during development. When running behind a reverse proxy, ensure it
|
chains a proxy behind another proxy emits (`https, http`) are all read
|
||||||
sets the `X-Forwarded-Proto: https` header.
|
as TLS.
|
||||||
|
|
||||||
|
This means both cookie security and CSRF protection work correctly in
|
||||||
|
all deployment scenarios: behind a TLS-terminating reverse proxy, with
|
||||||
|
direct TLS, or over plain HTTP during development — a plain-HTTP local
|
||||||
|
run gets non-`Secure` cookies and remains usable, and a proxied
|
||||||
|
deployment gets `Secure` ones without the operator setting anything.
|
||||||
|
When running behind a reverse proxy, ensure it sets the
|
||||||
|
`X-Forwarded-Proto: https` header.
|
||||||
|
|
||||||
All other differences (log format, security headers, etc.) are
|
All other differences (log format, security headers, etc.) are
|
||||||
independent of the environment setting — log format is determined by
|
independent of the environment setting — log format is determined by
|
||||||
@@ -1853,13 +1863,16 @@ the rest. Nothing dropped is needed for the likeliest use, debugging a
|
|||||||
CSRF rejection. Its three inputs are the TLS decision, `Origin` and
|
CSRF rejection. Its three inputs are the TLS decision, `Origin` and
|
||||||
`Referer`; the latter two are kept, and the first is the scheme of the
|
`Referer`; the latter two are kept, and the first is the scheme of the
|
||||||
retained URL, because the SDK derives that scheme from
|
retained URL, because the SDK derives that scheme from
|
||||||
`r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https"` — byte
|
`r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https"`. That
|
||||||
for byte the predicate `internal/middleware/csrf.go` uses to choose
|
predicate is the SDK's own and is stricter than `internal/reqtls.IsTLS`,
|
||||||
between the `csrf.Secure(true)` and `csrf.Secure(false)` handlers.
|
which this service now uses everywhere it decides transport: the SDK
|
||||||
That is what the rewrite above preserves it for, and it is why
|
reports `http` for the `HTTPS` and `https, http` spellings `reqtls`
|
||||||
dropping `X-Forwarded-Proto` costs nothing. The dropped provider
|
accepts. Only a reported scheme is affected, no decision is, so it is
|
||||||
headers (`X-GitHub-Event`, `X-Gitlab-Event` and the like) are real
|
left to the SDK rather than reimplemented. That is what the rewrite
|
||||||
signal but are recorded locally on the event, and
|
above preserves it for, and it is why dropping `X-Forwarded-Proto`
|
||||||
|
costs nothing. The dropped provider headers (`X-GitHub-Event`,
|
||||||
|
`X-Gitlab-Event` and the like) are real signal but are recorded
|
||||||
|
locally on the event, and
|
||||||
`Sentry-Trace`/`Baggage` are already reflected in the event's trace
|
`Sentry-Trace`/`Baggage` are already reflected in the event's trace
|
||||||
context.
|
context.
|
||||||
|
|
||||||
@@ -2515,8 +2528,9 @@ check, see [The login endpoint](#the-login-endpoint).
|
|||||||
|
|
||||||
- **Web UI:** Cookie-based sessions using gorilla/sessions with
|
- **Web UI:** Cookie-based sessions using gorilla/sessions with
|
||||||
encrypted cookies. Sessions are configured with HttpOnly, SameSite
|
encrypted cookies. Sessions are configured with HttpOnly, SameSite
|
||||||
Lax, and Secure (in production). Absolute session lifetime is 7 days,
|
Lax, and Secure whenever the request is on TLS — the flag follows the
|
||||||
with a sliding idle timeout on top of it (see
|
request's transport, not the environment. Absolute session lifetime
|
||||||
|
is 7 days, with a sliding idle timeout on top of it (see
|
||||||
[Sessions](#sessions)).
|
[Sessions](#sessions)).
|
||||||
- **API (planned):** API key authentication via `Authorization: Bearer`
|
- **API (planned):** API key authentication via `Authorization: Bearer`
|
||||||
header. API keys are stored per-user with usage tracking
|
header. API keys are stored per-user with usage tracking
|
||||||
@@ -2529,7 +2543,10 @@ check, see [The login endpoint](#the-login-endpoint).
|
|||||||
### Security
|
### Security
|
||||||
|
|
||||||
- Passwords hashed with Argon2id (64 MB memory cost)
|
- Passwords hashed with Argon2id (64 MB memory cost)
|
||||||
- Session cookies are HttpOnly, SameSite Lax, Secure (prod only)
|
- Session cookies are HttpOnly, SameSite Lax, and Secure on any request
|
||||||
|
that arrived over TLS (directly or through a reverse proxy reporting
|
||||||
|
it), decided per-request by `internal/reqtls.IsTLS` rather than by the
|
||||||
|
configured environment
|
||||||
- Session regeneration on login to prevent session fixation attacks
|
- Session regeneration on login to prevent session fixation attacks
|
||||||
- Session key is a 32-byte value auto-generated on first startup and
|
- Session key is a 32-byte value auto-generated on first startup and
|
||||||
stored in the database
|
stored in the database
|
||||||
@@ -2542,9 +2559,10 @@ check, see [The login endpoint](#the-login-endpoint).
|
|||||||
on all state-changing forms (cookie-based double-submit tokens with
|
on all state-changing forms (cookie-based double-submit tokens with
|
||||||
HMAC authentication). Applied to `/pages`, `/sources`, `/source`, and
|
HMAC authentication). Applied to `/pages`, `/sources`, `/source`, and
|
||||||
`/user` routes. Excluded from `/webhook` (inbound webhook POSTs) and
|
`/user` routes. Excluded from `/webhook` (inbound webhook POSTs) and
|
||||||
`/api` (stateless API). The middleware auto-detects TLS status
|
`/api` (stateless API). The middleware detects TLS per-request through
|
||||||
per-request (via `r.TLS` and `X-Forwarded-Proto`) to set appropriate
|
`internal/reqtls.IsTLS` — the same predicate the session cookie uses —
|
||||||
cookie security flags and Origin/Referer validation mode
|
to set appropriate cookie security flags and Origin/Referer validation
|
||||||
|
mode
|
||||||
- **Optional inbound signature verification** per entrypoint (GitHub
|
- **Optional inbound signature verification** per entrypoint (GitHub
|
||||||
`X-Hub-Signature-256`, GitLab `X-Gitlab-Token`). Off by default and
|
`X-Hub-Signature-256`, GitLab `X-Gitlab-Token`). Off by default and
|
||||||
off after an upgrade, so behaviour is unchanged until an operator
|
off after an upgrade, so behaviour is unchanged until an operator
|
||||||
|
|||||||
Reference in New Issue
Block a user