dotnet / dotnet/msbuild

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

Open
#14,815 0 comments 0 reactions 1 assignee Claimed by @ViktorHofer View on GitHub
Priority:1 triaged
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 8h
Merged PRs (30d)
141

Description

### 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:

```csharp
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

```xml


net10.0
$([System.IO.Directory]::GetParent('some_dir/x').Delete(true))

```

```
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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.