T09 · Insecure Skill Coding Practices
- Location
references/worker-patterns.md:59- Finding
Unrestricted Webhook Destination Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
references/worker-patterns.md, lines 59–78
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: Highelixir def perform(%Oban.Job{args: args, attempt: attempt}) do %{"url" => url, "event" => event, "payload" => payload} = args headers = build_headers(args) case Req.post(url, json: payload, headers: headers, receive_timeout: 25_000) do {:ok, %{status: status}} when status in 200..299 -> :ok {:ok, %{status: 410}} -> Logger.info("Webhook endpoint gone: #{url}") {:cancel, "endpoint returned 410 Gone"} {:ok, %{status: status, body: body}} -> Logger.warning("Webhook failed: #{status} - #{inspect(body)}") {:error, "HTTP #{status}"} {:error, %Req.TransportError{reason: reason}} -> {:error, "transport: #{inspect(reason)}"} end endTechnical Analysis
The worker obtains the request destination directly from persistent job arguments and passes it to
Req.post/2. It does not validate the URL scheme, hostname, resolved IP address, port, or redirect destination.If an untrusted user can directly enqueue jobs or indirectly control webhook configuration used to create these arguments, the worker can be induced to send requests from the application server to otherwise inaccessible destinations. Potential targets include loopback services, private network addresses, container infrastructure, and cloud instance metadata services.
The error path also logs the remote response body. This may disclose internal response content to anyone with access to application logs and can allow untrusted endpoints to inject large or sensitive content into those logs.
Attack Path
- An attacker gains control over a webhook URL that is serialized into an Oban job.
- The attacker supplies a URL targeting an internal service, loopback address, private network host, or cloud metadata endpoint.
...[truncated 999 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not accept a request URL directly from job arguments. Store a trusted webhook subscription identifier and resolve its destination from an authorized database record when the job executes.
- Permit only explicitly supported schemes, preferably HTTPS.
- Enforce an allowlist of approved hostnames or domains where the business model permits it.
- Resolve the hostname and reject loopback, link-local, private, multicast, reserved, and metadata-service addresses for both IPv4 and IPv6.
- Protect against DNS rebinding by verifying the address used for the actual connection, not only an earlier DNS lookup.
- Disable redirects or validate the scheme, hostname, port, and resolved destination after every redirect.
- Apply outbound firewall or proxy rules so the worker cannot access infrastructure management networks or metadata services.
- Limit response sizes and avoid logging complete untrusted response bodies. Log a bounded, sanitized diagnostic value instead.
- Authorize webhook creation and job insertion, and validate that the referenced webhook belongs to the appropriate tenant.
