diff --git a/server/fleet/windows_mdm.go b/server/fleet/windows_mdm.go index 901235b835..c06e18e1fe 100644 --- a/server/fleet/windows_mdm.go +++ b/server/fleet/windows_mdm.go @@ -79,6 +79,7 @@ func (m *MDMWindowsConfigProfile) ValidateUserProvided() error { // structure (Target>Item>LocURI) so we don't need to track all the tags. var inValidNode bool var inLocURI bool + var inComment bool for { tok, err := dec.Token() @@ -97,9 +98,19 @@ func (m *MDMWindowsConfigProfile) ValidateUserProvided() error { return errors.New("The file should include valid XML: processing instructions are not allowed.") case xml.Comment: + inComment = true continue case xml.StartElement: + // Top-level comments should be followed by or elements + if inComment { + if !inValidNode && t.Name.Local != "Replace" && t.Name.Local != "Add" { + return errors.New("Windows configuration profiles can only have or top level elements after comments") + } + inValidNode = true + inComment = false + } + switch t.Name.Local { case "Replace", "Add": inValidNode = true diff --git a/server/fleet/windows_mdm_test.go b/server/fleet/windows_mdm_test.go index 2738e703fa..93f56f8b0a 100644 --- a/server/fleet/windows_mdm_test.go +++ b/server/fleet/windows_mdm_test.go @@ -422,6 +422,23 @@ func TestValidateUserProvided(t *testing.T) { }, wantErr: "", }, + { + name: "XML with top level comment followed by invalid element", + profile: MDMWindowsConfigProfile{ + SyncML: []byte(` + + + Custom/URI + + + + Custom/URI + + + `), + }, + wantErr: "Windows configuration profiles can only have or top level elements after comments", + }, { name: "XML with nested root element in data", profile: MDMWindowsConfigProfile{