- Shipped
- October 14, 2026 at 4:15 PM UTC
- Author
- Kamo
- Commit
- e58f1a9
The outbound webhook worker POSTed to whatever URL a subscriber stored, from inside the cluster, with no egress control - a subscription aimed at **************** or 169.254.169.254 got a signed POST on every pipeline event. It then stored exception text ("Connection refused", "Read timed out", TLS detail) and the DTOs returned it, which made the pair an oracle for mapping the pod network. The signing secret sat in plaintext. Targets (WebhookTargetGuard, plain class): - At save (create/update): absolute https only, no credentials, a hostname PublicHostGuard deems public (or a public IP literal), and EVERY address it resolves to publicly routable. Fixed-text IllegalArgumentException. - Before each delivery: the syntax rules again, then the client resolves the host once through PinnedPublicDns, drops non-public addresses and connects only to the survivors (no rebinding window; SNI/cert checks unchanged). Redirects are never followed, no silent route retry, hard connect/read/call deadlines; the response body is never read. - A refused target is recorded and acked, not redelivered. Failures (WebhookFailureCategory): only INVALID_TARGET, BLOCKED_ADDRESS, CONNECT_FAILED, TIMEOUT, HTTP_3XX/4XX/5XX, SIGNING_FAILED or OTHER are stored (the status code stays in RESPONSE_STATUS). Both DTOs sanitise on read, so a legacy row's free text comes back as OTHER ("HTTP 503" maps to HTTP_5XX). Detail goes only to the platform log. Signing secret (WebhookSigningSecrets): written only as PlatformSecretCipher ciphertext in the new SIGNING_SECRET_CIPHERTEXT column; storing fails closed with no platform key. The read path still accepts the legacy plaintext column until **************** (re-runnable, per row) encrypts it and nulls the plaintext. A stored secret that cannot be decrypted or applied stops the delivery instead of sending it unsigned. Schema: securityservice **************** (adds the column, scrubs legacy failure text) - applied 2026-10-14 as owner.
