Critical severityNVD Advisory· Published Mar 6, 2025· Updated Apr 15, 2026
CVE-2025-27509
CVE-2025-27509
Description
fleetdm/fleet is an open source device management, built on osquery. In vulnerable versions of Fleet, an attacker could craft a specially-formed SAML response to forge authentication assertions, provision a new administrative user account if Just-In-Time (JIT) provisioning is enabled, or create new accounts tied to forged assertions if f MDM enrollment is enabled. This vulnerability is fixed in 4.64.2, 4.63.2, 4.62.4, and 4.58.1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/fleetdm/fleet/v4Go | >= 4.64.0, < 4.64.2 | 4.64.2 |
github.com/fleetdm/fleet/v4Go | >= 4.63.0, < 4.63.2 | 4.63.2 |
github.com/fleetdm/fleet/v4Go | >= 4.62.0, < 4.62.4 | 4.62.4 |
github.com/fleetdm/fleet/v4Go | >= 4.54.0, < 4.58.1 | 4.58.1 |
github.com/fleetdm/fleet/v4Go | < 4.53.2 | 4.53.2 |
Patches
57a7aebb82a8d1b6be19eb92d178676ec5ba55ead113564d2718c95e47ad0Merge commit from fork (#26853)
2 files changed · +34 −23
changes/9778-saml-validation-workflow+1 −0 added@@ -0,0 +1 @@ +* Improved SAML validation workflow.
server/sso/validate.go+33 −23 modified@@ -15,7 +15,6 @@ import ( "github.com/fleetdm/fleet/v4/server/fleet" rtvalidator "github.com/mattermost/xml-roundtrip-validator" dsig "github.com/russellhaering/goxmldsig" - "github.com/russellhaering/goxmldsig/etreeutils" ) type Validator interface { @@ -161,38 +160,50 @@ func (v *validator) validateSignature(elt *etree.Element) (*etree.Element, error // If entire doc is signed, success, we're done. return validated, nil } + // Some IdPs (like Google) do not sign the root, and only sign the Assertion. if err == dsig.ErrMissingSignature { - // If entire document is not signed find signed assertions, remove assertions - // that are not signed. - err = v.validateAssertionSignature(elt) - if err != nil { + if err := v.validateAssertionSignature(elt); err != nil { return nil, err } return elt, nil } - return nil, err } +var ( + errMissingAssertion = errors.New("missing Assertion element under namespace urn:oasis:names:tc:SAML:2.0:assertion") + errMultipleAssertions = errors.New("multiple Assertions elements found") + errAssertionWithInvalidNamespace = errors.New("Assertion with invalid namespace found") +) + +// validateAssertionSignature validates that one "Assertion" child element exists under +// the "urn:oasis:names:tc:SAML:2.0:assertion" namespace and that it's signed by the IdP. +// It returns: +// - errMissingAssertion if there is no "Assertion" child element under the given tree. +// - errMultipleAssertions if there's more than one "Assertion" element under the given tree. +// - errAssertionWithInvalidNamespace if an "Assertion" element has a namespace that's not +// "urn:oasis:names:tc:SAML:2.0:assertion" +// - an error if the signature of the one "Assertion" element is invalid. func (v *validator) validateAssertionSignature(elt *etree.Element) error { - validateAssertion := func(ctx etreeutils.NSContext, unverified *etree.Element) error { - if unverified.Parent() != elt { - return fmt.Errorf("assertion with unexpected parent: %s", unverified.Parent().Tag) - } - // Remove assertions that are not signed. - detached, err := etreeutils.NSDetatch(ctx, unverified) - if err != nil { - return err + var assertion *etree.Element + for _, child := range elt.ChildElements() { + if child.Tag == "Assertion" { + if child.NamespaceURI() != "urn:oasis:names:tc:SAML:2.0:assertion" { + return errAssertionWithInvalidNamespace + } + if assertion != nil { + return errMultipleAssertions + } + assertion = child } - signed, err := v.context.Validate(detached) - if err != nil { - return err - } - elt.RemoveChild(unverified) - elt.AddChild(signed) - return nil } - return etreeutils.NSFindIterate(elt, "urn:oasis:names:tc:SAML:2.0:assertion", "Assertion", validateAssertion) + if assertion == nil { + return errMissingAssertion + } + if _, err := v.context.Validate(assertion); err != nil { + return fmt.Errorf("failed to validate assertion signature: %w", err) + } + return nil } const ( @@ -221,7 +232,6 @@ func generateSAMLValidID() (string, error) { func ValidateAudiences(metadata Metadata, auth fleet.Auth, audiences ...string) error { validator, err := NewValidator(metadata, WithExpectedAudience(audiences...)) - if err != nil { return fmt.Errorf("create validator from metadata: %w", err) }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-52jx-g6m5-h735ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-27509ghsaADVISORY
- github.com/fleetdm/fleet/commit/718c95e47ad010ad6b8ceb3f3460e921fbfc53bbnvdWEB
- github.com/fleetdm/fleet/releases/tag/fleet-v4.64.2ghsaWEB
- github.com/fleetdm/fleet/security/advisories/GHSA-52jx-g6m5-h735nvdWEB
- pkg.go.dev/vuln/GO-2025-3505ghsaWEB
News mentions
0No linked articles in our index yet.