NuGet / NuGet/Home

nuget install / nuget restore extracts .signature.p7s to disk; collides when multiple signed packages share an install root

Open Beginner friendly
#14,902 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area:ContentFiles Functionality:Install Functionality:Signing Priority:3 Product:NuGet.exe Type:Bug
Dominant language
HTML
Stars
1.6k
Forks
276
Avg merge
6d 1h
Merged PRs (30d)
1

Description

NuGet Product Used

NuGet.exe

Product Version

nuget 7.3.0

Worked before?

No

Impact

It's more difficult to complete my work

Repro Steps & Context
Minimal repro
  1. Author-sign two .nupkg files using dotnet sign code azure-key-vault (or any tool that wraps NuGet.Packaging.Signing.SigningUtility). Call them pkg-a.1.0.0.nupkg and pkg-b.1.0.0.nupkg. Each will contain .signature.p7s at the ZIP root.
  2. Push both to any NuGet feed.
  3. On a consumer, run:
    nuget.exe install pkg-a -Source <feed> -OutputDirectory C:\extracted -PackageSaveMode nupkg -ExcludeVersion
    nuget.exe install pkg-b -Source <feed> -OutputDirectory C:\extracted -PackageSaveMode nupkg -ExcludeVersion
    
  4. Inspect C:\extracted\pkg-a\ and C:\extracted\pkg-b\. Both contain .signature.p7s at the directory root, despite NuGet correctly stripping every other piece of NuGet metadata (_rels/, package/, [Content_Types].xml, *.sha512, *.nupkg.metadata).
What I expected

.signature.p7s is part of the NuGet package signature spec (NuGet/NuGet.Client/src/NuGet.Core/NuGet.Packaging/Signing/Specifications/SigningSpecificationsV1.cs, hardcoded as private const string _signaturePath = ".signature.p7s"). It is metadata, not content. It belongs in the same exclude list as the other signing/structural metadata files.

The expected behavior: NuGet client verifies the signature during restore, then strips .signature.p7s from the extracted output, just as it strips _rels/, package/, [Content_Types].xml, *.sha512, and *.nupkg.metadata.

What I got

.signature.p7s extracted to disk alongside the package payload. For consumers that do not merge multiple packages into one directory, this is harmless cruft. For consumers that do merge (e.g. vcpkg's --x-install-root model), any second package collides on the path:

error: The following files are already installed in
       <install-root>/x64-windows
       and are in conflict with vcpkg-cmake:x64-windows
       Installed by vcpkg-cmake-config:x64-windows: .signature.p7s
Where the omission lives (NuGet source)

NuGet.Packaging.PackageExtraction.PackageHelper.ExcludePaths (https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Packaging/PackageExtraction/PackageHelper.cs) currently filters:

_rels/
package/
[Content_Types].xml
*.sha512
*.nupkg.metadata

It does NOT filter .signature.p7s. Adding it is a one-line change. The signature blob has already served its verification purpose by the time extraction runs; there is no consumer use case for reading it from disk after restore.

Why this matters beyond vcpkg

Anyone whose consumer-side workflow assumes "extracted contents == package payload" hits this. vcpkg is the public example we tripped on. Internal build systems that consume NuGet feeds as opaque archive storage (and there are several — anything that uses NuGet as transport for non-.NET artifacts) would hit it the same way. The fix shifts the responsibility of stripping .signature.p7s from "every consumer that cares" to "the NuGet client, once, where it belongs."

Suggested fix (one-line change)

In NuGet.Packaging.PackageExtraction.PackageHelper.ExcludePaths, append .signature.p7s to the static array of excluded paths. (.signature.p7s is the sole signature-file path constant in the spec, defined as _signaturePath in SigningSpecificationsV1.cs.) Signature verification still runs against the in-memory ZIP entry before extraction; nothing else needs to change.

Verbose Logs
PS> & vcpkg.exe install --triplet x64-windows-v143-hybrid --binarysource="clear;nuget,vcpkg-deps,read" ...
Detecting compiler hash for triplet x64-windows-v143-hybrid...
Restored 0 package(s) from C:\Users\runneradmin\AppData\Local\vcpkg\archives in 67.2 us. Use --debug to see more details.
Installing 1/3 vcpkg-cmake-config:x64-windows@2024-05-23#0...
Restored 0 package(s) from NuGet feed: vcpkg-deps in 245.7 ms. Use --debug to see more details.
Installing 2/3 vcpkg-cmake:x64-windows@2024-04-23#0...
error: The following files are already installed in
       <redacted>/packages/vcpkg/x64-windows-v143-hybrid/x64-windows
       and are in conflict with vcpkg-cmake:x64-windows
       Installed by vcpkg-cmake-config:x64-windows: .signature.p7s

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in NuGet.Packaging/PackageExtraction/PackageHelper.cs at PackageHelper.ExcludePaths, then read the .signature.p7s definition in SigningSpecificationsV1.cs. Confirm extraction of signed packages omits the signature entry while signature verification still occurs before extraction.

Written by the indexing model from the issue text.

Assessment

Domain
tooling
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.