Skip to content

[Security] Build-daemon named pipe: NULL DACL + unauthenticated Start-packet loads arbitrary assemblies (code execution) #46

Closed

Description

Severity: CVSS 7.8 (High) CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H · MSRC Important
Attacker: local co-tenant (same build account, different session/integrity; or pipe squat) · Metalama analogue: metalama/Metalama#1651 (+ metalama/Metalama#1648)
Scope: Windows, .NET Framework attended-build pipe-server mode

Affected code

  • Core/PostSharp.Compiler.Client.Protocol/Pipe/PipeStream.cs:354-366 — CreateNamedPipe(..., PIPE_UNLIMITED_INSTANCES, ..., IntPtr.Zero) (NULL security descriptor)
  • Core/PostSharp.Compiler.Client.Protocol/Pipe/PipeEndpointName.cs:17-50 — predictable name (embeds the user SID)
  • Core/PostSharp.Compiler.Hosting.NetFramework/PipeServerWorker.cs:242-260,103-166,302-333 — accepts an unauthenticated PipeStartPacket, runs its WorkingDirectory+Arguments in a FullTrust AppDomain
  • Core/PostSharp.Compiler.Client.Protocol/Pipe/PipeStartPacket.cs:27-44
  • Core/PostSharp.Compiler.Hosting/Program.cs:825-838,979-988 — args → project file
  • Core/PostSharp.Compiler.Engine/Sdk/Extensibility/Project.cs:699-723,1390-1432,2530-2543 — .dll/.exe loaded via AssemblyLoadHelper.LoadAssemblyFromFile, or <Using>/<Tasks AssemblyFile> from a .config; only a syntax path check
  • Core/PostSharp.MSBuild/Pipe/PipeClient.cs:453-465 — client blindly trusts the server Hello (squat direction)

Description

The server pipe is created with a NULL security descriptor (the process default token DACL, not owner-only) and PIPE_UNLIMITED_INSTANCES; its name is predictable. The server reads a PipeStartPacket with no peer authentication and uses its arguments to load and execute an arbitrary project file / plugin DLL / PostSharp.config (<Using>) in a FullTrust AppDomain.

Exploit scenario

(A) Code execution: a same-account process at a lower integrity level or in a different logon session (the NULL-SD default DACL admits same-SID cross-IL/cross-session access) connects to \\.\pipe\postsharp-<SID>... and sends a Start-packet whose args point at an attacker-writable evil.dll / /X:evil.config. The host loads & runs it in its FullTrust AppDomain → code execution in the build host's context.
(B) Squat / theft: because of unlimited instances + predictable name + no server authentication on the client, an attacker pre-creates a same-named server; the victim's MSBuild client connects and hands over the project path and /L: license keys, and accepts forged results.

Preconditions

Same build account (cross-session/cross-integrity), or the squat race; Windows + .NET Framework pipe-server mode. A plain same-account/same-session/same-integrity peer is non-additive (already equivalent power).

Recommendation

Create the pipe with an explicit owner-only PipeSecurity (and session/integrity restriction) instead of IntPtr.Zero; set FILE_FLAG_FIRST_PIPE_INSTANCE; authenticate the peer SID on accept (GetNamedPipeClientProcessId) and on connect (GetNamedPipeServerProcessId); constrain loadable project/plugin paths to the expected output dirs.

Backward compatibility

The pipe SD/flag change is shared between host and MSBuild client (they ship together, but users may mix package versions) → negotiate via a capability bit in the Hello packet; do not change the wire packet layout. No public API/IL impact.

Severity notes

Most debatable: Scope. S:C treats same-SID cross-integrity/cross-session as an authority crossing (the weakest S:C in the set since the SID is identical); S:U → 7.0, still High. If you reject the cross-session/cross-IL attacker entirely, the code-exec path is non-additive (informational) and only the squat info-disclosure remains.

Part of #56.

Activity

  1. changed the title [-]Placeholder for #50[/-] [+][Security] Build-daemon named pipe: NULL DACL + unauthenticated Start-packet loads arbitrary assemblies (code execution)[/+] on Jun 27, 2026
  2. gfraiteur commented on Jun 27, 2026

    @gfraiteur
    MemberAuthor

    Released in v2024.0.24.

    -- Claude for Gael

  3. gfraiteur commented on Jun 27, 2026

    @gfraiteur
    MemberAuthor

    Also released in v2026.0.13, which includes the upstream 2024.0.24 changes.

    -- Claude for Gael

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Area-Compiler-HostingCompiler processes, pipe server, CLR host, build-time tracesecurity

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions