nebula-mesh: POST /api/v1/hosts/{id}/mobile-bundle response lacks Cache-Control: no-store
Date: 2026-06
Affected: go/github.com/juev/nebula-mesh
Attack vector: deserialization
Category: vulnerability-disclosure
Severity: Low
CWE: CWE-525

`internal/api/mobile_bundle.go:62-66` sets only `Content-Type: application/yaml`. The Web-UI sibling at `internal/web/handlers.go:1316-1321` sets `Cache-Control: no-store`, `Pragma: no-cache`, `Expires: 0`, `X-Content-Type-Options: nosniff` — and has a test asserting it. The API path was missed. ## Affected All released versions up to v0.3.0. ## Threat model The endpoint returns a freshly minted X25519 private key inline. Without `no-store`, any intermediary proxy or CDN that caches `200 OK` YAML responses retains the private key for its cache TTL. Same applies to browser disk cache for direct API hits. Combined with the cross-tenant authz advisory (critical), even a corrected authz layer would still leak via cache after fix. ## Suggested fix Copy the four headers from the Web sibling: ```go w.Header().Set("Content-Type", "application/yaml; charset=utf-8") w.Header().Set("Cache-Control", "no-store") w.Header().Set("Pragma", "no-cache") w.Header().Set("Expires", "0") w.Header().Set("X-Content-Type-Options", "nosniff") ``` Mirrors `internal/web/handlers.go:1316-1321`. Add a parallel test to the existing web-side coverage. ## Suggested patch Verified locally: `go vet`, `go test -race -count=1 ./...`, `golangci-lint v2.12` all clean. ```diff diff --git a/internal/api/mobile_bundle.go b/internal/api/mobile_bundle.go index fc09da0..73152eb 100644 --- a/internal/api/mobile_bundle.go +++ b/internal/api/mobile_bundle.go @@ -58,8 +58,15 @@ func (s *Server) handleMobileBundle(w


Mitigations:

Architectural layers (MAESTRO):