You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[P2][security] Credential host allowlist is config-author-controlled: add an operator-controlled allowlist (follow-up to #2086/#1977) #2103
Follow-up to #2086 / #1977, found while auditing the #2086 fix (epic epic/security-zero-2026-10-19, local branch, not pushed yet).
Finding
The credential-host gate introduced by #1977 (REST) and extended by #2086 (all non-REST targets and findings_sink) has two parts:
Env-name prefix (DATA_BOAR_, REST_API_, API_): limits which process env vars a config can copy into a credential. This one has teeth against a config author.
Explicit destination allowlist (allowed_hosts): read from the same YAML the config author writes. An author who can set pass_from_env and host can also set allowed_hosts: [<their host>], so this part is a speed bump, not an independent control.
Net effect: anyone who can write the scan YAML (partner snippet, config_admin, dashboard with require_api_key: false) can still send any env var that carries an allowed prefix (for example DATA_BOAR_* or API_* secrets) to a host they control, by listing that host in allowed_hosts.
Suggested direction (recommendation, not a decision)
Add an operator-controlled allowlist that the config author cannot edit: for example a process env var (DATA_BOAR_CREDENTIAL_ALLOWED_HOSTS) or a separate trusted file outside the scanned/edited YAML. A destination is accepted only if it is in the operator list; the in-config allowed_hosts can only narrow it, never widen it.
Fail closed when the operator list is unset and a target uses any *_from_env credential (with a documented migration path and an explicit opt-out for lab setups).
Audit comment after #2115 (merged 2026-10-21 02:15 UTC, 6bdb4ad). Read-only review of main; nothing was run against a live instance.
#2115 deliberately leaves this issue open because allowed_hosts is a brake on the same YAML. Agreed on that point.
Class of problem (details withheld until the fix is merged). The env-name prefix rule (CREDENTIAL_ENV_PREFIXES in config/loader.py) is documented in docs/SECURITY.md as the control that is independent of the config author. The prefix namespace is shared with names that Boar itself reads from the environment, so the prefix alone does not separate operator-supplied credentials from Boar-internal values. Specific names and the reachable path are intentionally not listed in this public thread.
Smallest change that restores the independence the docs claim (executor's choice): make the separation explicit (an explicit deny-list of Boar-internal names, or a distinct prefix for operator credentials), plus a test generated from a source scan of the names Boar reads from the environment, so the list cannot drift.
Docs drift in the same area.docs/TECH_GUIDE.md:396 and docs/SECURITY.md:37 disagree on whether non-REST *_from_env names are subject to the prefix rule; one of them is stale.
Note for contributors and LLM agents: do not describe attack vectors, exploit recipes, concrete secret or variable names, or step-by-step reachable paths in public issues or comments before the fix is merged. State the class of problem, the affected component, and the acceptance criteria; keep the detail in the private tracker or hand it to the maintainer. Technical detail can go into the fix PR, where the repair is being reviewed.
Provenance: git 6bdb4ad, read only. Triage before fix.
Nota de desenho, em classe. A lista do operador fica fora do YAML. A lista escrita no YAML só estreita; não amplia. O mesmo helper em config/loader.py cobre REST, não-REST e findings_sink.
Antes de codar: quando a lista do operador não está definida, instalações que já usam credencial via ambiente continuam como hoje, ou passam a falhar fechado com um opt-out documentado? Essa escolha muda o padrão das instalações existentes. Não implemento até a resposta.
Nota de desenho, em classe. A lista do operador fica fora do YAML. A lista escrita no YAML só estreita; não amplia. O mesmo helper em config/loader.py cobre REST, não-REST e findings_sink.
Antes de codar: quando a lista do operador não está definida, instalações que já usam credencial via ambiente continuam como hoje, ou passam a falhar fechado com um opt-out documentado? Essa escolha muda o padrão das instalações existentes. Não implemento até a resposta.
Activity
FabioLeitao commentedon Oct 21, 2026
Audit comment after #2115 (merged 2026-10-21 02:15 UTC,
6bdb4ad). Read-only review ofmain; nothing was run against a live instance.#2115 deliberately leaves this issue open because
allowed_hostsis a brake on the same YAML. Agreed on that point.Class of problem (details withheld until the fix is merged). The env-name prefix rule (
CREDENTIAL_ENV_PREFIXESinconfig/loader.py) is documented indocs/SECURITY.mdas the control that is independent of the config author. The prefix namespace is shared with names that Boar itself reads from the environment, so the prefix alone does not separate operator-supplied credentials from Boar-internal values. Specific names and the reachable path are intentionally not listed in this public thread.Smallest change that restores the independence the docs claim (executor's choice): make the separation explicit (an explicit deny-list of Boar-internal names, or a distinct prefix for operator credentials), plus a test generated from a source scan of the names Boar reads from the environment, so the list cannot drift.
Docs drift in the same area.
docs/TECH_GUIDE.md:396anddocs/SECURITY.md:37disagree on whether non-REST*_from_envnames are subject to the prefix rule; one of them is stale.Provenance: git
6bdb4ad, read only. Triage before fix.fix(security): refuse reserved names inside credential placeholders
fix(security): treat non-string api keys as unclassified
FabioLeitao commentedon Oct 21, 2026
Nota de desenho, em classe. A lista do operador fica fora do YAML. A lista escrita no YAML só estreita; não amplia. O mesmo helper em
config/loader.pycobre REST, não-REST efindings_sink.Antes de codar: quando a lista do operador não está definida, instalações que já usam credencial via ambiente continuam como hoje, ou passam a falhar fechado com um opt-out documentado? Essa escolha muda o padrão das instalações existentes. Não implemento até a resposta.
FabioLeitao commentedon Oct 21, 2026
Nota de desenho, em classe. A lista do operador fica fora do YAML. A lista escrita no YAML só estreita; não amplia. O mesmo helper em
config/loader.pycobre REST, não-REST efindings_sink.Antes de codar: quando a lista do operador não está definida, instalações que já usam credencial via ambiente continuam como hoje, ou passam a falhar fechado com um opt-out documentado? Essa escolha muda o padrão das instalações existentes. Não implemento até a resposta.
fix(config): gate discover_url on the operator host list