mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 00:49:03 +00:00
AP: Validate top-level keys in android profile upload (#34360)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34334 # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually
This commit is contained in:
parent
92a58851fa
commit
4609bca8cf
2 changed files with 53 additions and 0 deletions
|
|
@ -6,6 +6,9 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/mdm"
|
||||
|
|
@ -71,6 +74,10 @@ func (m *MDMAndroidConfigProfile) ValidateUserProvided() error {
|
|||
if errMsg, ok := AndroidForbiddenJSONKeys[key]; ok {
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
|
||||
if !IsAndroidPolicyFieldValid(key) {
|
||||
return fmt.Errorf("Invalid JSON payload. Unknown key %q", key)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -134,3 +141,34 @@ type AndroidPolicyRequestPayload struct {
|
|||
type AndroidPolicyRequestPayloadMetadata struct {
|
||||
SettingsOrigin map[string]string `json:"settings_origin"` // Map of policy setting name, to profile uuid.
|
||||
}
|
||||
|
||||
var (
|
||||
policyFieldsCache map[string]bool
|
||||
policyFieldsOnce sync.Once
|
||||
)
|
||||
|
||||
// Initialize the cache once, lazily, with only JSON tag names.
|
||||
// Since we take in the JSON value.
|
||||
func initPolicyFieldsCache() {
|
||||
policyFieldsCache = make(map[string]bool)
|
||||
policyType := reflect.TypeOf(androidmanagement.Policy{})
|
||||
|
||||
for i := 0; i < policyType.NumField(); i++ {
|
||||
field := policyType.Field(i)
|
||||
|
||||
// Add JSON tag name if it exists
|
||||
jsonTag := field.Tag.Get("json")
|
||||
if jsonTag != "" {
|
||||
tagName := strings.Split(jsonTag, ",")[0]
|
||||
if tagName != "" && tagName != "-" {
|
||||
policyFieldsCache[tagName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fast lookup using cached field names
|
||||
func IsAndroidPolicyFieldValid(fieldName string) bool {
|
||||
policyFieldsOnce.Do(initPolicyFieldsCache)
|
||||
return policyFieldsCache[fieldName]
|
||||
}
|
||||
|
|
|
|||
15
server/fleet/android_test.go
Normal file
15
server/fleet/android_test.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package fleet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIsAndroidPolicyFieldValid(t *testing.T) {
|
||||
isValid := IsAndroidPolicyFieldValid("bogusKeyThatWillNeverExist")
|
||||
require.False(t, isValid)
|
||||
|
||||
isValid = IsAndroidPolicyFieldValid("name") // "name" is a valid top-level policy field, that we assume will exist forever
|
||||
require.True(t, isValid)
|
||||
}
|
||||
Loading…
Reference in a new issue