HTTP delivery targets are validated at creation time by delivery.ValidateTargetURL (called from internal/handlers/source_management.go), which enforces an http/https scheme allowlist and blocks private, reserved, link-local, and cloud-metadata address ranges. buildSlackTargetConfig does not call ValidateTargetURL, so a Slack target's incoming webhook URL is only checked by the request-time dialer guard, not at creation. That is an inconsistent, weaker gate for one target type.
Definition of done:
Slack target URLs are validated with ValidateTargetURL (or an equivalent) at creation time, matching the HTTP target path
creating a Slack target with an internal/reserved URL is rejected with a clear error
a test covers both acceptance of a public URL and rejection of a reserved one
Part of the road to 1.0 (see #33).
HTTP delivery targets are validated at creation time by `delivery.ValidateTargetURL` (called from `internal/handlers/source_management.go`), which enforces an http/https scheme allowlist and blocks private, reserved, link-local, and cloud-metadata address ranges. `buildSlackTargetConfig` does not call `ValidateTargetURL`, so a Slack target's incoming webhook URL is only checked by the request-time dialer guard, not at creation. That is an inconsistent, weaker gate for one target type.
Definition of done:
- Slack target URLs are validated with `ValidateTargetURL` (or an equivalent) at creation time, matching the HTTP target path
- creating a Slack target with an internal/reserved URL is rejected with a clear error
- a test covers both acceptance of a public URL and rejection of a reserved one
clawbot
added this to the 1.0.0 milestone 2026-08-07 13:16:06 +02:00
Confine this change to internal/handlers/source_management.go and its test file ONLY. Do NOT modify internal/delivery/ — the validator already exists and is exported; just call it.
The problem: HTTP targets are validated at creation by delivery.ValidateTargetURL (defined in internal/delivery/ssrf.go). The Slack target creation path (buildSlackTargetConfig / HandleTargetCreate) does not call it, so a Slack incoming-webhook URL is only checked at request time, not at creation.
Fix:
in the Slack target creation path, validate the Slack webhook URL with delivery.ValidateTargetURL before persisting, mirroring the HTTP target path
on validation failure, reject the create with the same clear, user-facing error pattern the HTTP path already uses (do not leak internals)
Definition of done:
creating a Slack target with a private/reserved/internal or non-http(s) URL is rejected at creation time with a clear error
creating a Slack target with a valid public URL still succeeds
a test in the handlers package covers both the accepted and rejected cases
Gates and process:
make fmt before committing
validate with docker build . (must exit 0; host Go 1.25 vs go.mod 1.26, so Docker is the gate)
branch from main named issue-68-slack-url-validation; commit subject ends with (closes #68)
open a PR (base main) and comment on it with the diff summary and the docker build . result
no AI-assistant/tooling references anywhere
## Implementation instructions
Confine this change to `internal/handlers/source_management.go` and its test file ONLY. Do NOT modify `internal/delivery/` — the validator already exists and is exported; just call it.
The problem: HTTP targets are validated at creation by `delivery.ValidateTargetURL` (defined in `internal/delivery/ssrf.go`). The Slack target creation path (`buildSlackTargetConfig` / `HandleTargetCreate`) does not call it, so a Slack incoming-webhook URL is only checked at request time, not at creation.
Fix:
- in the Slack target creation path, validate the Slack webhook URL with `delivery.ValidateTargetURL` before persisting, mirroring the HTTP target path
- on validation failure, reject the create with the same clear, user-facing error pattern the HTTP path already uses (do not leak internals)
Definition of done:
- creating a Slack target with a private/reserved/internal or non-http(s) URL is rejected at creation time with a clear error
- creating a Slack target with a valid public URL still succeeds
- a test in the `handlers` package covers both the accepted and rejected cases
Gates and process:
- `make fmt` before committing
- validate with `docker build .` (must exit 0; host Go 1.25 vs go.mod 1.26, so Docker is the gate)
- branch from `main` named `issue-68-slack-url-validation`; commit subject ends with ` (closes #68)`
- open a PR (base `main`) and comment on it with the diff summary and the `docker build .` result
- no AI-assistant/tooling references anywhere
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of the road to 1.0 (see #33).
HTTP delivery targets are validated at creation time by
delivery.ValidateTargetURL(called frominternal/handlers/source_management.go), which enforces an http/https scheme allowlist and blocks private, reserved, link-local, and cloud-metadata address ranges.buildSlackTargetConfigdoes not callValidateTargetURL, so a Slack target's incoming webhook URL is only checked by the request-time dialer guard, not at creation. That is an inconsistent, weaker gate for one target type.Definition of done:
ValidateTargetURL(or an equivalent) at creation time, matching the HTTP target pathImplementation instructions
Confine this change to
internal/handlers/source_management.goand its test file ONLY. Do NOT modifyinternal/delivery/— the validator already exists and is exported; just call it.The problem: HTTP targets are validated at creation by
delivery.ValidateTargetURL(defined ininternal/delivery/ssrf.go). The Slack target creation path (buildSlackTargetConfig/HandleTargetCreate) does not call it, so a Slack incoming-webhook URL is only checked at request time, not at creation.Fix:
delivery.ValidateTargetURLbefore persisting, mirroring the HTTP target pathDefinition of done:
handlerspackage covers both the accepted and rejected casesGates and process:
make fmtbefore committingdocker build .(must exit 0; host Go 1.25 vs go.mod 1.26, so Docker is the gate)mainnamedissue-68-slack-url-validation; commit subject ends with(closes #68)main) and comment on it with the diff summary and thedocker build .result