diff --git a/server/fleet/apple_mdm_test.go b/server/fleet/apple_mdm_test.go
index 6469d97f67..679f3e9f56 100644
--- a/server/fleet/apple_mdm_test.go
+++ b/server/fleet/apple_mdm_test.go
@@ -30,6 +30,7 @@ func TestMDMAppleConfigProfile(t *testing.T) {
testName string
mobileconfig mobileconfig.Mobileconfig
shouldFail bool
+ errString *string
}{
{
testName: "TestParseConfigProfileOK",
@@ -91,6 +92,24 @@ func TestMDMAppleConfigProfile(t *testing.T) {
}(),
shouldFail: true,
},
+ {
+ testName: "TestParseConfigProfileUnescapedCharsInPayload",
+ mobileconfig: MobileconfigForTest("ValidName", "ValidIdentifier", uuid.NewString(), `Unescaped & < > ' "`),
+ shouldFail: true,
+ errString: new("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again."),
+ },
+ {
+ testName: "TestParseConfigProfileUnescapedCharsInIdentifier",
+ mobileconfig: MobileconfigForTest("ValidName", "ValidValid`),
+ shouldFail: true,
+ errString: new("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again."),
+ },
+ {
+ testName: "TestParseConfigProfileUnescapedCharsInName",
+ mobileconfig: MobileconfigForTest("ValidValid`),
+ shouldFail: true,
+ errString: new("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again."),
+ },
}
for _, c := range cases {
@@ -98,6 +117,9 @@ func TestMDMAppleConfigProfile(t *testing.T) {
parsed, err := NewMDMAppleConfigProfile(c.mobileconfig, nil)
if c.shouldFail {
require.Error(t, err)
+ if c.errString != nil {
+ require.ErrorContains(t, err, *c.errString)
+ }
} else {
require.NoError(t, err)
require.Equal(t, "ValidName", parsed.Name)
diff --git a/server/mdm/apple/mobileconfig/mobileconfig.go b/server/mdm/apple/mobileconfig/mobileconfig.go
index 2a48797f8f..53a7c2e9b2 100644
--- a/server/mdm/apple/mobileconfig/mobileconfig.go
+++ b/server/mdm/apple/mobileconfig/mobileconfig.go
@@ -113,8 +113,8 @@ func (mc Mobileconfig) ParseConfigProfile() (*Parsed, error) {
}
var p Parsed
if _, err := plist.Unmarshal(mcBytes, &p); err != nil {
- if strings.Contains(err.Error(), "illegal base64 data") {
- return nil, errors.New("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again.")
+ if strings.Contains(err.Error(), "illegal base64 data") || strings.Contains(err.Error(), "invalid character entity") || strings.Contains(err.Error(), "expected attribute name in element") {
+ return nil, errors.New("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again.")
}
return nil, err
}
@@ -168,8 +168,8 @@ func (mc Mobileconfig) payloadSummary() ([]payloadSummary, error) {
}
_, err := plist.Unmarshal(mcBytes, &tlo)
if err != nil {
- if strings.Contains(err.Error(), "illegal base64 data") {
- return nil, errors.New("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again.")
+ if strings.Contains(err.Error(), "illegal base64 data") || strings.Contains(err.Error(), "invalid character entity") || strings.Contains(err.Error(), "expected attribute name in element") {
+ return nil, errors.New("The configuration profile contains special characters (&, <, >, ', \") that must be XML-escaped. Please escape them (e.g. & → &, < → <) and try again.")
}
return nil, err
}