Skip to content

fix: SSRF protection for webhook URLs and screenshot fetch — Issue #346#379

Merged
OneStepAt4time merged 4 commits intomainfrom
fix/ssrf-webhook-validation-346
Mar 27, 2026
Merged

fix: SSRF protection for webhook URLs and screenshot fetch — Issue #346#379
OneStepAt4time merged 4 commits intomainfrom
fix/ssrf-webhook-validation-346

Conversation

@OneStepAt4time
Copy link
Copy Markdown
Owner

Fixes #346

Changes (7 files, +633/-49)

  • New `src/ssrf.ts`: shared SSRF validation utility with DNS resolution, IP range checks (RFC 1918, loopback, link-local, CGNAT)
  • `src/channels/webhook.ts`: Zod schema for webhook endpoints, SSRF validation on all URLs
  • `src/server.ts`: extracted screenshot SSRF validation to shared utility, added DNS check
  • `src/validation.ts`: added URL validation helpers
  • 3 new test files: ssrf.test.ts (174 lines), webhook-ssrf.test.ts (154 lines), screenshot-ssrf.test.ts (83 lines)

1047 tests passing.

Shared module with isPrivateIP (RFC 1918, loopback, link-local, CGNAT),
validateWebhookUrl (HTTPS enforcement, localhost dev mode), and
resolveAndCheckIp (DNS resolution with DI for testability).

Generated by Hephaestus (Aegis dev agent)
Generated by Hephaestus (Aegis dev agent)
#346

Rejects non-HTTPS, private IPs, and localhost in webhook URLs.
Accepts HTTP only for 127.0.0.1 dev mode.

Generated by Hephaestus (Aegis dev agent)
…check — Issue #346

Replaces inline validateScreenshotUrl in server.ts with shared module.
Adds post-DNS-resolution IP check to screenshot routes.

Generated by Hephaestus (Aegis dev agent)
@OneStepAt4time OneStepAt4time merged commit 877bb6e into main Mar 27, 2026
3 checks passed
@OneStepAt4time OneStepAt4time deleted the fix/ssrf-webhook-validation-346 branch March 27, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security: SSRF via unvalidated webhook URLs

1 participant