Soumettre #972855: ollama Ollama 0.34 7PK Input Validation and Representationinformation

Titreollama Ollama 0.34 7PK Input Validation and Representation
DescriptionThis is not a first-time discovery and I am declaring the overlap explicitly: CVE-2026-5530 (CNA: VulDB) covers SSRF in /api/pull via server/download.go up to 0.18.1, CVE-2026-85180 (CNA: VulnCheck) covers cross-host tensor-blob redirect SSRF in 0.30.0–0.33.2, and several public reports exist (50d65e91, fe948d6a, 30a586e6, 5f7be736, 4a743a75). My incremental claim is therefore not that "an SSRF exists", but two verifiable points: (a) the gap is still open in the latest release — reproduced end-to-end on the official v0.34.0 binary; and (b) the repository contains three outbound transfer paths, of which two implement a redirect policy and the manifest fetch path does not. Concretely: x/transfer/transfer.go:128-130 returns http.ErrUseLastResponse (follows no redirects at all), server/download.go:242-256 allows only redirects whose Hostname() matches the original (max 10 hops, else ErrUseLastResponse), while server/images.go:1410 sets CheckRedirect: regOpts.CheckRedirect, which is nil on the pull path (populated from server/routes.go:1146 regOpts{Insecure: req.Insecure}) — so Go's default applies: follow all redirects, allow host change and https→http downgrade. CVE-2026-85180 addressed exactly this class of gap on the tensor-blob path; the manifest path is the remaining unhardened sibling. Root cause: types/model/name.go:167 parses scheme, host, ok := strings.Cut(s, "://") with no allowlist, and IsValid() (:262) validates only Host/Namespace/Model/Tag character sets — ProtocolScheme is not validated. The only gate is server/images.go:1022, which permits plaintext HTTP when Insecure == true — a caller-supplied request field, even though api/types.go:767 labels it // Deprecated: ignored. The upstream response body is then echoed verbatim: server/images.go:1348-1352 fmt.Errorf("%d: %s", resp.StatusCode, responseBody) → server/routes.go:1153 returns it to the unauthenticated caller. No outbound address filtering exists anywhere in the repository; every IsPrivate/IsLoopback/169.254/LinkLocal occurrence is on an inbound path. PoC (official v0.34.0, Windows amd64, served on loopback only; archive SHA256 verified against the vendor sha256sum.txt): with a test service on 127.0.0.1:8899 answering 403 with body {"INTERNAL-VALUE-1":"alpha-9f3c","note":"this body must never reach an unauthenticated client"}, an unauthenticated POST http://127.0.0.1:11434/api/pull with {"model":"http://127.0.0.1:8899/ns/m","insecure":true,"stream":false} returned HTTP 500 and {"error":"pull model manifest: 403: {\"INTERNAL-VALUE-1\":\"alpha-9f3c\", ...}"} — the internal body verbatim. The test service logged HIT GET /v2/ns/m/manifests/latest Host=127.0.0.1:8899 UA=ollama/0.34.0 (amd64 windows) Go/go1.26.0; the User-Agent is assembled by Ollama itself, proving the request came from the Ollama process, and the Host shows the attacker-chosen host and port used verbatim. Boundary controls: removing insecure yields Get "https://127.0.0.1:8899/...": tls: first record does not look like a TLS handshake, proving the one gate is a caller-supplied field rather than a server policy; targeting a closed port yields connectex: No connection could be made because the target machine actively refused it, so error text discriminates port state — an internal scanning oracle. Impact: unauthenticated reading of internal 4xx (except 401, which the auth-challenge branch swallows) and 5xx response bodies; arbitrary redirect following including https→http downgrade; internal port discrimination; cloud metadata reach (x.x.x.x) wherever Ollama has egress; and on Linux/macOS/Docker a manifest write into the local model store (server/images.go:1113). The official Docker image sets OLLAMA_HOST=x.x.x.x:11434 and the API has no authentication by design, so a container-published deployment is reachable as-is. Fix: give the pull path the policy its siblings already have — reject any hop whose Hostname() differs from the original and reject https→http downgrade (mirroring server/download.go:242-256), or adopt the stricter http.ErrUseLastResponse at x/transfer/transfer.go:128; filter outbound destinations in DialContext; stop echoing upstream bodies at images.go:1352; make plaintext HTTP a server-side decision instead of a request field; and validate ProtocolScheme in IsValid()
La source⚠️ https://github.com/aLtEr6/test.git
Utilisateur
 aLtEr (UID 71573)
Soumission11/09/2026 10:30 (il y a 1 mois)
Modérer11/10/2026 13:49 (1 month later)
StatutAccepté
Entrée VulDB416610 [Ollama jusqu’à 0.34.1 Pull API types/model/name.go IsValid élévation de privilèges]
Points20

Do you need the next level of professionalism?

Upgrade your account now!