Mask target config on the source detail page (closes #113)
Some checks failed
check / check (push) Has been cancelled

The page rendered the stored target config verbatim, exposing the Slack
incoming-webhook URL, which is a bearer credential: anyone holding it can
post to the channel indefinitely, and it cannot be scoped or revoked
per-holder.

Target config now reaches the template only as a TargetView carrying
labelled fields, so no code path can render the raw blob. maskURL keeps
scheme and host and elides the path, and drops query, fragment and
userinfo; every parse failure yields a neutral placeholder rather than
falling back to the stored string. HTTP header values are never rendered,
only a count.

Rendering change only: the stored config format and the delivery path are
unchanged.
This commit was merged in pull request #114.
This commit is contained in:
2026-08-11 14:37:09 +02:00
parent e50a79ced9
commit 15a61173fc
5 changed files with 719 additions and 5 deletions

View File

@@ -414,9 +414,12 @@ func (h *Handlers) renderSourceDetail(
data := map[string]any{
tmplKeyWebhook: &webhook,
"Entrypoints": entrypoints,
"Targets": targets,
"Events": events,
"BaseURL": scheme + "://" + host,
// Targets are projected to a display-safe view: the
// stored config blob holds credentials and must never
// reach a template.
"Targets": delivery.NewTargetViews(targets),
"Events": events,
"BaseURL": scheme + "://" + host,
}
h.renderTemplate(w, r, "source_detail.html", data)