Skip to content

fix(adhoc-sweep-fixes): CU-86akj32d7 74 review findings across 40 files - #167

Draft
flamingo[bot] wants to merge 40 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-7a9776d4-1446a072
Draft

flamingo[bot] wants to merge 40 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-7a9776d4-1446a072

Conversation

@flamingo

@flamingo flamingo Bot commented Sep 14, 2026

Copy link
Copy Markdown

Closes 74 review findings across 40 files.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Fix confidence Finding Location
1 🟡 75 medium newPrivateKey ignores CommonName collision and possible unencrypted key file left behind on partial failure server/mdm/scep/depot/file/depot.go:102
2 🟡 70 medium Serial() returns underlying error unwrapped when SetString fails, and other bare error returns lack context server/mdm/scep/depot/file/depot.go:41
3 🔴 55 low — review closely Serial() reads with ReadString('\r') but serial file is written with '\n' terminator, causing potential misread server/mdm/scep/depot/file/depot.go:127
4 🟡 60 medium fmt.Println used for revocation notice instead of structured logging server/mdm/scep/depot/file/depot.go:238
5 🟡 85 medium Android enterprise auth compares fleetServerSecret using non-constant-time string equality website/api/controllers/android-proxy/get-android-enterprises.js:49
6 🔴 55 low — review closely get-android-enterprises.js loses 429 rate-limit signal to caller unlike sibling get-enterprise-applications.js website/api/controllers/android-proxy/get-android-enterprises.js:93
7 🔴 20 low — review closely Android Management API auth boilerplate duplicated across both android-proxy controllers website/api/controllers/android-proxy/get-android-enterprises.js:56
8 🟢 97 high Typo PROCESSED_PACKAGED writes to a different variable than the one that is read/reported tools/gitops-migrate/migrate.sh:193
9 🟢 92 high World-writable temp files created with chmod 666 in gitops migration tool tools/gitops-migrate/migrate.sh:76
10 🟢 92 high pubSubLogWriter.Write drops messages silently for oversized entries without surfacing a partial-failure signal server/logging/pubsub.go:96
11 🟢 90 high Potential slice out-of-range when truncating log message for oversized-drop log line server/logging/pubsub.go:80
12 🟢 98 high CheckinHandler writes response body after http.Error already sent headers on error path server/mdm/nanomdm/http/mdm/mdm.go:51
13 🟢 98 high CommandAndReportResultsHandler writes response body after http.Error already sent headers server/mdm/nanomdm/http/mdm/mdm.go:80
14 🟢 92 high jira.go doWithRetry dereferences resp without checking for nil, risking a panic on network errors server/service/externalsvc/jira.go:113
15 🟡 65 medium jira.go: strconv.ParseInt error from Retry-After header parsing is silently ignored server/service/externalsvc/jira.go:126
16 🟢 92 high helpers.tests.ts: assertions outside it(...) blocks execute at describe-time, not as part of a test frontend/pages/admin/IntegrationsPage/cards/IdentityProviders/components/EndUserAuthSection/helpers.tests.ts:82
17 🟢 92 high helpers.tests.ts: newFormDataIdP assertions run outside any it() block frontend/pages/admin/IntegrationsPage/cards/IdentityProviders/components/EndUserAuthSection/helpers.tests.ts:216
18 🟡 88 medium Unsynchronized shared variable stopError read/write in concurrent goroutines tools/github-manage/pkg/ghapi/issues.go:372
19 🟢 95 high Errors wrapped with %v instead of %w lose the causal chain tools/github-manage/pkg/ghapi/issues.go:137
20 🟢 90 high expressvpn-install.sh privilege check compares $EUID against console_user, which is always true when running as root regardless of console session ee/maintained-apps/inputs/homebrew/scripts/expressvpn-install.sh:18
21 🟡 85 medium expressvpn-install.sh does not clean up TMPDIR created via mktemp ee/maintained-apps/inputs/homebrew/scripts/expressvpn-install.sh:4
22 🟢 95 high installedPaths.map produces sibling elements without a key prop frontend/pages/hosts/details/components/InventoryVersions/InventoryVersions.tsx:109
23 🟡 70 medium InventoryVersion component uses non-unique React key that can collide across versions frontend/pages/hosts/details/components/InventoryVersions/InventoryVersions.tsx:173
24 🟢 90 high CustomValueContainer destructures non-existent 'props' key from ValueContainerProps, breaking prop passthrough frontend/pages/hosts/ManageHostsPage/components/CustomValueContainer/CustomValueContainer.tsx:1
25 🟡 85 medium CustomValueContainer component is misnamed as CustomDropdownIndicator, duplicating the name of a sibling component frontend/pages/hosts/ManageHostsPage/components/CustomValueContainer/CustomValueContainer.tsx:8
26 🟢 92 high nextRunAfter divides by zero risk when jitterPct causes maxJitter of 0 server/service/async/collect.go:178
27 🟡 70 medium errHandler callback in collector.exec ignores whether DEL of the lock key succeeds server/service/async/collect.go:109
28 🟡 75 medium server/service/embedded_scripts/delete-duplicate-scep-certificates.sh: date parsing failure silently treated as epoch 0, causing wrong certificate to be deleted server/service/embedded_scripts/delete-duplicate-scep-certificates.sh:75
29 🟡 60 medium delete-duplicate-scep-certificates.sh: unauthenticated openssl parse of attacker-controllable PEM without validating cert count/structure boundaries server/service/embedded_scripts/delete-duplicate-scep-certificates.sh:60
30 🟡 85 medium Update() can call teamModelToTF with a nil upTeam pointer causing a nil dereference tools/terraform/provider/teams_resource.go:223
31 🟢 95 high Delete-on-error cleanup errors are silently swallowed with '_ =' in Create tools/terraform/provider/teams_resource.go:129
32 🔴 30 low — review closely Duplicate scroll-hiding platform-filter handler copy-pasted verbatim across three Sails page controllers website/assets/js/pages/docs/vital-details.page.js:126
33 🟢 95 high copy-button click handler drops guard against empty clipboard text on vital-details page (inconsistent with script-details page) website/assets/js/pages/docs/vital-details.page.js:86
34 🟡 60 medium XML/JSON detection heuristic for secret escaping is ambiguous and can misclassify documents server/datastore/mysql/secret_variables.go:361
35 🟡 85 medium xml.EscapeText error silently discarded, returning generic 'not ok' with no diagnostic server/datastore/mysql/secret_variables.go:374
36 🟡 80 medium wtsEnumerateSessions never frees the memory returned by WTSEnumerateSessionsW orbit/pkg/execuser/execuser_windows.go:164
37 🔴 55 low — review closely userToken and impersonationToken handles are never closed on the success path in startProcessAsCurrentUser orbit/pkg/execuser/execuser_windows.go:209
38 🔴 55 low — review closely Environment-variable gated migration silently skips instead of failing loudly when partially configured, risking schema drift across replicas server/datastore/mysql/migrations/tables/20250902112642_MigratePrimoFailingPoliciesAutomations.go:19
39 🟡 80 medium Migration silently drops No-team webhook policy IDs when JSON number types don't match expected switch cases server/datastore/mysql/migrations/tables/20250902112642_MigratePrimoFailingPoliciesAutomations.go:71
40 🟢 90 high list() errors returned without call-site context in github.go server/vulnerabilities/io/github.go:124
41 🔴 55 low — review closely MacOfficeReleaseNotes returns nil error alongside empty result when no assets found server/vulnerabilities/io/github.go:97
42 🟡 85 medium removeOldOSVArtifacts error incorrectly wrapped with 'warning:' prefix but still returned as a hard error server/vulnerabilities/osv/sync.go:43
43 🔴 20 low — review closely removeOldOSVArtifacts and removeOldRHELOSVArtifacts are near-identical duplicated implementations server/vulnerabilities/osv/sync.go:55
44 🟢 95 high privateIPRegex incorrectly matches any string with a private-IP-like prefix, not an anchored full match cmd/osquery-perf/software-library/tools/import-data/main.go:49
45 🟡 70 medium import-data tool builds SQL error strings via string matching on driver error text, which is fragile across sqlite3 driver versions cmd/osquery-perf/software-library/tools/import-data/main.go:246
46 🟡 85 medium Info.tsx logo upload/delete failures silently swallow the underlying error frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx:319
47 🔴 55 low — review closely onInputChange in Info.tsx clears all form errors on every keystroke, discarding relevant validation state prematurely frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx:185
48 🟡 75 medium log.Fatalf inside Migrations.Less will crash the whole process on duplicate migration versions server/goose/migrate.go:28
49 🔴 45 low — review closely GetDBVersion falls back to createVersionTable on ANY query error, masking real DB errors as 'table missing' server/goose/migrate.go:165
50 🔴 20 low — review closely view-basic-webinar.js and view-basic-whitepaper.js are near-identical duplicated controllers website/api/controllers/articles/view-basic-webinar.js:1
51 🟢 95 high Unguarded access to thisPage.meta can throw if meta is undefined website/api/controllers/articles/view-basic-webinar.js:47
52 🔴 55 low — review closely install-fleetctl.sh downloads and extracts release archives without any checksum/signature verification website/assets/resources/install-fleetctl.sh:53
53 🟢 90 high install-fleetctl.sh trusts an unvalidated version string scraped from a public npm registry response for a URL and filesystem path website/assets/resources/install-fleetctl.sh:19
54 🔴 55 low — review closely appExists builds SQL query via unescaped string concatenation despite validateSqlInput guard cmd/maintained-apps/validate/windows.go:54
55 🟡 80 medium executeScript swallows the original context-timeout error and produces a misleading generic error cmd/maintained-apps/validate/windows.go:306
56 🔴 55 low — review closely Legacy team_id query param rewrite can double-fire causing duplicate/garbled redirect frontend/hooks/useTeamIdParam.ts:79
57 🟡 60 medium preferredOrLowestIdFleet uses raw unicode escape for emoji that may not match the actual laptop emoji used elsewhere in the UI/data frontend/hooks/useTeamIdParam.ts:191
58 🟡 82 medium InstallSoftwareForm swallows individual save failures but always calls refetchSoftwareTitles(), potentially masking partial-save state to the user frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/InstallSoftwareForm/InstallSoftwareForm.tsx:162
59 🟡 78 medium onChangeSoftwareSelect useCallback has empty dependency array but is stable only because setSelectedSoftwareIds is used, which is fine — but isSoftwareSelectionDirty comparison uses .slice().sort() destructively on state reference each render causing unnecessary renders frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/InstallSoftwareForm/InstallSoftwareForm.tsx:104
60 🟡 75 medium SimpleMDM API token passed via command-line flag, logged and reused across requests tools/mdm/migration/simplemdm/main.go:20
61 🔴 30 low — review closely webhook handler in simplemdm/main.go ignores incoming device serial and always unenrolls the CLI-provided device tools/mdm/migration/simplemdm/main.go:123
62 🟡 75 medium BootstrapPackage's onDelete swallows the caught error without any logging or detail frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/BootstrapPackage.tsx:141
63 🔴 55 low — review closely onDelete has a partial-failure window: bootstrap package can be deleted while settings update fails, leaving inconsistent state frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/BootstrapPackage.tsx:141
64 🔴 55 low — review closely updateSoftwareInstallerRequest silently drops SelfService validation error path present in upload variant server/service/software_installers.go:44
65 🟡 80 medium TODO comment flags known auth-bypass risk in DecodeRequest parsing full multipart body before authorization server/service/software_installers.go:67
66 🟢 95 high Migration error message mismatches actual operation for index creation server/datastore/mysql/migrations/tables/20220831100151_AddWindowsUpdatesTable.go:24
67 🟢 100 high Software.tsx passes wrong sort direction constant to 'All' tab TableContainer frontend/pages/DashboardPage/cards/Software/Software.tsx:95
68 🟢 95 high get-access-token-and-api-urls.js returns an Error object instead of throwing it website/api/helpers/microsoft-proxy/get-access-token-and-api-urls.js:29
69 🟡 85 medium Non-deterministic timing-based flakiness risk in jitter distribution test server/service/jitter_test.go:37
70 🟢 90 high getopts flag f defined twice, second definition silently shadows the source-file flag tools/team-builder/build_teams.sh:12
71 🟢 95 high Duplicate '|| ""' in status fallback produces no functional difference but signals a copy-paste bug frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetailsModal/SoftwareInstallDetailsModal.tsx:366
72 🟢 92 high getUninstallErrorMessage produces malformed message with stray period before reason for the 'no uninstall script' branch frontend/pages/hosts/details/cards/HostSoftwareLibrary/helpers.tsx:94
73 🟢 92 high mdmproxy entrypoint.sh uses eval on env-var-derived arguments, risking shell injection via unquoted expansion tools/mdm/migration/mdmproxy/entrypoint.sh:12
74 🟢 95 high FleetClient#req swallows exceptions into a string, losing exception type/backtrace ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb:177

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: 1446a072-096e-4294-8082-c7cadffe76de

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

ClickUp task: CU-86akj32d7 FleetMDM bulk review findings sweep (12 PRs)

flamingo Bot added 30 commits September 14, 2026 06:47

@flamingo flamingo Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 What this fix changed, finding by finding

74 finding(s) fixed in this draft — 74 explained inline on the diff; 17 low-confidence hunk(s) need close review before merging.

@@ -100,7 +101,11 @@ func (d *fileDepot) Put(cn string, crt *x509.Certificate) error {
return err
}
if err := d.writeDB(cn, serial, filename, crt); err != nil {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 newPrivateKey ignores CommonName collision and possible unencrypted key file left behind on partial failure

In Put() (server/mdm/scep/depot/file/depot.go), the writeDB failure path now calls os.Remove(filepath) before returning the error, removing the leftover cert PEM file so the on-disk files stay in sync with index.txt; the stale TODO comment was replaced with an explanatory comment describing the mechanism. This does not address the CommonName collision detection itself (that is handled separately by HasCN/writeDB's own DN-collision error), only the file-removal-on-failure half of the finding.

🤖 Prompt for AI agents
In server/mdm/scep/depot/file/depot.go around line 102, review and complete this code-review fix: newPrivateKey ignores CommonName collision and possible unencrypted key file left behind on partial failure.
What the draft fix changed: In Put() (server/mdm/scep/depot/file/depot.go), the writeDB failure path now calls os.Remove(filepath) before returning the error, removing the leftover cert PEM file so the on-disk files stay in sync with index.txt; the stale TODO comment was replaced with an explanatory comment describing the mechanism. This does not address the CommonName collision detection itself (that is handled separately by HasCN/writeDB's own DN-collision error), only the file-removal-on-failure half of the finding.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 75 medium — react 👍/👎 to teach the reviewer

@@ -41,19 +42,19 @@ type fileDepot struct {
func (d *fileDepot) CA(pass []byte) ([]*x509.Certificate, *rsa.PrivateKey, error) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Serial() returns underlying error unwrapped when SetString fails, and other bare error returns lack context

Wrapped bare error returns with fmt.Errorf("...: %w", err) context in NewFileDepot (opening index.txt), CA() (reading ca.pem/ca.key, loading ca certificate/key), Serial() (writing serial, opening/reading serial file, incrementing serial), and getFile() (checking/stat/reading the named file). Left other propagated errors (e.g. inside HasCN, writeDB, writeSerial) unwrapped since the finding specifically named Serial(), CA(), and getFile(); a fully complete fix per FLEETMDM-002-2 would wrap every bare return ..., err in the file, which is a broader change than these three functions.

🤖 Prompt for AI agents
In server/mdm/scep/depot/file/depot.go around line 41, review and complete this code-review fix: Serial() returns underlying error unwrapped when SetString fails, and other bare error returns lack context.
What the draft fix changed: Wrapped bare error returns with fmt.Errorf("...: %w", err) context in NewFileDepot (opening index.txt), CA() (reading ca.pem/ca.key, loading ca certificate/key), Serial() (writing serial, opening/reading serial file, incrementing serial), and getFile() (checking/stat/reading the named file). Left other propagated errors (e.g. inside HasCN, writeDB, writeSerial) unwrapped since the finding specifically named Serial(), CA(), and getFile(); a fully complete fix per FLEETMDM-002-2 would wrap every bare `return ..., err` in the file, which is a broader change than these three functions.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 70 medium — react 👍/👎 to teach the reviewer

return nil, fmt.Errorf("opening serial file: %w", err)
}
defer file.Close()
r := bufio.NewReader(file)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Serial() reads with ReadString('\r') but serial file is written with '\n' terminator, causing potential misread

Changed Serial()'s r.ReadString('\r') to r.ReadString('\n') in the Serial() function so the reader delimiter matches writeSerial()'s \n terminator; the existing TrimSuffix("\r") then TrimSuffix("\n") calls are left in place to remain tolerant of any stray \r (e.g. CRLF), so behavior for normal single-line files is unchanged but now correctly stops at the actual line terminator instead of relying on EOF. Not extensively tested against externally-edited multi-line serial files.

🤖 Prompt for AI agents
In server/mdm/scep/depot/file/depot.go around line 127, review and complete this code-review fix: Serial() reads with ReadString('\r') but serial file is written with '\n' terminator, causing potential misread.
What the draft fix changed: Changed Serial()'s r.ReadString('\r') to r.ReadString('\n') in the Serial() function so the reader delimiter matches writeSerial()'s `\n` terminator; the existing TrimSuffix("\r") then TrimSuffix("\n") calls are left in place to remain tolerant of any stray `\r` (e.g. CRLF), so behavior for normal single-line files is unchanged but now correctly stops at the actual line terminator instead of relying on EOF. Not extensively tested against externally-edited multi-line serial files.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 55 low — review closely — react 👍/👎 to teach the reviewer

@@ -236,7 +241,7 @@ func (d *fileDepot) HasCN(_ string, allowTime int, cert *x509.Certificate, revok
return false, errors.New("DN " + dn + " already exists")
}
if revokeOldCertificate {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 fmt.Println used for revocation notice instead of structured logging

Replaced fmt.Println in HasCN with slog.Info("revoking certificate from DB, recreation of CRL needed", "serial", key), using the log/slog package directly instead of routing through kitlogadapter.go (which was not shown to me and whose exact adapter API/signature I cannot verify); this satisfies "structured logging" but a reviewer should confirm whether call sites expect this file to route through the specific kitlogadapter bridge instead of stdlib slog directly.

🤖 Prompt for AI agents
In server/mdm/scep/depot/file/depot.go around line 238, review and complete this code-review fix: fmt.Println used for revocation notice instead of structured logging.
What the draft fix changed: Replaced fmt.Println in HasCN with slog.Info("revoking certificate from DB, recreation of CRL needed", "serial", key), using the log/slog package directly instead of routing through kitlogadapter.go (which was not shown to me and whose exact adapter API/signature I cannot verify); this satisfies "structured logging" but a reviewer should confirm whether call sites expect this file to route through the specific kitlogadapter bridge instead of stdlib slog directly.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 60 medium — react 👍/👎 to teach the reviewer

throw 'notFound';
}

if (thisAndroidEnterprise.fleetServerSecret !== fleetServerSecret) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Android enterprise auth compares fleetServerSecret using non-constant-time string equality

In fn, replaced the plain !== comparison of fleetServerSecret with a constant-time comparison using crypto.timingSafeEqual, guarding against length mismatches (which throw in timingSafeEqual) by first comparing buffer lengths before calling it. This removes the timing-attack-prone equality check.

🤖 Prompt for AI agents
In website/api/controllers/android-proxy/get-android-enterprises.js around line 49, review and complete this code-review fix: Android enterprise auth compares fleetServerSecret using non-constant-time string equality.
What the draft fix changed: In `fn`, replaced the plain `!==` comparison of `fleetServerSecret` with a constant-time comparison using `crypto.timingSafeEqual`, guarding against length mismatches (which throw in `timingSafeEqual`) by first comparing buffer lengths before calling it. This removes the timing-attack-prone equality check.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 85 medium — react 👍/👎 to teach the reviewer

@@ -12,7 +12,7 @@ run(){
while getopts s:p:u:f:d:o:x flag

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getopts flag f defined twice, second definition silently shadows the source-file flag

In run(), the getopts case statement's first f) branch (path to team-names file) was renamed to s) to match the existing s: flag already declared in the getopts s:p:u:f:d:o:x flag spec string, eliminating the duplicate f) pattern. The second f) branch (additional fleetctl flags, flags+=($OPTARG)) is now reachable. The getopts spec string was left unchanged since s: was already present but previously unused/shadowed by the duplicate f) case; the comment text for the file-source flag was preserved as-is.

🤖 Prompt for AI agents
In tools/team-builder/build_teams.sh around line 12, review and complete this code-review fix: getopts flag `f` defined twice, second definition silently shadows the source-file flag.
What the draft fix changed: In `run()`, the getopts case statement's first `f)` branch (path to team-names file) was renamed to `s)` to match the existing `s:` flag already declared in the `getopts s:p:u:f:d:o:x flag` spec string, eliminating the duplicate `f)` pattern. The second `f)` branch (additional fleetctl flags, `flags+=($OPTARG)`) is now reachable. The getopts spec string was left unchanged since `s:` was already present but previously unused/shadowed by the duplicate `f)` case; the comment text for the file-source flag was preserved as-is.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

@@ -365,7 +365,7 @@ export const SoftwareInstallDetailsModal = ({
const overrideFailedMessageWithInstalledMessage =
canOverrideFailureWithInstalled &&

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Duplicate '|| ""' in status fallback produces no functional difference but signals a copy-paste bug

Removed the duplicate || "" fallback in the overrideFailedMessageWithInstalledMessage computation inside SoftwareInstallDetailsModal (around the .includes(swInstallResult?.status || "" || "") expression), changing it to .includes(swInstallResult?.status || "") as suggested, with no functional change.

🤖 Prompt for AI agents
In frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetailsModal/SoftwareInstallDetailsModal.tsx around line 366, review and complete this code-review fix: Duplicate '|| ""' in status fallback produces no functional difference but signals a copy-paste bug.
What the draft fix changed: Removed the duplicate `|| ""` fallback in the `overrideFailedMessageWithInstalledMessage` computation inside `SoftwareInstallDetailsModal` (around the `.includes(swInstallResult?.status || "" || "")` expression), changing it to `.includes(swInstallResult?.status || "")` as suggested, with no functional change.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

"Couldn't uninstall."
);
} else if (reason.startsWith("No uninstall script exists")) {
return `${UNINSTALL_SOFTWARE_ERROR_PREFIX}. An uninstall script does not exist for this package.`;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getUninstallErrorMessage produces malformed message with stray period before reason for the 'no uninstall script' branch

In getUninstallErrorMessage, the "No uninstall script exists" branch template literal changed from ${UNINSTALL_SOFTWARE_ERROR_PREFIX}. An uninstall script... to ${UNINSTALL_SOFTWARE_ERROR_PREFIX} An uninstall script..., removing the stray period that doubled up with the prefix's own trailing period, matching the suggested fix exactly.

🤖 Prompt for AI agents
In frontend/pages/hosts/details/cards/HostSoftwareLibrary/helpers.tsx around line 94, review and complete this code-review fix: getUninstallErrorMessage produces malformed message with stray period before reason for the 'no uninstall script' branch.
What the draft fix changed: In getUninstallErrorMessage, the "No uninstall script exists" branch template literal changed from `${UNINSTALL_SOFTWARE_ERROR_PREFIX}. An uninstall script...` to `${UNINSTALL_SOFTWARE_ERROR_PREFIX} An uninstall script...`, removing the stray period that doubled up with the prefix's own trailing period, matching the suggested fix exactly.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 92 high — react 👍/👎 to teach the reviewer

-fleet-url "${MDMPROXY_FLEET_URL:?}" \
-server-address "${MDMPROXY_SERVER_ADDRESS:?}"

if [ -n "${MDMPROXY_AUTH_TOKEN}" ]; then

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 mdmproxy entrypoint.sh uses eval on env-var-derived arguments, risking shell injection via unquoted expansion

Replaced the eval-based argument assembly in tools/mdm/migration/mdmproxy/entrypoint.sh with a positional-parameter (set --) array built incrementally, then executed via exec /usr/bin/mdmproxy "$@" without eval. This removes the string-concatenation-then-eval anti-pattern entirely, so env vars like MDMPROXY_AUTH_TOKEN, MDMPROXY_MIGRATE_PERCENTAGE, and MDMPROXY_MIGRATE_UDIDS are passed as single quoted positional args and cannot be re-parsed by the shell, eliminating the injection vector regardless of embedded shell metacharacters.

🤖 Prompt for AI agents
In tools/mdm/migration/mdmproxy/entrypoint.sh around line 12, review and complete this code-review fix: mdmproxy entrypoint.sh uses eval on env-var-derived arguments, risking shell injection via unquoted expansion.
What the draft fix changed: Replaced the eval-based argument assembly in `tools/mdm/migration/mdmproxy/entrypoint.sh` with a positional-parameter (`set --`) array built incrementally, then executed via `exec /usr/bin/mdmproxy "$@"` without eval. This removes the string-concatenation-then-eval anti-pattern entirely, so env vars like MDMPROXY_AUTH_TOKEN, MDMPROXY_MIGRATE_PERCENTAGE, and MDMPROXY_MIGRATE_UDIDS are passed as single quoted positional args and cannot be re-parsed by the shell, eliminating the injection vector regardless of embedded shell metacharacters.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 92 high — react 👍/👎 to teach the reviewer

@@ -175,7 +175,7 @@ def req(method: :get, path: '', body: nil, headers: {}, cached: false, environme
end
end
rescue => e

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 FleetClient#req swallows exceptions into a string, losing exception type/backtrace

In FleetClient#req's rescue clause, changed out['error'] = e to out['error'] = e.message so the stored error is a String consistent with parse_response's error messages, avoiding downstream type errors from an unserialized Exception object.

🤖 Prompt for AI agents
In ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb around line 177, review and complete this code-review fix: FleetClient#req swallows exceptions into a string, losing exception type/backtrace.
What the draft fix changed: In FleetClient#req's rescue clause, changed `out['error'] = e` to `out['error'] = e.message` so the stored error is a String consistent with parse_response's error messages, avoiding downstream type errors from an unserialized Exception object.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

@flamingo flamingo Bot changed the title fix(adhoc-sweep-fixes): 74 review findings across 40 files fix(adhoc-sweep-fixes): CU-86akj32d7 74 review findings across 40 files Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants