tinyrelaycommit

Commit 849dd7263f87

browse files at this commit | history

1diff --git a/internal/daemon/callbacks.go b/internal/daemon/callbacks.go
2index e997353..f18e355 100644
3--- a/internal/daemon/callbacks.go
4+++ b/internal/daemon/callbacks.go
5@@ -205,12 +205,15 @@ func (t *Tenant) checkCallbackURL(raw string) error {
6 return nil
7 }
8 host := strings.ToLower(parsed.Hostname())
9+ if ip := net.ParseIP(host); ip != nil {
10+ if privateAddress(ip) {
11+ return errors.New("invalid: url must not name a private or loopback address")
12+ }
13+ return nil
14+ }
15 if host == "localhost" || strings.HasSuffix(host, ".localhost") || strings.HasSuffix(host, ".local") || strings.HasSuffix(host, ".internal") || !strings.Contains(host, ".") {
16 return errors.New("invalid: url must name a public host")
17 }
18- if ip := net.ParseIP(host); ip != nil && privateAddress(ip) {
19- return errors.New("invalid: url must not name a private or loopback address")
20- }
21 return nil
22 }
23
24diff --git a/internal/daemon/callbacks_test.go b/internal/daemon/callbacks_test.go
25index c8448b9..4ab3713 100644
26--- a/internal/daemon/callbacks_test.go
27+++ b/internal/daemon/callbacks_test.go
28@@ -100,6 +100,8 @@ func TestCallbackRegistrationValidatesURLFilterScopeAndCap(t *testing.T) {
29 {"credentials", member, "https://user:pw@hooks.example/wake", `{"kinds":[1]}`, "invalid: url must be https"},
30 {"private address", member, "https://10.0.0.1/wake", `{"kinds":[1]}`, "invalid: url must not name a private"},
31 {"loopback address", member, "https://127.0.0.1/wake", `{"kinds":[1]}`, "invalid: url must not name a private"},
32+ {"loopback ipv6", member, "https://[::1]/wake", `{"kinds":[1]}`, "invalid: url must not name a private"},
33+ {"shared address", member, "https://100.64.0.9/wake", `{"kinds":[1]}`, "invalid: url must not name a private"},
34 {"localhost", member, "https://localhost/wake", `{"kinds":[1]}`, "invalid: url must name a public host"},
35 {"bare host", member, "https://relay/wake", `{"kinds":[1]}`, "invalid: url must name a public host"},
36 {"no kinds", member, "https://hooks.example/wake", `{"#p":["` + member + `"]}`, "invalid: filter must name at least one kind"},
37@@ -145,6 +147,8 @@ func TestCallbackRegistrationValidatesURLFilterScopeAndCap(t *testing.T) {
38 for i := 0; i < 6; i++ {
39 addCallback(t, tenant, owner, "https://hooks.example/owner/"+strconv.Itoa(i), `{"kinds":[1]}`)
40 }
41+ // A public address literal is a host like any other.
42+ addCallback(t, tenant, owner, "https://[2001:db8::10]/wake", `{"kinds":[1]}`)
43 // The secret shows once: listings and the table row never repeat it.
44 listed, err := tenant.Execute(ctx, agent, "listcallbacks", nil)
45 if err != nil {

About

ownerc01503e8035f
visibilitypublic
head849dd7263f87

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs