Skip to content

Property function allowlist is not enforced for chained instance methods (e.g. Directory::GetParent(...).Delete(true)) #14815

Description

@ViktorHofer

Issue Description

Static property functions are restricted to the allowlist in Microsoft.Build.Internal.AvailableStaticMethods (src/Build/Resources/Constants.cs). However, when an allowlisted static returns an object, any public instance method can then be chained onto the result.

Expander.Function.IsInstanceMethodAvailable (src/Build/Evaluation/Expander.Function.cs:1154) only rejects GetType unless FeatureSwitches.RestrictPropertyFunctionReceivers is on:

if (string.Equals("GetType", methodName, StringComparison.OrdinalIgnoreCase)) { return false; }
if (FeatureSwitches.RestrictPropertyFunctionReceivers) { return PropertyFunctionReceiver.IsAllowed(receiverType, methodName); }
return true;

That switch is effectively never on for a normal MSBuild: FeatureSwitches.cs:97 reads it via AppContext.TryGetSwitch (false when unset), and Microsoft.Build.Framework.csproj:47 emits the RuntimeHostConfigurationOption with Trim="true", so it only applies to trimmed apps. Microsoft.Build.dll in the SDK and in VS is untrimmed, so PropertyFunctionReceiver.IsAllowed — which deliberately excludes mutating members like Delete/MoveTo/CopyTo — never runs.

Practical consequence: Directory::GetParent is allowlisted and returns a live DirectoryInfo, so a project file can call mutating file-system methods during plain evaluation (no targets run, no packages involved).

Steps to Reproduce

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Result>$([System.IO.Directory]::GetParent('some_dir/x').Delete(true))</Result>
  </PropertyGroup>
</Project>
mkdir some_dir && echo hi > some_dir/important.txt
dotnet build Repro.csproj -getProperty:Result
ls some_dir      # gone

Expected Behavior

Chained instance calls should be limited to the curated PropertyFunctionReceiver allowlist; DirectoryInfo.Delete should fail to bind.

Actual Behavior

some_dir and its contents are deleted during evaluation. -getProperty shows it happens with evaluation alone (i.e. also on IDE background evaluation), with no output at all.

Versions & Configurations

Reproduced on .NET SDK 10.0.301; the same code path exists in the 8.0/9.0 SDKs. Default configuration, no environment variables or command-line switches.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions