diff --git a/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint b/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint new file mode 100644 index 0000000000..9385222293 --- /dev/null +++ b/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint @@ -0,0 +1,2 @@ +- If a policy was defined with an invalid query, the desktop endpoint should count that policy as a + failed policy. diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go index 4b3980428d..6b955feb0d 100644 --- a/server/datastore/mysql/hosts.go +++ b/server/datastore/mysql/hosts.go @@ -2230,7 +2230,7 @@ func (ds *Datastore) FailingPoliciesCount(ctx context.Context, host *fleet.Host) query := ` SELECT SUM(1 - pm.passes) AS n_failed FROM policy_membership pm - WHERE pm.host_id = ? + WHERE pm.host_id = ? AND pm.passes IS NOT null GROUP BY host_id ` diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 55dee6a7f9..5c62d050f3 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -3589,3 +3589,34 @@ func (s *integrationEnterpriseTestSuite) setTokenForTest(t *testing.T, email, pa s.token = s.getCachedUserToken(email, password) } + +func (s *integrationEnterpriseTestSuite) TestDesktopEndpointWithInvalidPolicy() { + t := s.T() + + token := "abcd123" + host := createHostAndDeviceToken(t, s.ds, token) + + // Create an 'invalid' global policy for host + admin := s.users["admin1@example.com"] + err := s.ds.SaveUser(context.Background(), &admin) + require.NoError(t, err) + + policy, err := s.ds.NewGlobalPolicy(context.Background(), &admin.ID, fleet.PolicyPayload{ + Query: "SELECT 1 FROM table", + Name: "test", + Description: "Some invalid Query", + Resolution: "", + Platform: host.Platform, + Critical: false, + }) + require.NoError(t, err) + require.NoError(t, s.ds.RecordPolicyQueryExecutions(context.Background(), host, map[uint]*bool{policy.ID: nil}, time.Now(), false)) + + // Any 'invalid' policies should be ignored. + desktopRes := fleetDesktopResponse{} + res := s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/desktop", nil, http.StatusOK) + require.NoError(t, json.NewDecoder(res.Body).Decode(&desktopRes)) + require.NoError(t, res.Body.Close()) + require.NoError(t, desktopRes.Err) + require.Equal(t, uint(0), *desktopRes.FailingPolicies) +}