ollama - 💡(How to fix) Fix HIGH: /api/create accepts arbitrary RemoteHost — SSRF via remote model proxying to internal services

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

func remoteURL(raw string) (string, error) {

Code Example

remoteHost := r.RemoteHost  // ⚠️ attacker-controlled
// ...
config.RemoteModel = fromRef.Base
config.RemoteHost = ru
remote = true

---

func remoteURL(raw string) (string, error) {
    if strings.HasPrefix(raw, "/") {
        return (&url.URL{
            Scheme: "http",
            Host:   net.JoinHostPort("localhost", "11434"),
            Path:   path.Clean(raw),
        }).String(), nil
    }
    // ... parses URL, defaults port 11434 ...
}

---

POST /api/create
{
  "model": "evil-proxy",
  "from": "llama3.2",
  "remote_host": "http://169.254.169.254/latest/meta-data/"
}
RAW_BUFFERClick to expand / collapse

CWE-918: Model Creation with Arbitrary RemoteHost — SSRF via Remote Model Proxying

Severity: HIGH (CVSS 7.5)

Location

server/create.goCreateHandler and remoteURL():

remoteHost := r.RemoteHost  // ⚠️ attacker-controlled
// ...
config.RemoteModel = fromRef.Base
config.RemoteHost = ru
remote = true

The remoteURL() helper accepts arbitrary user input and only performs minimal validation:

func remoteURL(raw string) (string, error) {
    if strings.HasPrefix(raw, "/") {
        return (&url.URL{
            Scheme: "http",
            Host:   net.JoinHostPort("localhost", "11434"),
            Path:   path.Clean(raw),
        }).String(), nil
    }
    // ... parses URL, defaults port 11434 ...
}

Impact

A user can create a model that proxies inference requests to any URL by setting RemoteHost in the Create API:

POST /api/create
{
  "model": "evil-proxy",
  "from": "llama3.2",
  "remote_host": "http://169.254.169.254/latest/meta-data/"
}

When this model is used for inference, Ollama will proxy the request to the attacker-specified URL. This enables:

  1. Cloud metadata exfiltration — proxy to 169.254.169.254 on AWS/GCP/Azure
  2. Internal network scanning — probe private IP ranges
  3. Localhost service accesshttp://localhost:6379 (Redis), http://localhost:5432 (Postgres)

The only constraint is that the remote host must be in OLLAMA_REMOTES list (default: ["ollama.com"]) OR the user can set OLLAMA_REMOTES to include any host.

Remediation

  1. Validate RemoteHost against the OLLAMA_REMOTES allowlist before creating the model
  2. Block private/internal IP ranges in remote URLs
  3. Require HTTPS for non-localhost remote hosts
  4. Add a server-side configuration flag to disable remote model creation entirely

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING