Skip to content

Windows SCEP profiles now fail with non-printable chars - #49887

Merged
getvictor merged 4 commits into
mainfrom
victor/47492-win-printable-chars
Jul 27, 2026
Merged

Windows SCEP profiles now fail with non-printable chars#49887
getvictor merged 4 commits into
mainfrom
victor/47492-win-printable-chars

Conversation

@getvictor

@getvictor getvictor commented Jul 24, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #47492

Windows cert profile fails if challenge uses non-printable characters.
image

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.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes

    • Windows SCEP profiles now fail with a clear error when the certificate authority challenge includes characters not supported by Windows ASN.1 PrintableString.
    • Prevents misleading “Verified” status when no certificate is installed.
    • Preserves valid challenge values, including leading/trailing spaces.
    • Improves Windows error tooltips by showing raw certificate-install error details.
  • Tests

    • Added coverage for invalid/valid Windows SCEP challenge scenarios and the updated error tooltip behavior.

Copilot AI review requested due to automatic review settings July 24, 2026 13:04
@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@getvictor

Copy link
Copy Markdown
Member Author

/agentic_review

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Adds Windows-specific validation for Custom SCEP Proxy challenge values so that profiles fail fast (with a clear host-facing detail) when the configured challenge contains characters that Windows can’t encode as an ASN.1 PrintableString (e.g., _), addressing the on-device enrollment failure described in #47492.

Changes:

  • Introduces a Windows SCEP challenge PrintableString allowlist regexp and returns a MicrosoftProfileProcessingError when invalid characters are detected during Windows profile preprocessing.
  • Adds unit tests that lock down the exact allowed/rejected character set and exercises the new failure/success paths in Windows profile preprocessing.
  • Includes a user-visible changes entry (content excluded by policy).

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
server/mdm/microsoft/profile_variables.go Adds PrintableString regexp and fails Windows profile preprocessing with a clear detail when the Custom SCEP challenge contains unsupported characters.
server/mdm/microsoft/profile_variables_test.go Adds coverage for the regexp’s exact character class and new preprocessing behaviors (invalid challenge errors, space preservation).
changes/47492-windows-scep-challenge-failed-profile User-visible change entry (content excluded; not reviewed).
Files excluded by content exclusion policy (1)
  • changes/47492-windows-scep-challenge-failed-profile

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/mdm/microsoft/profile_variables.go Outdated
Comment thread server/mdm/microsoft/profile_variables.go Outdated
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Windows SCEP preprocessing validates custom CA challenges against the ASN.1 PrintableString character set and returns a detailed processing error for invalid characters. Tests cover rejection of unsupported characters and preservation of surrounding spaces. Windows certificate installation errors are displayed verbatim in host profile status tooltips.

Possibly related issues

Possibly related PRs

  • fleetdm/fleet#49758: Directly changes the same SCEP challenge character-validation logic in other certificate authority flows.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The backend validation is present, but the PR summary does not show the required UI field validation or unchanged/masked-challenge bypass behavior. Add UI validation for the challenge field and gate backend checks so unchanged or masked challenges bypass the new PrintableString validation.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately describes the main change: Windows SCEP profiles now fail on unsupported challenge characters.
Description check ✅ Passed The description includes the related issue, checklist items, and testing notes expected by the template.
Out of Scope Changes check ✅ Passed The frontend tooltip adjustment is directly related to the new Windows SCEP error messaging and does not introduce unrelated functionality.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch victor/47492-win-printable-chars

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/mdm/microsoft/profile_variables.go`:
- Around line 151-156: Add write-path validation for custom SCEP CA creation and
updates, reusing windowsSCEPChallengeRegexp to reject unmasked challenge values
containing unsupported characters before persistence. Ensure unchanged masked
challenge updates remain valid by validating only newly supplied, unmasked
values while preserving the existing IsCustomSCEPConfigured/profile
preprocessing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b0e1a339-a94c-4763-bcfe-70131908fbe6

📥 Commits

Reviewing files that changed from the base of the PR and between aa572dc and 218f87b.

📒 Files selected for processing (3)
  • changes/47492-windows-scep-challenge-failed-profile
  • server/mdm/microsoft/profile_variables.go
  • server/mdm/microsoft/profile_variables_test.go

Comment thread server/mdm/microsoft/profile_variables.go Outdated
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jul 24, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Invalid new() usage 🐞 Bug ≡ Correctness
Description
server/mdm/microsoft/profile_variables_test.go uses new("...") to create *string values, but
Go's built-in new requires a type (e.g., new(string)), so these test cases will not compile.
This will break CI/test runs for the package and block validation of the PR.
Code

server/mdm/microsoft/profile_variables_test.go[R306-330]

+							Name:      new("CERTIFICATE"),
+							Type:      string(fleet.CATypeCustomSCEPProxy),
+							URL:       new("https://scep.proxy.url/scep"),
+							Challenge: new("super_secret"),
+						},
+					}, nil
+				}
+			},
+		},
+		{
+			name:             "custom scep proxy challenge with leading and trailing spaces preserved",
+			hostUUID:         "test-host-1234-uuid",
+			profileContents:  `<Replace><Data>$FLEET_VAR_CUSTOM_SCEP_CHALLENGE_CERTIFICATE</Data></Replace>`,
+			expectedContents: `<Replace><Data> super secret </Data></Replace>`,
+			setup: func() {
+				ds.GetAllCertificateAuthoritiesFunc = func(ctx context.Context, includeSecrets bool) ([]*fleet.CertificateAuthority, error) {
+					return []*fleet.CertificateAuthority{
+						{
+							ID:        1,
+							Name:      new("CERTIFICATE"),
+							Type:      string(fleet.CATypeCustomSCEPProxy),
+							URL:       new("https://scep.proxy.url/scep"),
+							Challenge: new(" super secret "),
+						},
+					}, nil
Evidence
The newly-added test cases set Name, URL, and Challenge using new("..."), which is not valid
Go for obtaining a *string. Earlier test cases in the same file correctly use ptr.String("...")
for the same struct fields, showing the intended pattern.

server/mdm/microsoft/profile_variables_test.go[232-246]
server/mdm/microsoft/profile_variables_test.go[296-333]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The tests construct `*fleet.CertificateAuthority` using `new("...")` for `Name`, `URL`, and `Challenge`. In Go, `new` is a built-in that takes a *type*, not a value literal, so `new("CERTIFICATE")` is invalid and causes compilation failures.
## Issue Context
The same test file already uses `ptr.String("...")` for these pointer fields in other test cases, which is the correct and consistent approach.
## Fix Focus Areas
- server/mdm/microsoft/profile_variables_test.go[296-333]
## Expected fix
Replace `new("...")` with `ptr.String("...")` (or equivalent local variables whose addresses are taken) for `Name`, `URL`, and `Challenge` in the newly-added test cases.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread server/mdm/microsoft/profile_variables_test.go
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.92%. Comparing base (aa572dc) to head (7a634fa).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main   #49887    +/-   ##
========================================
  Coverage   67.92%   67.92%            
========================================
  Files        3905     3906     +1     
  Lines      249676   249707    +31     
  Branches    13350    13191   -159     
========================================
+ Hits       169580   169606    +26     
  Misses      64828    64828            
- Partials    15268    15273     +5     
Flag Coverage Δ
backend 69.31% <100.00%> (-0.01%) ⬇️
frontend 60.42% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI review requested due to automatic review settings July 24, 2026 14:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

Files excluded by content exclusion policy (1)
  • changes/47492-windows-scep-challenge-failed-profile
Comments suppressed due to low confidence (2)

server/mdm/microsoft/profile_variables_test.go:304

  • Same issue here: new("...") is invalid Go (built-in new requires a type). Use ptr.String(...) to build *string values so the test compiles.
							Name:      new("CERTIFICATE"),
							Type:      string(fleet.CATypeCustomSCEPProxy),
							URL:       new("https://scep.proxy.url/scep"),
							Challenge: new(" super secret "),

server/mdm/microsoft/profile_variables.go:153

  • Issue #47492’s expected behavior calls for rejecting an invalid Custom SCEP Proxy challenge at save-time (UI + backend) so admins get immediate feedback. This PR adds validation only at Windows profile preprocessing time, so an admin can still save an unsupported challenge and only discover it later when a Windows profile is processed.
			if ca := deps.CustomSCEPCAs[caName]; ca != nil && !windowsSCEPChallengeRegexp.MatchString(ca.Challenge) {
				return profileContents, &MicrosoftProfileProcessingError{
					message: fmt.Sprintf(scepChallengeInvalidCharsDetail, caName),
				}
			}

Comment thread server/mdm/microsoft/profile_variables_test.go
Copilot AI review requested due to automatic review settings July 24, 2026 14:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated no new comments.

Files excluded by content exclusion policy (1)
  • changes/47492-windows-scep-challenge-failed-profile

Copilot AI review requested due to automatic review settings July 24, 2026 14:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Files excluded by content exclusion policy (1)
  • changes/47492-windows-scep-challenge-failed-profile
Comments suppressed due to low confidence (1)

server/mdm/microsoft/profile_variables.go:153

  • This change makes Windows profiles fail at deployment time if a Custom SCEP proxy challenge contains non-PrintableString characters, but it doesn’t implement the issue’s requested admin-side validation (reject invalid challenges on certificate authority create/update). As a result, admins can still save an invalid challenge and only discover it later when profiles are deployed.
			if ca := deps.CustomSCEPCAs[caName]; ca != nil && !windowsSCEPChallengeRegexp.MatchString(ca.Challenge) {
				return profileContents, &MicrosoftProfileProcessingError{
					message: fmt.Sprintf(scepChallengeInvalidCharsDetail, caName),
				}
			}

@getvictor
getvictor marked this pull request as ready for review July 24, 2026 14:45
@getvictor
getvictor requested a review from a team as a code owner July 24, 2026 14:45
@getvictor
getvictor requested a review from a team as a code owner July 24, 2026 14:45
@getvictor
getvictor requested a review from nulmete July 24, 2026 14:45
@getvictor

Copy link
Copy Markdown
Member Author

@nulmete I'm assigning this one for you to review since you're familiar with this issue.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/mdm/microsoft/profile_variables.go (1)

149-153: ⚠️ Potential issue | 🟠 Major

Validate custom SCEP challenges before persistence.

This only rejects invalid values during profile preprocessing, so super_secret-style challenges can still be saved through CA create/update and fail later on Windows enrollment. Add the same validation at the write boundary, validating only newly supplied or changed unmasked values while allowing unchanged masked placeholders for backward compatibility. This remains the unresolved write-path requirement from the PR objective and prior review.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/mdm/microsoft/profile_variables.go` around lines 149 - 153, Extend the
CA create/update write path to validate custom SCEP challenge values using
windowsSCEPChallengeRegexp before persistence, reusing the existing
invalid-character error detail where appropriate. Validate only newly supplied
or changed unmasked challenges; accept unchanged masked placeholders so existing
records remain compatible, while retaining the preprocessing validation in the
profile flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@server/mdm/microsoft/profile_variables.go`:
- Around line 149-153: Extend the CA create/update write path to validate custom
SCEP challenge values using windowsSCEPChallengeRegexp before persistence,
reusing the existing invalid-character error detail where appropriate. Validate
only newly supplied or changed unmasked challenges; accept unchanged masked
placeholders so existing records remain compatible, while retaining the
preprocessing validation in the profile flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 80880243-78e5-4dc0-ac82-55c7094560f2

📥 Commits

Reviewing files that changed from the base of the PR and between 218f87b and 7a634fa.

📒 Files selected for processing (4)
  • frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingStatusCell/errorTooltipHelpers.tests.tsx
  • frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingStatusCell/errorTooltipHelpers.tsx
  • server/mdm/microsoft/profile_variables.go
  • server/mdm/microsoft/profile_variables_test.go

@nulmete

nulmete commented Jul 27, 2026

Copy link
Copy Markdown
Member

@nulmete I'm assigning this one for you to review since you're familiar with this issue.

@getvictor Sounds good. Will look today.

@getvictor
getvictor merged commit 19efda2 into main Jul 27, 2026
48 checks passed
@getvictor
getvictor deleted the victor/47492-win-printable-chars branch July 27, 2026 17:49
@coderabbitai coderabbitai Bot mentioned this pull request Aug 11, 2026
3 tasks
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.

Custom SCEP proxy challenge with non-printable characters breaks Windows certificate enrollment

3 participants