From 57e979f0a4ea40bdc204f45299e0499db9846796 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Mon, 16 Dec 2024 14:01:38 -0600 Subject: [PATCH 01/12] Swap JetBrains EAP versions for maxed last major release for vuln check purposes (#24783) For #22723. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --- changes/22723-jetbrains-eap-versions | 1 + server/service/osquery_utils/queries.go | 67 +++++++++++++++----- server/service/osquery_utils/queries_test.go | 42 ++++++++++++ 3 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 changes/22723-jetbrains-eap-versions diff --git a/changes/22723-jetbrains-eap-versions b/changes/22723-jetbrains-eap-versions new file mode 100644 index 0000000000..6efe38c674 --- /dev/null +++ b/changes/22723-jetbrains-eap-versions @@ -0,0 +1 @@ +* Aliased EAP versions of JetBrains IDEs to "last release version plus all fixes" (e.g. 2024.3 EAP -> 2024.2.99) to avoid vulnerability false positives \ No newline at end of file diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index 9d8e301e08..bc3dca255f 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -1599,15 +1599,9 @@ func directIngestSoftware(ctx context.Context, logger log.Logger, host *fleet.Ho var ( macOSMSTeamsVersion = regexp.MustCompile(`(\d).00.(\d)(\d+)`) citrixName = regexp.MustCompile(`Citrix Workspace [0-9]+`) -) - -// sanitizeSoftware performs any sanitization required to the ingested software fields. -// -// Some fields are reported with known incorrect values and we need to fix them before using them. -func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { - softwareSanitizers := []struct { + softwareSanitizers = []struct { checkSoftware func(*fleet.Host, *fleet.Software) bool - mutateSoftware func(*fleet.Software) + mutateSoftware func(*fleet.Software, log.Logger) }{ // "Microsoft Teams" on macOS defines the `bundle_short_version` (CFBundleShortVersionString) in a different // unexpected version format. Thus here we transform the version string to the expected format @@ -1623,7 +1617,7 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { checkSoftware: func(h *fleet.Host, s *fleet.Software) bool { return h.Platform == "darwin" && (s.Name == "Microsoft Teams.app" || s.Name == "Microsoft Teams classic.app") }, - mutateSoftware: func(s *fleet.Software) { + mutateSoftware: func(s *fleet.Software, logger log.Logger) { if matches := macOSMSTeamsVersion.FindStringSubmatch(s.Version); len(matches) > 0 { s.Version = fmt.Sprintf("%s.%s.00.%s", matches[1], matches[2], matches[3]) } @@ -1635,7 +1629,7 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { checkSoftware: func(h *fleet.Host, s *fleet.Software) bool { return h.Platform == "windows" && s.Name == "Cloudflare WARP" && s.Source == "programs" }, - mutateSoftware: func(s *fleet.Software) { + mutateSoftware: func(s *fleet.Software, logger log.Logger) { // Perform some sanity check on the version before mutating it. parts := strings.Split(s.Version, ".") if len(parts) <= 1 { @@ -1658,7 +1652,7 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { checkSoftware: func(h *fleet.Host, s *fleet.Software) bool { return citrixName.Match([]byte(s.Name)) || s.Name == "Citrix Workspace.app" }, - mutateSoftware: func(s *fleet.Software) { + mutateSoftware: func(s *fleet.Software, logger log.Logger) { parts := strings.Split(s.Version, ".") if len(parts) <= 1 { level.Debug(logger).Log("msg", "failed to parse software version", "name", s.Name, "version", s.Version) @@ -1694,7 +1688,7 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { checkSoftware: func(h *fleet.Host, s *fleet.Software) bool { return s.Name == "minio" && strings.Contains(s.Version, "RELEASE.") }, - mutateSoftware: func(s *fleet.Software) { + mutateSoftware: func(s *fleet.Software, logger log.Logger) { s.Version = strings.TrimPrefix(s.Version, "RELEASE.") }, }, @@ -1705,7 +1699,7 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { return s.Name == "minio" && regex.MatchString(s.Version) }, - mutateSoftware: func(s *fleet.Software) { + mutateSoftware: func(s *fleet.Software, logger log.Logger) { timestamp, err := time.Parse("20060102150405", s.Version) if err != nil { level.Debug(logger).Log("msg", "failed to parse software version", "name", s.Name, "version", s.Version, "err", err) @@ -1714,11 +1708,54 @@ func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { s.Version = timestamp.Format("2006-01-02T15-04-05Z") }, }, - } + { + // JetBrains EAP version numbers aren't what are used in CPEs; this handles the translation for Mac versions. + // See #22723 for background. Bundle identifier for EAPs also ends with "-EAP" but checking version makes it + // a bit easier to add other platforms later. EAP version numbers are e.g. EAP GO-243.21565.42, and checking + // here for the dash ensures that string splitting in the mutator always works without a bounds check. + checkSoftware: func(h *fleet.Host, s *fleet.Software) bool { + return s.BundleIdentifier != "" && strings.HasPrefix(s.BundleIdentifier, "com.jetbrains.") && + strings.HasPrefix(s.Version, "EAP ") && strings.Contains(s.Version, "-") + }, + mutateSoftware: func(s *fleet.Software, logger log.Logger) { + // 243 -> 2024.3 + eapMajorVersion := strings.Split(strings.Split(s.Version, "-")[1], ".")[0] + yearBasedMajorVersion, err := strconv.Atoi("20" + eapMajorVersion[:2]) + if err != nil { + level.Debug(logger).Log("msg", "failed to parse JetBrains EAP major version", "version", s.Version, "err", err) + return + } + yearBasedMinorVersion, err := strconv.Atoi(eapMajorVersion[2:]) + if err != nil { + level.Debug(logger).Log("msg", "failed to parse JetBrains EAP minor version", "version", s.Version, "err", err) + return + } + // EAPs are treated as having all fixes from the previous year-based release, but no fixes from the + // year-based release they're an EAP of. The exception to this would be CVE-2024-37051, which was fixed + // in a second/third EAP depending on product, but at this point all vulnerable EAPs force exit on + // startup due to being expired, so that CVE can't be exploited. + yearBasedMinorVersion -= 1 + if yearBasedMinorVersion <= 0 { // wrap e.g. 2024.1 to 2023.4 (not a real version, but has all 2023.3 fixes) + yearBasedMajorVersion -= 1 + yearBasedMinorVersion = 4 + } + + // pass through minor and patch version for EAP to tell different EAP builds apart + eapMinorAndPatchVersion := strings.Join(strings.Split(strings.Split(s.Version, "-")[1], ".")[1:], ".") + s.Version = fmt.Sprintf("%d.%d.%s.%s", yearBasedMajorVersion, yearBasedMinorVersion, "99", eapMinorAndPatchVersion) + }, + }, + } +) + +// sanitizeSoftware performs any sanitization required to the ingested software fields. +// +// Some fields are reported with known incorrect values and we need to fix them before using them. +func sanitizeSoftware(h *fleet.Host, s *fleet.Software, logger log.Logger) { for _, softwareSanitizer := range softwareSanitizers { if softwareSanitizer.checkSoftware(h, s) { - softwareSanitizer.mutateSoftware(s) + softwareSanitizer.mutateSoftware(s, logger) return } } diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index bf66be3665..a1c366dfe0 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -1920,6 +1920,48 @@ func TestSanitizeSoftware(t *testing.T) { Version: "2020-03-10T00-00-00Z", }, }, + { + name: "JetBrains non-EAP", + h: &fleet.Host{}, + s: &fleet.Software{ + Name: "GoLand.app", + Version: "2024.3.1", + BundleIdentifier: "com.jetbrains.goland", + }, + sanitized: &fleet.Software{ + Name: "GoLand.app", + Version: "2024.3.1", + BundleIdentifier: "com.jetbrains.goland", + }, + }, + { + name: "JetBrains EAP", + h: &fleet.Host{}, + s: &fleet.Software{ + Name: "GoLand.app", + Version: "EAP GO-243.21565.42", + BundleIdentifier: "com.jetbrains.goland-EAP", + }, + sanitized: &fleet.Software{ + Name: "GoLand.app", + Version: "2024.2.99.21565.42", + BundleIdentifier: "com.jetbrains.goland-EAP", + }, + }, + { + name: "JetBrains year-wrapped EAP", + h: &fleet.Host{}, + s: &fleet.Software{ + Name: "IntelliJ IDEA CE", + Version: "EAP IC-241.12345.67", + BundleIdentifier: "com.jetbrains.intellij-EAP", + }, + sanitized: &fleet.Software{ + Name: "IntelliJ IDEA CE", + Version: "2023.4.99.12345.67", + BundleIdentifier: "com.jetbrains.intellij-EAP", + }, + }, } { t.Run(tc.name, func(t *testing.T) { sanitizeSoftware(tc.h, tc.s, log.NewNopLogger()) From cbac9e89895414494c6d40a5d0994f145110e7eb Mon Sep 17 00:00:00 2001 From: Drew Baker <89049099+Drew-P-drawers@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:32:23 -0500 Subject: [PATCH 02/12] Update consolidate-multiple-tools-with-fleet.md (#24809) Removing redundancy for clarity. --- articles/consolidate-multiple-tools-with-fleet.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/articles/consolidate-multiple-tools-with-fleet.md b/articles/consolidate-multiple-tools-with-fleet.md index cfc4da7199..9de6c4cad0 100644 --- a/articles/consolidate-multiple-tools-with-fleet.md +++ b/articles/consolidate-multiple-tools-with-fleet.md @@ -9,8 +9,6 @@ We've been using Fleet for a few years and we couldn't be happier. The fact that ## Challenge -Scaling organizations face a common challenge: managing every device efficiently across varying teams and locations. Here, we take a deeper look at the impact that Fleet has made at a leading financial technology company. - The leading financial company looked to simplify how they manage devices and reduce tool overlap without sacrificing control over their infrastructure. The use of multiple proprietary device management tools was creating operational silos, and it required specialized expertise for different legacy systems, leading to inefficiencies. ## Solution From f0b49a58b02b05f470e5052684ff950d76f7c720 Mon Sep 17 00:00:00 2001 From: Brock Walters <153771548+nonpunctual@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:33:46 -0500 Subject: [PATCH 03/12] Update seamless-mdm-migration.md (#24756) Added a note to this article that it's not intended to be fully self service at this time per Zay... Thanks! --- articles/seamless-mdm-migration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/articles/seamless-mdm-migration.md b/articles/seamless-mdm-migration.md index 369c6c1714..4474924325 100644 --- a/articles/seamless-mdm-migration.md +++ b/articles/seamless-mdm-migration.md @@ -1,5 +1,7 @@ # Seamless macOS MDM migration +> NOTE: Please contact Fleet here https://fleetdm.com/contact or reach out to the Fleet Customer Success team if you are a current Fleet customer for consultation when considering this migration path. We'd love to help! + ![Seamless macOS MDM migrations to Fleet](../website/assets/images/articles/seamless-mdm-migration-1600x900@2x.png) Migrating macOS devices between Mobile Device Management (MDM) solutions is often fraught with challenges, including potential gaps in device management, user disruption, and compliance issues. Traditional MDM migrations typically require end-user interaction and leave devices unmanaged for a period, leading to problems like Wi-Fi disconnections due to certificate profile removal and incomplete migrations. These challenges can force organizations to stay with outdated MDM solutions that no longer meet their needs. But there’s a better way. From cc2faac78171178a2ed35d6b52e2b3e9793e61d4 Mon Sep 17 00:00:00 2001 From: Robert Fairburn <8029478+rfairburn@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:09:17 -0600 Subject: [PATCH 04/12] Add JSON logging to loadtesting (#24808) --- infrastructure/loadtesting/terraform/ecs.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infrastructure/loadtesting/terraform/ecs.tf b/infrastructure/loadtesting/terraform/ecs.tf index 2327c2787b..fb1b13205a 100644 --- a/infrastructure/loadtesting/terraform/ecs.tf +++ b/infrastructure/loadtesting/terraform/ecs.tf @@ -132,6 +132,10 @@ resource "aws_ecs_task_definition" "backend" { } ] environment = concat([ + { + name = "FLEET_LOGGING_JSON" + value = "true" + }, { name = "FLEET_MYSQL_USERNAME" value = module.aurora_mysql.cluster_master_username From 78cab5b8a83b22548d59f8fac8f5ccc3d9596291 Mon Sep 17 00:00:00 2001 From: Jacob Burley Date: Tue, 17 Dec 2024 00:03:33 +0100 Subject: [PATCH 05/12] Add Mastodon link to server email templates (#23309) - Adds a link to FleetDM's Mastodon account to emails sent by the FleetDM server - Adds a Mastodon PNG image to the repo --- changes/23309-mastodon-in-email-templates | 1 + .../templates/change_email_confirmation.html | 7 +++++++ server/mail/templates/invite_token.html | 7 +++++++ server/mail/templates/mfa.html | 7 +++++++ server/mail/templates/password_reset.html | 7 +++++++ server/mail/templates/smtp_setup.html | 7 +++++++ .../images/permanent/mastodon-logo-50x40@2x.png | Bin 0 -> 1857 bytes 7 files changed, 36 insertions(+) create mode 100644 changes/23309-mastodon-in-email-templates create mode 100644 website/assets/images/permanent/mastodon-logo-50x40@2x.png diff --git a/changes/23309-mastodon-in-email-templates b/changes/23309-mastodon-in-email-templates new file mode 100644 index 0000000000..6eac06da3e --- /dev/null +++ b/changes/23309-mastodon-in-email-templates @@ -0,0 +1 @@ +* Added Mastodon icon and URL to server email templates. diff --git a/server/mail/templates/change_email_confirmation.html b/server/mail/templates/change_email_confirmation.html index d557c06180..917e45a8a2 100644 --- a/server/mail/templates/change_email_confirmation.html +++ b/server/mail/templates/change_email_confirmation.html @@ -143,6 +143,13 @@ src="{{.AssetURL}}/fleet-mark-color-40x40@2x.png" /> + + Mastodon logo + X logo + + Mastodon logo + X logo + + Mastodon logo + X logo + + Mastodon logo + X logo + + Mastodon logo + X logoF5Wq2pGtvv;gI@ z;O?^Q?d(~0_vwGOm4H3Z%Pu1Z@62!1;r*ZY`Lkz1c9Engm(diw9iD`lumEjo<;+`W`#b2qk02 z_uxjpNRE;U4xkZEhCGOTWDMEfBz&NK1PmE1GiH8yKneLqr~(>g4)vDM>pa&Rbn@Fk z(K6y9i{A0l+A@VUZ~WK#wF)g;>}u z!2I$57Rhqo1xJ9Qv7o?1dw=jzQ&WH(jv)E{6ykCPsih@AKkx6M!UY~Szpl(nr%w9G zVhNHg69oc9ib7CQAAY*Xs}j5?Na+Q)kEEC9bUY_5hU?%f0#C zUn(SfqR&^J@zYyxxP>!?nPD1=I5z=_%+))|jKN}Et+>_l4NfXv?hf5Tv93c0eZslI zypSa2q&xNjiF~l$6Z;h5wfieCoje}hEj4hd&$~Rmcs2+^vXqn7{Ra@ol+{h;C$$H$ zSp)RVE}2#?anZ6OCvE-MLrsl-3ii2!)W7%rw=4&#{FIN@mAYx^J5E}=+C@hXE7Zeu z{dALuovja}l#^;V191uq9CYElKjHxONxx;YJ7WL4OPqA+V&wiS>&PL6<{7*DWpZ_P z`t28mf*QBqfuFqWY<=XRNS70cvvRS6I?RzLoIIwGDN{SM^<%eY2@js^`Fgu%W<`;M z+S?*O0TtywGBW4%F<;6~vH5{GtCu@Mx6r_~=W7p}DJ-yS7OAi8VKZ;cwNpb~Pei8r ztdH_@y4YM8iX>Y}WX;NMvUf!m`C_|EnA7?yb@Z^8-9IcL8xqSJ(wb z_?*kBRYYd@=Vn+0MXbWJAX(DQ?lc2&N|$$O-&&tL*^G)S!tFPuU)C(5-dghw7SUM& zm@VmMbu^N+3?@QY%xWo6V?Pj>t@?2(#amV&;ovcZkk% zLxPm`O4|t_PRUY>W|19RyV;CNyNH|JZ%k=ti_FV5i_UVw3>0ZS48$o}a+xV&XEQ3z zBEP!X{l?@r6p=NGcxj%lU38Wmrb}5#t$TquY?06GY-T8ob5P{8pa`F}K)jTdcxfjP zr(|&_*=>>k2ioyj7n>Ohi@zQ1>&gw-SY!Oi|R)*OvRLK>| zY!zkC!b4K#%;qv64qIf4jm->&VfIB7iTnYsu3AQs7E$&v+$m)yG%p0=tS&P1MFhE6 z8DF@&?Poe@xu0qb4nMPN&iYS zpG|0*6e^N2qcI7*K%>xs-d7qkUiv!@I)FwQOU8`96Z;hT>v5<98btz71pmFYkn!S$ zd*B4nDDpjw>-S20`tG#957)5;dW$^YFaan=R>+4$D1_~B5SqXjMcxlKI1k5Q2b6#w z5?~UHA9VPEEA6@Z3ZNJ$kjz}`2ABws4e%&TfLmi8FzO=lb*q44w0_tI8tO`Ww)R1& z0E$5y-1dLZ-fv-`G4N*EGv_Eq%Yc8+`~O&}&(x^)f*&YKa%x=7Mz|luzmcGIW?ao! z7_a_$b<4!nJdzq$eFP{50VszJFcq}FVTG<=JprbG9#+ARa2)QvszpMFP5b>8*bfTO z5ZT}Y)Q0^9Ucvr{u6mJhnY-bW)Tw9b8hLnFiu4wmT9pNrK*Q{TVJ(s}rD_a30^3ri zR62mJG7GM~4sIIOBK=A|U2!|S3Ex5kxPfBig?jide62gKSpkhgH^GyT04q}_pV literal 0 HcmV?d00001 From c6f922ba6b5657d95d54a0b429b93697de1e49be Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 16 Dec 2024 17:07:02 -0600 Subject: [PATCH 06/12] Website: add links to recent case studies to /testimonials. (#24814) Related to: #24746 Changes: - Added links to recent case studies articles to the /testimonials page. --- website/assets/styles/pages/testimonials.less | 38 +++++++++++++++++++ website/views/pages/testimonials.ejs | 26 +++++++++++++ 2 files changed, 64 insertions(+) diff --git a/website/assets/styles/pages/testimonials.less b/website/assets/styles/pages/testimonials.less index 787c64738c..f825fed4ab 100644 --- a/website/assets/styles/pages/testimonials.less +++ b/website/assets/styles/pages/testimonials.less @@ -100,6 +100,34 @@ } } + [purpose='section-headline'] { + padding-top: 64px; + padding-bottom: 64px; + p { + margin-bottom: 0px; + } + } + [purpose='articles'] { + padding-bottom: 64px; + } + [purpose='article-link'] { + padding-top: 24px; + padding-bottom: 24px; + border-bottom: 1px solid var(--Fleet-Black-10, #E2E4EA); + [parasails-component='animated-arrow-button'] { + width: fit-content; + display: flex; + align-items: center; + padding: 0; + text-decoration: none; + font-weight: 700; + [purpose='button-text'] { + width: 100%; + } + } + } + + [purpose='testimonials-container'] { columns: 3; margin-bottom: 32px; @@ -427,6 +455,16 @@ height: 304px; } } + [purpose='section-headline'] { + padding-top: 32px; + padding-bottom: 32px; + p { + margin-bottom: 0px; + } + } + [purpose='articles'] { + padding-bottom: 48px; + } [purpose='statistics'] { [purpose='statistics-column'] { display: flex; diff --git a/website/views/pages/testimonials.ejs b/website/views/pages/testimonials.ejs index 5fd1f40323..d4dd1c7153 100644 --- a/website/views/pages/testimonials.ejs +++ b/website/views/pages/testimonials.ejs @@ -112,6 +112,32 @@
+
+

Case strudies

+

Real-world stories of why the community and customers love Fleet.

+
+
+
+
+ 🥀 Leading financial company consolidates multiple tools with Fleet +
+
+ 🪟 Global edge cloud platform simplifies device management with Fleet +
+
+ 🚪 Worldwide security and authentication platform chooses Fleet for Linux management +
+
+ 🔌 Large gaming company enhances server observability with Fleet +
+
+ 🚪 Vehicle manufacturer transitions to Fleet for endpoint security +
+
+ 🚪 Foursquare quickly migrates to Fleet for Device Management +
+
+
From 8759f4b23f2d3f43e77323d7c7ee88c92743d839 Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:50:56 -0500 Subject: [PATCH 07/12] Currently, Fleet Desktop for Kubuntu requires Google Chrome (#24812) More context: https://github.com/fleetdm/fleet/issues/23697#issuecomment-2546913113 --------- Co-authored-by: Rachael Shaw --- docs/Get started/FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Get started/FAQ.md b/docs/Get started/FAQ.md index d5da69c959..10d4afe9f2 100644 --- a/docs/Get started/FAQ.md +++ b/docs/Get started/FAQ.md @@ -94,7 +94,7 @@ If a table is not available for your host, Fleet will generally handle things be Fleet Desktop is supported on Ubuntu and Fedora. -Fedora requires a [gnome extension](https://extensions.gnome.org/extension/615/appindicator-support/) and Google Chrome for Fleet Desktop. +Fedora and some flavors of Ubuntu (e.g. Kubuntu) require a [gnome extension](https://extensions.gnome.org/extension/615/appindicator-support/) and Google Chrome for Fleet Desktop. Fleet's default (un)install scripts use `apt-get` for Debian-based distributions, and `dnf` for Red Hat-based distributions. To install packages on CentOS versions prior to 8, either add `dnf` or edit install and uninstall scripts to use the `yum` or `rpm` command. From be5748251cb00db8a9c47b81701219c41aefac12 Mon Sep 17 00:00:00 2001 From: Drew Baker <89049099+Drew-P-drawers@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:13:12 -0500 Subject: [PATCH 08/12] Update foursquare-quickly-migrates-to-fleet.md (#24818) Removed additional quotation marks # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [ ] Added/updated tests - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes - [ ] If database migrations are included, checked table schema to confirm autoupdate - For database migrations: - [ ] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [ ] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). - [ ] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit feature/bugfix should only apply to one platform (`runtime.GOOS`). - [ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux. - [ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)). --- articles/foursquare-quickly-migrates-to-fleet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/foursquare-quickly-migrates-to-fleet.md b/articles/foursquare-quickly-migrates-to-fleet.md index 697cee4044..0fc128180e 100644 --- a/articles/foursquare-quickly-migrates-to-fleet.md +++ b/articles/foursquare-quickly-migrates-to-fleet.md @@ -2,7 +2,7 @@
-“After several fast-paced weeks of planning, testing, and collaboration, our corporate engineering team at Foursquare has officially completed the migration to Fleet Device Management as our new device management platform. This move represents a big step forward for us.” +After several fast-paced weeks of planning, testing, and collaboration, our corporate engineering team at Foursquare has officially completed the migration to Fleet Device Management as our new device management platform. This move represents a big step forward for us. **— Mike Meyer, Manager, Corporate Engineering at Foursquare**
From 22b81d149751e69accf8d4198e9ab6444759d62c Mon Sep 17 00:00:00 2001 From: Drew Baker <89049099+Drew-P-drawers@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:08:50 -0500 Subject: [PATCH 09/12] Create global-social-media-platform-switches-to-fleet.md (#24819) --- ...social-media-platform-switches-to-fleet.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 articles/global-social-media-platform-switches-to-fleet.md diff --git a/articles/global-social-media-platform-switches-to-fleet.md b/articles/global-social-media-platform-switches-to-fleet.md new file mode 100644 index 0000000000..37a299b07c --- /dev/null +++ b/articles/global-social-media-platform-switches-to-fleet.md @@ -0,0 +1,78 @@ +# Global social media platform switches to Fleet for workstation telemetry + +
+ +Context is king for device data, and Fleet provides a way to surface that information to our other teams and partners. +**- Systems and infrastructure manager** +
+ +## Challenge + +One of the largest social media platforms sought to enhance its telemetry capabilities to maintain strict compliance and security without compromising data accessibility and operational efficiency. Managing thousands of devices across multiple platforms had led to fragmented visibility and reliance on manual data handling processes, which were time-consuming and error-prone. Additionally, the existing solution failed to provide actionable insights without significant customization, hindering proactive operations and complicating compliance with ongoing [ISO27002](https://www.iso.org/standard/75652.html) and [SOC audit](https://en.wikipedia.org/wiki/System_and_Organization_Controls) requirements. + +## Solution + +The social media platform transitioned to Fleet, consolidating under a single, [multi-platform](https://fleetdm.com/orchestration) system that supports macOS, Linux, and Windows. Fleet's compliance features made it easier to meet regulatory standards and protect sensitive data. Leveraging Fleet's real-time reporting and flexible data management capabilities eliminated the need for manual workflows and extensive customizations. Additionally, deploying [osquery](https://osquery.io/) independently from their existing EDR enhanced data accuracy and reliability, providing more accurate measurement against other benchmarks like [CIS](https://www.cisecurity.org/cis-benchmarks), and standardized osquery operations across their entire fleet. + +## Results + +
+ +Verifiable compliance + +Cross-team data accessibility + +Real-time insights + +Standardized processes +
+ +By switching to Fleet, they were able to institute more stringent compliance policies, verify security posture, gather real-time insight into ongoing operations, and standardize these processes across their growing fleet of diverse devices and teams. + + +## Their story + +This social media platform is one of the largest globally, connecting thousands of communities and millions of users. With a vast user base and a significant global presence, effective visibility is essential to maintaining their required performance, security, and compliance standards. + +The decision to switch to Fleet was driven by a few key factors. Strict adherence to compliance standards, balancing proactive and reactive security measures to protect sensitive data, and streamlining device data accessibility. By making data easily accessible and parsable, Fleet eliminated the inefficiencies of manual workflows and addressed communication gaps across teams, enabling better, faster decision-making. + + +With Fleet, they achieved this through: + +- Eliminating tool overlap + +- Definitive data for compliance and real-time reporting + +- Robust API and webhook support + +- A Unified reporting language + +### Eliminate tool overlap + +Fleet’s centralized platform enabled the combination of device operations across macOS, Windows, and Linux with a [unified reporting language](https://fleetdm.com/docs/deploy/reference-architectures#mysql) that provides flexibility and contextualized data. By adhering to standard data shapes and formats, Fleet makes sure that data is easily interpretable and usable across various teams and applications while serving as the central hub for security data. + +### Definitive data for compliance + +Fleet’s live query engine streams easily accessible and parsable [data](https://fleetdm.com/tables/account_policy_data), eliminating the need for manual exports and data consolidation from multiple tools. With accurate visibility and access across teams, remediations based on information directly from each device lead to fewer infrastructure failures and auditing errors. + +### Robust API and webhook support + +Fleet’s API facilitates real-time [compliance](https://fleetdm.com/queries) auditing and reporting, allowing the team to respond promptly to potential issues by combining data from different tools. The [API](https://fleetdm.com/docs/rest-api/rest-api) and webhook features enable automation and integration with existing systems, eliminating the need for extra middleware and reducing reliance on manual configurations. + +### Unified reporting language + +Fleet's straightforward deployment of the osquery agent across their devices as an independent element ensured data accuracy and reliability while standardizing its operations across macOS, Windows, and Linux. This allowed the social media platform to inspect, collect, fix, install, patch, and program just about anything, every minute of the day, on any computer in their infrastructure, with an unnoticeable performance impact + + +## Conclusion + +Transitioning to Fleet provided the platform with a strategic solution that addressed its critical needs for compliance, security, data accessibility, and operational efficiency. Fleet's cross-platform support and open-source transparency set it apart from competitors, providing a single source of truth for all devices. + + + + + + + + + From 35f0741c82dee6eb0bffe41212bb979cce7443f9 Mon Sep 17 00:00:00 2001 From: Drew Baker <89049099+Drew-P-drawers@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:32:42 -0500 Subject: [PATCH 10/12] Update global-social-media-platform-switches-to-fleet.md (#24820) Update publish date and spacing for quote title. --- articles/global-social-media-platform-switches-to-fleet.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/articles/global-social-media-platform-switches-to-fleet.md b/articles/global-social-media-platform-switches-to-fleet.md index 37a299b07c..6829aa7e53 100644 --- a/articles/global-social-media-platform-switches-to-fleet.md +++ b/articles/global-social-media-platform-switches-to-fleet.md @@ -3,7 +3,8 @@
Context is king for device data, and Fleet provides a way to surface that information to our other teams and partners. -**- Systems and infrastructure manager** + +**- Systems and Infrastructure Manager**
## Challenge @@ -73,6 +74,6 @@ Transitioning to Fleet provided the platform with a strategic solution that addr - + From edc68d304215e3ab47af13bb4ff2e24ab8ff8407 Mon Sep 17 00:00:00 2001 From: Scott Gress Date: Tue, 17 Dec 2024 09:46:03 -0600 Subject: [PATCH 11/12] Add versions to product names in MSRC bulletins to aid Windows vulnerability matching (#24172) for #24041 This PR addresses an issue that can cause Windows vulnerability checks to fail (possibly causing false negatives). We determine whether a vulnerability in an MSRC bulletin applies to any hosts in a Fleet instance by attempting to matching the data in [each row of the `operating_systems` table](https://github.com/fleetdm/fleet/blob/65e374c85c32a7dd582aa1d438161663a4abc43c/cmd/fleet/cron.go#L297-L303) with [at least one "product" in a bulletin](https://github.com/fleetdm/fleet/blob/e2d9a9016cb2bbf6cfe0ef7512f58d9934bf69de/server/vulnerabilities/msrc/analyzer.go#L39), including [matching architecture and "display version"](https://github.com/fleetdm/fleet/blob/76f5baced9360576743c9aa87a62f30b0fe63d45/server/vulnerabilities/msrc/parsed/product.go#L26-L39). However a subset of products listed in these bulletins do not include the display version, so for example a host whose OS was listed as `Microsoft Windows Server 2022 Datacenter 21H2` (21H2 being the "display version") would match nothing in the bulletins because no listed Server 2022 products include "21H2" in their names. The fix made here is to add relevant version info to the products list when we do our ETL of the MSRC bulletins. The version info was gleaned from https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions. We see logs related to this issue a lot, so cleaning this up will alleviate some noise and infra costs as well. --- cmd/fleet/cron.go | 2 +- server/vulnerabilities/msrc/parsed/product.go | 48 +- .../msrc/parsed/product_test.go | 491 ++++++++++-------- .../msrc/parsed/security_bulletin.go | 6 +- server/vulnerabilities/msrc/parser_test.go | 77 ++- 5 files changed, 409 insertions(+), 215 deletions(-) diff --git a/cmd/fleet/cron.go b/cmd/fleet/cron.go index 1adc6ade43..36e00ddaaf 100644 --- a/cmd/fleet/cron.go +++ b/cmd/fleet/cron.go @@ -309,7 +309,7 @@ func checkWinVulnerabilities( "found new", len(r)) results = append(results, r...) if err != nil { - errHandler(ctx, logger, "analyzing hosts for Windows vulnerabilities", err) + errHandler(ctx, kitlog.With(logger, "os name", o.Name, "display version", o.DisplayVersion), "analyzing hosts for Windows vulnerabilities", err) } } } diff --git a/server/vulnerabilities/msrc/parsed/product.go b/server/vulnerabilities/msrc/parsed/product.go index 2da20eac86..09b9caea87 100644 --- a/server/vulnerabilities/msrc/parsed/product.go +++ b/server/vulnerabilities/msrc/parsed/product.go @@ -66,7 +66,53 @@ func (p Products) GetMatchForOS(ctx context.Context, os fleet.OperatingSystem) ( } func NewProductFromFullName(fullName string) Product { - return Product(fullName) + // If the full name includes a version, return it as-is. + p := Product(fullName) + if p.HasDisplayVersion() { + return p + } + + // Several Windows products listed in MSRC bulletins don't include the OS version number. + // We need this to match the product with a host's OS, so we'll add them here. + versionString := "" + switch { + case strings.Contains(fullName, "Windows Server 2022"): + versionString = "21H2" + + case strings.Contains(fullName, "Windows Server 2016"): + versionString = "1607" + + case strings.Contains(fullName, "Windows Server 2019"): + versionString = "1809" + + case strings.Contains(fullName, "Windows 8.1"): + versionString = "6.3 / NT 6.3" + + case strings.Contains(fullName, "Windows RT 8.1"): + versionString = "6.3 / NT 6.3" + + case strings.Contains(fullName, "Windows Server 2012 R2"): + versionString = "6.3 / NT 6.3" + + case strings.Contains(fullName, "Windows Server 2012"): + versionString = "6.2 / NT 6.2" + + case strings.Contains(fullName, "Windows Server 2008 R2"): + versionString = "6.1 / NT 6.1" + + case strings.Contains(fullName, "Windows 7"): + versionString = "6.1 / NT 6.1" + + case strings.Contains(fullName, "Windows Server 2008"): + versionString = "6.0 / NT 6.0" + } + + finalName := fullName + if versionString != "" { + finalName += (" Version " + versionString) + } + + return Product(finalName) } func NewProductFromOS(os fleet.OperatingSystem) Product { diff --git a/server/vulnerabilities/msrc/parsed/product_test.go b/server/vulnerabilities/msrc/parsed/product_test.go index 13f7a4db49..4164617b06 100644 --- a/server/vulnerabilities/msrc/parsed/product_test.go +++ b/server/vulnerabilities/msrc/parsed/product_test.go @@ -67,354 +67,424 @@ func TestMatches(t *testing.T) { func TestFullProductName(t *testing.T) { testCases := []struct { - fullName string - arch string - prodName string + fullName string + arch string + prodName string + finalName string }{ { - fullName: "Windows 10 Version 1809 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1809 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1809 for 32-bit Systems", }, { - fullName: "Windows 10 Version 1809 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1809 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1809 for x64-based Systems", }, { - fullName: "Windows 10 Version 1809 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 1809 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 1809 for ARM64-based Systems", }, { - fullName: "Windows Server 2019", - arch: "all", - prodName: "Windows Server 2019", + fullName: "Windows Server 2019", + arch: "all", + prodName: "Windows Server 2019", + finalName: "Windows Server 2019 Version 1809", }, { - fullName: "Windows Server 2019 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2019", + fullName: "Windows Server 2019 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2019", + finalName: "Windows Server 2019 (Server Core installation) Version 1809", }, { - fullName: "Windows 10 Version 1909 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1909 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1909 for 32-bit Systems", }, { - fullName: "Windows 10 Version 1909 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1909 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1909 for x64-based Systems", }, { - fullName: "Windows 10 Version 1909 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 1909 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 1909 for ARM64-based Systems", }, { - fullName: "Windows 10 Version 21H1 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H1 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H1 for x64-based Systems", }, { - fullName: "Windows 10 Version 21H1 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H1 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H1 for ARM64-based Systems", }, { - fullName: "Windows 10 Version 21H1 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H1 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H1 for 32-bit Systems", }, { - fullName: "Windows Server 2022", - arch: "all", - prodName: "Windows Server 2022", + fullName: "Windows Server 2022", + arch: "all", + prodName: "Windows Server 2022", + finalName: "Windows Server 2022 Version 21H2", }, { - fullName: "Windows Server 2022 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2022", + fullName: "Windows Server 2022 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2022", + finalName: "Windows Server 2022 (Server Core installation) Version 21H2", }, { - fullName: "Windows 10 Version 20H2 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 20H2 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 20H2 for x64-based Systems", }, { - fullName: "Windows 10 Version 20H2 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 20H2 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 20H2 for 32-bit Systems", }, { - fullName: "Windows 10 Version 20H2 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 20H2 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 20H2 for ARM64-based Systems", }, { - fullName: "Windows Server, version 20H2 (Server Core Installation)", - arch: "all", - prodName: "Windows Server", + fullName: "Windows Server, version 20H2 (Server Core Installation)", + arch: "all", + prodName: "Windows Server", + finalName: "Windows Server, version 20H2 (Server Core Installation)", }, { - fullName: "Windows 11 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 11", + fullName: "Windows 11 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 11", + finalName: "Windows 11 for x64-based Systems", }, { - fullName: "Windows 11 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 11", + fullName: "Windows 11 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 11", + finalName: "Windows 11 for ARM64-based Systems", }, { - fullName: "Windows 10 Version 21H2 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H2 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H2 for 32-bit Systems", }, { - fullName: "Windows 10 Version 21H2 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H2 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H2 for ARM64-based Systems", }, { - fullName: "Windows 10 Version 21H2 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 21H2 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 21H2 for x64-based Systems", }, { - fullName: "Windows 10 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 for 32-bit Systems", }, { - fullName: "Windows 10 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 for x64-based Systems", }, { - fullName: "Windows 10 Version 1607 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1607 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1607 for 32-bit Systems", }, { - fullName: "Windows 10 Version 1607 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1607 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1607 for x64-based Systems", }, { - fullName: "Windows Server 2016", - arch: "all", - prodName: "Windows Server 2016", + fullName: "Windows Server 2016", + arch: "all", + prodName: "Windows Server 2016", + finalName: "Windows Server 2016 Version 1607", }, { - fullName: "Windows Server 2016 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2016", + fullName: "Windows Server 2016 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2016", + finalName: "Windows Server 2016 (Server Core installation) Version 1607", }, { - fullName: "Windows 8.1 for 32-bit systems", - arch: "32-bit", - prodName: "Windows 8.1", + fullName: "Windows 8.1 for 32-bit systems", + arch: "32-bit", + prodName: "Windows 8.1", + finalName: "Windows 8.1 for 32-bit systems Version 6.3 / NT 6.3", }, { - fullName: "Windows 8.1 for x64-based systems", - arch: "64-bit", - prodName: "Windows 8.1", + fullName: "Windows 8.1 for x64-based systems", + arch: "64-bit", + prodName: "Windows 8.1", + finalName: "Windows 8.1 for x64-based systems Version 6.3 / NT 6.3", }, { - fullName: "Windows RT 8.1", - arch: "all", - prodName: "Windows RT 8.1", + fullName: "Windows RT 8.1", + arch: "all", + prodName: "Windows RT 8.1", + finalName: "Windows RT 8.1 Version 6.3 / NT 6.3", }, { - fullName: "Windows Server 2012", - arch: "all", - prodName: "Windows Server 2012", + fullName: "Windows Server 2012", + arch: "all", + prodName: "Windows Server 2012", + finalName: "Windows Server 2012 Version 6.2 / NT 6.2", }, { - fullName: "Windows Server 2012 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2012", + fullName: "Windows Server 2012 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2012", + finalName: "Windows Server 2012 (Server Core installation) Version 6.2 / NT 6.2", }, { - fullName: "Windows Server 2012 R2", - arch: "all", - prodName: "Windows Server 2012 R2", + fullName: "Windows Server 2012 R2", + arch: "all", + prodName: "Windows Server 2012 R2", + finalName: "Windows Server 2012 R2 Version 6.3 / NT 6.3", }, { - fullName: "Windows Server 2012 R2 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2012 R2", + fullName: "Windows Server 2012 R2 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2012 R2", + finalName: "Windows Server 2012 R2 (Server Core installation) Version 6.3 / NT 6.3", }, { - fullName: "Windows 7 for 32-bit Systems Service Pack 1", - arch: "32-bit", - prodName: "Windows 7", + fullName: "Windows 7 for 32-bit Systems Service Pack 1", + arch: "32-bit", + prodName: "Windows 7", + finalName: "Windows 7 for 32-bit Systems Service Pack 1 Version 6.1 / NT 6.1", }, { - fullName: "Windows 7 for x64-based Systems Service Pack 1", - arch: "64-bit", - prodName: "Windows 7", + fullName: "Windows 7 for x64-based Systems Service Pack 1", + arch: "64-bit", + prodName: "Windows 7", + finalName: "Windows 7 for x64-based Systems Service Pack 1 Version 6.1 / NT 6.1", }, { - fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2", - arch: "32-bit", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2", + arch: "32-bit", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for 32-bit Systems Service Pack 2 Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)", - arch: "32-bit", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)", + arch: "32-bit", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation) Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 for x64-based Systems Service Pack 2", - arch: "64-bit", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for x64-based Systems Service Pack 2", + arch: "64-bit", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for x64-based Systems Service Pack 2 Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)", - arch: "64-bit", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)", + arch: "64-bit", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation) Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1", - arch: "64-bit", - prodName: "Windows Server 2008 R2", + fullName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1", + arch: "64-bit", + prodName: "Windows Server 2008 R2", + finalName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1 Version 6.1 / NT 6.1", }, { - fullName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)", - arch: "64-bit", - prodName: "Windows Server 2008 R2", + fullName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)", + arch: "64-bit", + prodName: "Windows Server 2008 R2", + finalName: "Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation) Version 6.1 / NT 6.1", }, { - fullName: "Windows 10 Version 1803 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1803 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1803 for x64-based Systems", }, { - fullName: "Windows Server, version 1803 (Server Core Installation)", - arch: "all", - prodName: "Windows Server", + fullName: "Windows Server, version 1803 (Server Core Installation)", + arch: "all", + prodName: "Windows Server", + finalName: "Windows Server, version 1803 (Server Core Installation)", }, { - fullName: "Windows 10 Version 1809 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1809 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1809 for x64-based Systems", }, { - fullName: "Windows Server 2019", - arch: "all", - prodName: "Windows Server 2019", + fullName: "Windows Server 2019", + arch: "all", + prodName: "Windows Server 2019", + finalName: "Windows Server 2019 Version 1809", }, { - fullName: "Windows Server 2019 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2019", + fullName: "Windows Server 2019 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2019", + finalName: "Windows Server 2019 (Server Core installation) Version 1809", }, { - fullName: "Windows 10 Version 1709 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1709 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1709 for x64-based Systems", }, { - fullName: "Windows 10 Version 1903 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1903 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1903 for x64-based Systems", }, { - fullName: "Windows Server, version 1903 (Server Core installation)", - arch: "all", - prodName: "Windows Server", + fullName: "Windows Server, version 1903 (Server Core installation)", + arch: "all", + prodName: "Windows Server", + finalName: "Windows Server, version 1903 (Server Core installation)", }, { - fullName: "Windows 10 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 for x64-based Systems", }, { - fullName: "Windows 10 Version 1607 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1607 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1607 for x64-based Systems", }, { - fullName: "Windows Server 2016", - arch: "all", - prodName: "Windows Server 2016", + fullName: "Windows Server 2016", + arch: "all", + prodName: "Windows Server 2016", + finalName: "Windows Server 2016 Version 1607", }, { - fullName: "Windows Server 2016 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2016", + fullName: "Windows Server 2016 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2016", + finalName: "Windows Server 2016 (Server Core installation) Version 1607", }, { - fullName: "Windows 8.1 for x64-based systems", - arch: "64-bit", - prodName: "Windows 8.1", + fullName: "Windows 8.1 for x64-based systems", + arch: "64-bit", + prodName: "Windows 8.1", + finalName: "Windows 8.1 for x64-based systems Version 6.3 / NT 6.3", }, { - fullName: "Windows Server 2012", - arch: "all", - prodName: "Windows Server 2012", + fullName: "Windows Server 2012", + arch: "all", + prodName: "Windows Server 2012", + finalName: "Windows Server 2012 Version 6.2 / NT 6.2", }, { - fullName: "Windows Server 2012 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2012", + fullName: "Windows Server 2012 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2012", + finalName: "Windows Server 2012 (Server Core installation) Version 6.2 / NT 6.2", }, { - fullName: "Windows Server 2012 R2", - arch: "all", - prodName: "Windows Server 2012 R2", + fullName: "Windows Server 2012 R2", + arch: "all", + prodName: "Windows Server 2012 R2", + finalName: "Windows Server 2012 R2 Version 6.3 / NT 6.3", }, { - fullName: "Windows Server 2012 R2 (Server Core installation)", - arch: "all", - prodName: "Windows Server 2012 R2", + fullName: "Windows Server 2012 R2 (Server Core installation)", + arch: "all", + prodName: "Windows Server 2012 R2", + finalName: "Windows Server 2012 R2 (Server Core installation) Version 6.3 / NT 6.3", }, { - fullName: "Windows 10 Version 1909 for x64-based Systems", - arch: "64-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1909 for x64-based Systems", + arch: "64-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1909 for x64-based Systems", }, { - fullName: "Windows Server, version 1909 (Server Core installation)", - arch: "all", - prodName: "Windows Server", + fullName: "Windows Server, version 1909 (Server Core installation)", + arch: "all", + prodName: "Windows Server", + finalName: "Windows Server, version 1909 (Server Core installation)", }, { - fullName: "Windows 10 Version 1803 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1803 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1803 for 32-bit Systems", }, { - fullName: "Windows 10 Version 1803 for ARM64-based Systems", - arch: "arm64", - prodName: "Windows 10", + fullName: "Windows 10 Version 1803 for ARM64-based Systems", + arch: "arm64", + prodName: "Windows 10", + finalName: "Windows 10 Version 1803 for ARM64-based Systems", }, { - fullName: "Windows 10 Version 1809 for 32-bit Systems", - arch: "32-bit", - prodName: "Windows 10", + fullName: "Windows 10 Version 1809 for 32-bit Systems", + arch: "32-bit", + prodName: "Windows 10", + finalName: "Windows 10 Version 1809 for 32-bit Systems", }, { - fullName: "None Available", - arch: "all", - prodName: "", + fullName: "None Available", + arch: "all", + prodName: "", + finalName: "None Available", }, { - fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)", - arch: "32-bit", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)", + arch: "32-bit", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation) Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 for Itanium-Based Systems Service Pack 2", - arch: "itanium", - prodName: "Windows Server 2008", + fullName: "Windows Server 2008 for Itanium-Based Systems Service Pack 2", + arch: "itanium", + prodName: "Windows Server 2008", + finalName: "Windows Server 2008 for Itanium-Based Systems Service Pack 2 Version 6.0 / NT 6.0", }, { - fullName: "Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1", - arch: "itanium", - prodName: "Windows Server 2008 R2", + fullName: "Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1", + arch: "itanium", + prodName: "Windows Server 2008 R2", + finalName: "Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1 Version 6.1 / NT 6.1", }, } @@ -429,6 +499,7 @@ func TestFullProductName(t *testing.T) { for _, tCase := range testCases { sut := NewProductFromFullName(tCase.fullName) require.Equal(t, tCase.prodName, sut.Name(), tCase) + require.Equal(t, tCase.finalName, string(sut), tCase) } }) } diff --git a/server/vulnerabilities/msrc/parsed/security_bulletin.go b/server/vulnerabilities/msrc/parsed/security_bulletin.go index de90cc7f0f..8a9c4a5271 100644 --- a/server/vulnerabilities/msrc/parsed/security_bulletin.go +++ b/server/vulnerabilities/msrc/parsed/security_bulletin.go @@ -3,9 +3,10 @@ package parsed import ( "encoding/json" "errors" + "os" + "github.com/fleetdm/fleet/v4/server/ptr" "golang.org/x/exp/slices" - "os" ) type SecurityBulletin struct { @@ -45,6 +46,9 @@ func UnmarshalBulletin(fPath string) (*SecurityBulletin, error) { if err != nil { return nil, err } + for pID, name := range bulletin.Products { + bulletin.Products[pID] = NewProductFromFullName(string(name)) + } return &bulletin, nil } diff --git a/server/vulnerabilities/msrc/parser_test.go b/server/vulnerabilities/msrc/parser_test.go index d93dac23fd..598d2c705e 100644 --- a/server/vulnerabilities/msrc/parser_test.go +++ b/server/vulnerabilities/msrc/parser_test.go @@ -39,7 +39,7 @@ func TestParser(t *testing.T) { f.Close() require.NoError(t, err) - // All the products we expect to see, grouped by their product name + // All the products we expect to see after marshaling, grouped by their product name. expectedProducts := map[string]parsed.Products{ "Windows 10": { "11568": parsed.NewProductFromFullName("Windows 10 Version 1809 for 32-bit Systems"), @@ -112,6 +112,79 @@ func TestParser(t *testing.T) { }, } + // All the products we expect to see in the parsed XML file, grouped by product name. + expectedXMLProducts := map[string]parsed.Products{ + "Windows 10": { + "11568": parsed.Product("Windows 10 Version 1809 for 32-bit Systems"), + "11569": parsed.Product("Windows 10 Version 1809 for x64-based Systems"), + "11570": parsed.Product("Windows 10 Version 1809 for ARM64-based Systems"), + "11712": parsed.Product("Windows 10 Version 1909 for 32-bit Systems"), + "11713": parsed.Product("Windows 10 Version 1909 for x64-based Systems"), + "11714": parsed.Product("Windows 10 Version 1909 for ARM64-based Systems"), + "11896": parsed.Product("Windows 10 Version 21H1 for x64-based Systems"), + "11897": parsed.Product("Windows 10 Version 21H1 for ARM64-based Systems"), + "11898": parsed.Product("Windows 10 Version 21H1 for 32-bit Systems"), + "11800": parsed.Product("Windows 10 Version 20H2 for x64-based Systems"), + "11801": parsed.Product("Windows 10 Version 20H2 for 32-bit Systems"), + "11802": parsed.Product("Windows 10 Version 20H2 for ARM64-based Systems"), + "11929": parsed.Product("Windows 10 Version 21H2 for 32-bit Systems"), + "11930": parsed.Product("Windows 10 Version 21H2 for ARM64-based Systems"), + "11931": parsed.Product("Windows 10 Version 21H2 for x64-based Systems"), + "10729": parsed.Product("Windows 10 for 32-bit Systems"), + "10735": parsed.Product("Windows 10 for x64-based Systems"), + "10852": parsed.Product("Windows 10 Version 1607 for 32-bit Systems"), + "10853": parsed.Product("Windows 10 Version 1607 for x64-based Systems"), + }, + "Windows Server 2019": { + "11571": parsed.Product("Windows Server 2019"), + "11572": parsed.Product("Windows Server 2019 (Server Core installation)"), + }, + "Windows Server 2022": { + "11923": parsed.Product("Windows Server 2022"), + "11924": parsed.Product("Windows Server 2022 (Server Core installation)"), + }, + "Windows Server": { + "11803": parsed.Product("Windows Server, version 20H2 (Server Core Installation)"), + }, + "Windows 11": { + "11926": parsed.Product("Windows 11 for x64-based Systems"), + "11927": parsed.Product("Windows 11 for ARM64-based Systems"), + }, + "Windows Server 2016": { + "10816": parsed.Product("Windows Server 2016"), + "10855": parsed.Product("Windows Server 2016 (Server Core installation)"), + }, + "Windows 8.1": { + "10481": parsed.Product("Windows 8.1 for 32-bit systems"), + "10482": parsed.Product("Windows 8.1 for x64-based systems"), + }, + "Windows RT 8.1": { + "10484": parsed.Product("Windows RT 8.1"), + }, + "Windows Server 2012": { + "10378": parsed.Product("Windows Server 2012"), + "10379": parsed.Product("Windows Server 2012 (Server Core installation)"), + }, + "Windows Server 2012 R2": { + "10483": parsed.Product("Windows Server 2012 R2"), + "10543": parsed.Product("Windows Server 2012 R2 (Server Core installation)"), + }, + "Windows 7": { + "10047": parsed.Product("Windows 7 for 32-bit Systems Service Pack 1"), + "10048": parsed.Product("Windows 7 for x64-based Systems Service Pack 1"), + }, + "Windows Server 2008": { + "9312": parsed.Product("Windows Server 2008 for 32-bit Systems Service Pack 2"), + "10287": parsed.Product("Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)"), + "9318": parsed.Product("Windows Server 2008 for x64-based Systems Service Pack 2"), + "9344": parsed.Product("Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)"), + }, + "Windows Server 2008 R2": { + "10051": parsed.Product("Windows Server 2008 R2 for x64-based Systems Service Pack 1"), + "10049": parsed.Product("Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)"), + }, + } + expectedCVEs := map[string][]string{ "Windows 10": { "CVE-2022-30190", @@ -1213,7 +1286,7 @@ func TestParser(t *testing.T) { t.Run("parseXML", func(t *testing.T) { t.Run("only windows products are included", func(t *testing.T) { var expected []msrcxml.Product - for _, grp := range expectedProducts { + for _, grp := range expectedXMLProducts { for pID, pFn := range grp { expected = append( expected, From e78bf6e8b123c1183d113e8fc187a3baa2a3bd04 Mon Sep 17 00:00:00 2001 From: Gabriel Hernandez Date: Tue, 17 Dec 2024 10:31:00 -0600 Subject: [PATCH 12/12] Add helpful tooltip to install software setup experience (#24799) relates to #24795 Add a helpful tooltip to the install software section for the setup experience page image - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [x] Manual QA for all new/changed functionality --- .../24795-add-helpful-tooltip-setup-experience | 1 + .../AddInstallSoftware.tests.tsx | 5 ++++- .../AddInstallSoftware/AddInstallSoftware.tsx | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 changes/24795-add-helpful-tooltip-setup-experience diff --git a/changes/24795-add-helpful-tooltip-setup-experience b/changes/24795-add-helpful-tooltip-setup-experience new file mode 100644 index 0000000000..4c108c2231 --- /dev/null +++ b/changes/24795-add-helpful-tooltip-setup-experience @@ -0,0 +1 @@ +- add helpful tooltip for the install software setup experience page diff --git a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tests.tsx b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tests.tsx index 92081fdc54..6ca5d86d80 100644 --- a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tests.tsx +++ b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tests.tsx @@ -60,7 +60,10 @@ describe("AddInstallSoftware", () => { ); expect( - screen.getByText(/2 software will be installed during setup/) + screen.getByText( + (_, element) => + element?.textContent === "2 software will be installed during setup." + ) ).toBeVisible(); expect( screen.getByRole("button", { name: "Show selected software" }) diff --git a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tsx b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tsx index 98e772f6ec..1ca1ac38ed 100644 --- a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tsx +++ b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/AddInstallSoftware/AddInstallSoftware.tsx @@ -6,6 +6,7 @@ import Button from "components/buttons/Button"; import CustomLink from "components/CustomLink"; import { ISoftwareTitle } from "interfaces/software"; import LinkWithContext from "components/LinkWithContext"; +import TooltipWrapper from "components/TooltipWrapper"; const baseClass = "add-install-software"; @@ -45,9 +46,17 @@ const AddInstallSoftware = ({ software.app_store_app?.install_during_setup ).length; - return installDuringSetupCount === 0 - ? "No software added." - : `${installDuringSetupCount} software will be installed during setup.`; + return installDuringSetupCount === 0 ? ( + "No software added." + ) : ( + <> + {installDuringSetupCount} software will be{" "} + + installed during setup + + . + + ); }; const getButtonText = () => {