Skip to content

Client enforce manifest fields used for paths - #6531

Open
JohnMcPMS wants to merge 4 commits into
microsoft:masterfrom
JohnMcPMS:client-enforce-manifest
Open

JohnMcPMS wants to merge 4 commits into
microsoft:masterfrom
JohnMcPMS:client-enforce-manifest

Conversation

@JohnMcPMS

@JohnMcPMS JohnMcPMS commented Sep 18, 2026

Copy link
Copy Markdown
Member

📖 Description

Enforce that fields used for paths cannot have invalid characters or sequences that would be used to traverse the filesystem.

🔍 Validation

Added tests for enforcement.

Microsoft Reviewers: Open in CodeFlow

@JohnMcPMS
JohnMcPMS requested a review from a team as a code owner September 18, 2026 18:50
Comment thread src/AppInstallerSharedLib/Filesystem.cpp Outdated
Comment thread src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp

std::filesystem::path tempInstallerPath = Runtime::GetPathTo(Runtime::PathName::Temp);
tempInstallerPath /= Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);
tempInstallerPath /= Utility::ConvertToUTF16(pathPart);

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.

It might be a non-issue, but this introduces a change to the string between time of check and time of use. If the UTF8 representation passes the check, is it guaranteed that the UTF16 represenation will too?

@ranm-msft ranm-msft 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.

Looked at this from the "what can still reach the filesystem" angle rather than the diff shape. Enforcing the schema rules on Id/Version at runtime is the right call - REST sources never went through the schema, so that was a real hole - and the point-of-use PathEscapesBaseDirectory checks land where the values actually get concatenated (ContextOrchestrator, the temp/download dirs, the log name, Fonts).

One gap in ValidatePathFieldValue: the character set covers the Win32 invalid characters and relative specifiers, but not the other two things that make a name unusable as a path component.

  • Reserved DOS device names are matched on the base name even when followed by an extension - NUL.txt and NUL.tar.gz are documented as equivalent to NUL - so a PackageIdentifier like NUL.foo still produces the component NUL.foo.1.0. The dotted-segment shape of an identifier doesn't save us here.
  • PackageVersion terminates the constructed component, so a trailing dot or space ends up at the end of the directory/file name, where Win32 may normalize, alias or reject it depending on the API and the namespace form.

Separately, the control-character check starts at 0x01, so an embedded NUL passes - a REST source can send \u0000 and everything downstream is null-terminated.

Is the intent to cover those in the validator too, or to let them fail at the point of use?

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.

3 participants