[client] Treat a named upload URL as a request to upload in the privilege gate

DebugBundle uploads when either the upload flag or the upload URL is set, but
the privilege gate was told only about the flag. With an MDM policy pinning the
destination the gate blanks the caller's URL, so a request carrying a URL and no
flag reached the empty-URL branch and found upload false: nothing to weaken, let
it through. The daemon then uploaded as root with TLS verification disabled on
behalf of an unprivileged caller.

A client older than the upload flag sends exactly that shape, a URL and nothing
else, so this needs no crafted request to reach.

The gate now derives the upload intent from the URL rather than trusting the
caller's flag, and DebugBundle computes it once so the gate and the local-only
early return cannot drift apart.
This commit is contained in:
riccardom
2026-10-09 09:57:31 +02:00
parent d5a9f5b0ff
commit 676181b908
3 changed files with 20 additions and 2 deletions
+7 -2
View File
@@ -27,8 +27,13 @@ import (
// DebugBundle creates a debug bundle and returns the location.
func (s *Server) DebugBundle(callerCtx context.Context, req *proto.DebugBundleRequest) (resp *proto.DebugBundleResponse, err error) {
// One source of truth for "this request uploads", used by both the gate and
// the local-only early return below. A client older than the upload flag asks
// for an upload by naming a URL and nothing else, so the two must not drift.
wantsUpload := req.GetUpload() || req.GetUploadURL() != ""
mdmUploadURL := s.mdmDebugUploadURL()
if err := requirePrivilegeForUploadURL(callerCtx, req.GetUploadURL(), req.GetUploadInsecure(), req.GetUpload(), mdmUploadURL != ""); err != nil {
if err := requirePrivilegeForUploadURL(callerCtx, req.GetUploadURL(), req.GetUploadInsecure(), wantsUpload, mdmUploadURL != ""); err != nil {
return nil, err
}
@@ -42,7 +47,7 @@ func (s *Server) DebugBundle(callerCtx context.Context, req *proto.DebugBundleRe
return nil, err
}
if !req.GetUpload() && req.GetUploadURL() == "" {
if !wantsUpload {
return &proto.DebugBundleResponse{Path: path}, nil
}