Make the plist parser slightly more tolerant (#47371)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #

# Checklist for submitter

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

No changes file, already covered

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved compatibility with multiple Apple plist format versions for
more reliable file handling.
* Strengthened validation of plist inputs to reduce false positives and
improve security.
* Adjusted early bounds checking so very short or malformed plist files
are handled more robustly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Jordan Montgomery
2026-06-10 17:31:46 -04:00
committed by GitHub
co-authored by Copilot Autofix powered by AI
parent c60f436654
commit c686f574fe
+5 -2
View File
@@ -14,7 +14,9 @@ import (
// dictionary of scalar values.
const (
// binaryPlistMagic is the prefix that selects the binary plist decoder.
binaryPlistMagic = "bplist00"
// Apple doesn't fully document all versions, but "bplist00" and "bplist01" are known.
// Using "bplist0" lets us accept any "bplist0<digit>" version header.
binaryPlistMagic = "bplist0"
plistTrailerSize = 32
maxPlistObjects = 1 << 16 // distinct objects (offset-table size)
@@ -42,7 +44,8 @@ func BoundedPlistUnmarshal(data []byte, v any) error {
// checkBinaryPlistBounds walks a binary plist's object references, rejecting
// input that exceeds the limits or points outside the data region.
func checkBinaryPlistBounds(data []byte) error {
if len(data) < len(binaryPlistMagic)+plistTrailerSize {
// See comment on binaryPlistMagic above for why the +1 is needed
if len(data) < len(binaryPlistMagic)+1+plistTrailerSize {
return fmt.Errorf("%w: shorter than minimum size", errMalformedPlist)
}