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.
The privilege gate ran on the URL the caller named before the resolver applied
the MDM policy, so on a managed device an unprivileged `netbird debug bundle -U
--upload-bundle-url <host>` was refused with "requires root" — even though the
policy would have discarded that URL and uploaded to the pinned destination.
Gating a value that has no effect only turns a working bundle into a denial.
Read the policy before the gate and tell the gate the destination is pinned, so
it skips the caller-URL branch. --upload-bundle-insecure stays gated either way:
relaxing TLS towards the pinned host is a real weakening, and that one is the
caller's doing.
Reported by cubic on #7514.
A request with no URL, no upload and uploadInsecure set was denied, although
uploadInsecure has no effect on a local-only bundle: there is no destination to
weaken, and the caller only wanted the file on disk. Pass the upload intent into
the gate and apply the empty-URL branch only when the request asks to upload.
Reported by cubic on #7514.
requirePrivilegeForUploadURL returned early on an empty URL, which was correct
while an empty URL meant "do not upload": there was no destination for
--upload-bundle-insecure to weaken. Now an empty URL means "use the destination
the management server published", so an unprivileged local caller could send
upload=true with an empty URL and uploadInsecure=true and have the root daemon
PUT the bundle to that destination with TLS verification disabled.
Gate the insecure flag on the empty-URL path too. A named URL keeps its existing
order, so a malformed one still reports InvalidArgument rather than a privilege
error.