[management,client] Normalize anonymize_level and sanity-check the bundle upload URL

Two review follow-ups.

The API validated anonymize_level after trimming and lowercasing but
persisted the value verbatim, so " default " passed as default yet reached
the client — which only lowercases — as an unrecognized value it resolves
to strict. Persist the normalized form so what was validated is what the
client parses.

The remote debug bundle job forwarded the management-supplied upload URL
to the uploader unchecked and logged it at info level, where it can leak a
host, credentials, or query tokens. Reject a malformed or non-https URL
before generating the bundle, and keep the URL out of the info-level line
while leaving the full parameters at debug. The accepted host is left
unrestricted for now, pending a decision on management-directed uploads.
This commit is contained in:
mlsmaycon
2026-08-11 02:16:22 +00:00
parent 725dc451ca
commit 5585ceec85
4 changed files with 92 additions and 3 deletions
+31 -1
View File
@@ -1365,7 +1365,17 @@ func (e *Engine) receiveJobEvents() {
}
func (e *Engine) handleBundle(params *mgmProto.BundleParameters) (*mgmProto.JobResponse_Bundle, error) {
log.Infof("handle remote debug bundle request: %s", params.String())
// The upload URL can carry a host, credentials, or query tokens, so it is
// kept out of the info-level line; the full parameters stay available at
// debug level for troubleshooting.
log.Infof("handle remote debug bundle request: anonymize=%v anonymize_level=%q log_file_count=%d bundle_for=%v bundle_for_time=%d",
params.GetAnonymize(), params.GetAnonymizeLevel(), params.GetLogFileCount(), params.GetBundleFor(), params.GetBundleForTime())
log.Debugf("remote debug bundle request parameters: %s", params.String())
if err := validateBundleUploadURL(params.GetUploadUrl()); err != nil {
return nil, err
}
syncResponse, err := e.GetLatestSyncResponse()
if err != nil {
log.Warnf("get latest sync response: %v", err)
@@ -1406,6 +1416,26 @@ func (e *Engine) handleBundle(params *mgmProto.BundleParameters) (*mgmProto.JobR
return response, nil
}
// validateBundleUploadURL sanity-checks a management-supplied upload URL for a
// remote debug bundle job. An empty value is accepted — the executor falls back
// to the default upload service. A non-empty value must be a well-formed https
// URL with a host; a malformed value or a plaintext scheme is rejected. This
// deliberately does not constrain which host may receive the bundle; that
// policy is left open pending a decision on management-directed uploads.
func validateBundleUploadURL(raw string) error {
if raw == "" {
return nil
}
parsed, err := url.Parse(raw)
if err != nil {
return fmt.Errorf("parse upload URL: %w", err)
}
if parsed.Scheme != "https" || parsed.Host == "" {
return fmt.Errorf("upload URL must be an https URL with a host")
}
return nil
}
// receiveManagementEvents connects to the Management Service event stream to receive updates from the management service
// E.g. when a new peer has been registered and we are allowed to connect to it.
func (e *Engine) receiveManagementEvents() {