Skip to content

security: validate URLs to prevent SSRF in content fetching endpoints - #8476

Merged
mudler merged 1 commit into
mudler:masterfrom
kolega-ai-dev:v11-finding_8
Feb 10, 2026
Merged

security: validate URLs to prevent SSRF in content fetching endpoints#8476
mudler merged 1 commit into
mudler:masterfrom
kolega-ai-dev:v11-finding_8

Conversation

@kolega-ai-dev

Copy link
Copy Markdown
Contributor

Vulnerability identified and fix provided by Kolega.dev

Description

This PR fixes a Server-Side Request Forgery (SSRF) vulnerability in multiple endpoints that accept user-provided URLs and fetch them without validation.

Vulnerability Details

Location: pkg/utils/base64.go (GetContentURIAsBase64), core/http/endpoints/openai/image.go (downloadFile), and callers in core/http/middleware/request.go (lines 331, 341, 356) and core/http/endpoints/localai/detection.go (line 34).

Description: The GetContentURIAsBase64() function and downloadFile() function fetch arbitrary user-supplied URLs without any validation. This allows attackers to probe internal networks, access cloud metadata services (e.g., 169.254.169.254 on AWS/GCP), and reach internal services via loopback or private IP ranges.

Fix Applied: Added a ValidateExternalURL() function in pkg/utils/urlfetch.go that performs DNS resolution on the target URL hostname and verifies all resolved IPs are public. It blocks:

  • Private IP ranges (10.x, 172.16-31.x, 192.168.x)
  • Loopback addresses (127.0.0.1, ::1)
  • Link-local addresses (169.254.x.x — AWS/GCP metadata endpoint)
  • Well-known internal hostnames (localhost, *.local, metadata.google.internal)
  • Non-HTTP(S) schemes (file://, ftp://, etc.)

This validation is called at the entry point of both GetContentURIAsBase64() and downloadFile() before any HTTP request is made.

Notes for Reviewers

  • The fix is minimal and focused — only URL validation is added, no other changes
  • 15 new test cases cover all blocked address categories (private, loopback, link-local, metadata, scheme, IPv6)
  • All existing tests continue to pass, including the external URL download test

Tests/Linters Ran

Check Result
go vet ./pkg/utils/... Passed
go build ./pkg/utils/... Passed
gofmt -l (all changed files) Passed (no formatting issues)
go test ./pkg/utils/... -v 19/19 specs passed (4 existing + 15 new)

Contribution Notes

  • Commit follows conventional commit format as specified in the PR template
  • golangci-lint was not available in the build environment but go vet was run as a substitute
  • DCO sign-off was not applied as it requires GPG key configuration; maintainers may request this be added

Signed commits

  • Yes, I signed my commits.

User-supplied URLs passed to GetContentURIAsBase64() and downloadFile()
were fetched without validation, allowing SSRF attacks against internal
services. Added URL validation that blocks private IPs, loopback,
link-local, and cloud metadata endpoints before fetching.
@netlify

netlify Bot commented Feb 9, 2026

Copy link
Copy Markdown

Deploy Preview for localai ready!

Name Link
🔨 Latest commit df584ee
🔍 Latest deploy log https://app.netlify.com/projects/localai/deploys/698a3cdbee8a7e0008bf7382
😎 Deploy Preview https://deploy-preview-8476--localai.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mudler
mudler merged commit 780877d into mudler:master Feb 10, 2026
33 of 38 checks passed
@mudler mudler added the bug Something isn't working label Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants