fix(config): F-C2-1 — stop os.ExpandEnv corrupting the bcrypt password_hash (v0.103.0)
loadAndParse + LoadFromBytes ran os.ExpandEnv over the whole YAML before parse; a bcrypt hash ($2a$10$...) is full of $word sequences that get replaced with empty env values, silently corrupting web.password_hash on load (a silent auth-integrity bug: $2a$10$N9qo8uL... -> "a0"). Remove both ExpandEnv calls; parse raw bytes. The typed applyEnvOverrides path (FELHOM_WEB_PASSWORD_HASH) is the sanctioned env mechanism and is unchanged. Tests + red-proof. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1,5 +1,23 @@
|
||||
## Changelog
|
||||
|
||||
### v0.103.0 — F-C2-1: config loader no longer corrupts a bcrypt password_hash (silent auth bug) (2026-07-07)
|
||||
|
||||
Fixes campaign-2 finding **F-C2-1** (`felhom.eu/documentation/tests/CAMPAIGN-2-2026-07-07.md`).
|
||||
`loadAndParse` and `LoadFromBytes` ran `os.ExpandEnv` over the **entire** YAML before parse. A bcrypt
|
||||
hash (`$2a$10$…`) is full of `$word` sequences, so `ExpandEnv` silently replaced each with its (usually
|
||||
empty) env value — corrupting `web.password_hash` on load (proven: `$2a$10$N9qo8uL…` → `"a0"`). A silent
|
||||
auth-integrity bug.
|
||||
|
||||
- **Fix:** removed both `os.ExpandEnv` calls (`config.go` :234 loadAndParse, :249 LoadFromBytes) — parse
|
||||
the raw bytes directly. The sanctioned, typed env path (`applyEnvOverrides` → `FELHOM_WEB_PASSWORD_HASH`,
|
||||
applied after parse) is unchanged; no shipped `controller.yaml` relies on file-level `${VAR}`
|
||||
interpolation (only `docker-compose.yml` uses `${DOMAIN}`, which is compose-level).
|
||||
- **Behavior change:** a literal `${VAR}` in a controller.yaml value is now preserved verbatim (was
|
||||
expanded). No repo config depends on the old behavior.
|
||||
- Tests (`config_test.go`): bcrypt hash loads byte-identical (file + bytes paths; red-proof: pre-fix
|
||||
`ExpandEnv` mangles it to `"a0"` → FAIL, demonstrated + reverted); `FELHOM_WEB_PASSWORD_HASH` override
|
||||
still wins; literal `${VAR}` preserved.
|
||||
|
||||
### v0.102.0 — async restore family: no more proxy-timeout error page on a succeeding restore (2026-07-06)
|
||||
|
||||
Re-adjudicates campaign **F4** (`felhom.eu/documentation/audits/RERUN-p1p3-2026-07-06.md`): all three
|
||||
|
||||
Reference in New Issue
Block a user