bypass not found mdm commands (#20369)

for #20367

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Roberto Dip 2024-07-11 11:40:48 -03:00 committed by GitHub
parent ccba6f1d05
commit bf6e506c50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 1 deletions

View file

@ -0,0 +1 @@
* Avoid returning a 500 status code if a host sends a command response with an invalid command uuid.

View file

@ -232,7 +232,21 @@ func (s *Service) CommandAndReportResults(r *mdm.Request, results *mdm.CommandRe
logger.Info(logs...)
err := s.store.StoreCommandReport(r, results)
if err != nil {
return nil, fmt.Errorf("storing command report: %w", err)
// allow not found commands, this is an edge case only
// valid for migrations, other response codes confuse the
// mdmclient, and this gives us the opportunity to answer
// with more commands
if !service.IsNotFound(err) {
return nil, fmt.Errorf("storing command report: %w", err)
}
logger.Info(
"msg", "host reported status with invalid command uuid",
"command_uuid", results.CommandUUID,
"request_type", results.RequestType,
"status", results.Status,
"error_chain", results.ErrorChain,
)
}
cmd, err := s.store.RetrieveNextCommand(r, results.Status == "NotNow")
if err != nil {

View file

@ -119,6 +119,23 @@ func (m *MySQLStorage) StoreCommandReport(r *mdm.Request, result *mdm.CommandRes
if result.Status == "Idle" {
return nil
}
// ensure there's a matching command
matchingRow := m.db.QueryRowContext(
r.Context,
`SELECT 1 FROM nano_commands WHERE command_uuid = ?`,
result.CommandUUID,
)
var matchingCount int
if err := matchingRow.Scan(&matchingCount); err != nil {
return err
}
// this should be already handed by the error value in Scan above, but
// just to be safe
if matchingCount == 0 {
return sql.ErrNoRows
}
if m.rm && result.Status != "NotNow" {
return m.deleteCommandTx(r, result)
}

View file

@ -9250,6 +9250,15 @@ func (s *integrationMDMTestSuite) TestConnectedToFleetWithoutCheckout() {
require.False(t, *hostResp.Host.MDM.ConnectedToFleet)
}
func (s *integrationMDMTestSuite) TestInvalidCommandUUID() {
t := s.T()
_, device := createHostThenEnrollMDM(s.ds, s.server.URL, t)
s.runWorker()
cmd, err := device.Acknowledge("foo")
require.NoError(t, err)
require.NotNil(t, cmd)
}
func (s *integrationMDMTestSuite) TestEnrollAfterDEPSyncIOSIPadOS() {
t := s.T()
ctx := context.Background()