Skip to content

[Security] Build artifacts loaded/executed from world-writable shared directories without integrity check (DLL planting) #45

Closed

Description

Severity: CVSS 8.2 (High) CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H · MSRC Important
Attacker: local co-tenant · Metalama analogue: metalama/Metalama#1650

Affected code

  • Core/PostSharp.MSBuild/PostSharp.properties (defaults) — Unix Cache/Spool/Temp/Dependency under /var/tmp/postsharp; Windows under %PROGRAMDATA%\PostSharp (~lines 180-266, 306-338)
  • Core/PostSharp.MSBuild/NetCore/NativeImageManager.cs:471-498,556-568 — R2R native images returned on existence + mtime only, no hash/sig
  • Core/PostSharp.MSBuild/BuildToolsHelper.cs:54-204 + Core/PostSharp.MSBuild/BuildClient.cs:553,793,812-873 — extracted host assemblies executed via dotnet exec
  • Core/PostSharp.MSBuild/NetCore/BuildTimeDependencyRestorer.cs:188-190 — restored dependency assemblies
  • Core/PostSharp.MSBuild/PostSharp.targets:39-50 — dirs created (MakeDir/Directory.CreateDirectory) with no restrictive ACL and no symlink/owner check

Description

The cache/tools/dependency directories default to predictable shared locations that are world-writable on Unix (/var/tmp/postsharp, no per-user isolation) and Users-creatable on Windows (%PROGRAMDATA%\PostSharp). PostSharp loads and executes native R2R images, extracted compiler-host assemblies, and restored dependency assemblies from these directories with an existence-only up-to-date check and no hash/strong-name/Authenticode verification before execution.

Exploit scenario

On a shared Linux CI agent or multi-user host, an unprivileged co-tenant pre-plants a malicious PostSharp.Compiler.Engine.dll / *.ni.dll (bumping mtime / dropping the .touch sentinel) in the shared directory before the victim builds. The victim's next build hardlinks/copies and dotnet execs the planted assembly → arbitrary code execution as the building user. Pre-planting on a persistent shared dir is reliable (not a race). %PROGRAMDATA% on Windows is the same cross-user pattern.

Preconditions

Shared/world-writable dir reachable by the attacker (Unix default); victim runs a build (UI). ReadyToRun not disabled (for the native-image vector).

Recommendation

Default these dirs to per-user locations on Unix ($XDG_CACHE_HOME/$HOME/.cache/postsharp, $HOME/.local/share); create with owner-only permissions and reject a pre-existing dir that is not owned by the current user / is a symlink / is group-or-other-writable; verify strong-name/hash of cached native images and extracted host assemblies before load/exec (record a hash in the .touch and re-validate).

Backward compatibility

PostSharp*Directory MSBuild properties stay overridable; document the default-path change in Release Notes. ACL hardening + pre-exec verification are non-breaking.

Severity notes

Most debatable: AC (pre-plant reliable → AC:L; if the build trigger/filename is attacker-uncontrolled → AC:H = 8.5) and Scope (cross-user exec = S:C; if rejected → S:U = 7.3). Band is stable at High either way.

Part of #56.

Activity

  1. changed the title [-]Placeholder for #49[/-] [+][Security] Build artifacts loaded/executed from world-writable shared directories without integrity check (DLL planting)[/+] 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

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions