Skip to content

[Audit-Medium] Stable release signing omits the first-party dependency copies packed into the Tools packages #4949

Description

@pepone

Found while fixing #4814 (PR #4942). The gap was spotted by Claude (Anthropic, Fable 5.1) with an independent OpenAI Codex cross-check, then verified by emulating the signing catalog's glob against a local Release build. It has not been triaged by a human for severity or priority; the severity below mirrors #4814, which is the same class of problem.

Summary

The stable release workflow signs, for each project directory under src, only the assembly named after that directory (*\bin\Release\net*\<Project>.dll), and then runs dotnet pack --no-build:

IceRpc.Protobuf.Tools and IceRpc.Slice.Tools build their tools/ payload by globbing the generator and build-telemetry projects' bin/Release/net10.0/* folders:

Those folders hold copy-local copies of first-party assemblies that belong to other projects, and the catalog never lists such copies. Each published Tools package therefore ships unsigned copies of:

Package Unsigned first-party copies in tools/ Copied from
IceRpc.Protobuf.Tools IceRpc.dll, IceRpc.Protobuf.dll, ZeroC.Slice.Codec.dll IceRpc.Protobuf.BuildTelemetry/bin
IceRpc.Slice.Tools IceRpc.dll, IceRpc.Slice.dll, ZeroC.Slice.Codec.dll, ZeroC.Slice.Symbols.dll ZeroC.Slice.Generator/bin, IceRpc.Slice.Generator/bin, IceRpc.Slice.BuildTelemetry/bin

The generator and build-telemetry assemblies themselves (IceRpc.Protobuf.Generator.dll, IceRpc.Slice.BuildTelemetry.dll, ...) are signed: they live under their own project directory and match the catalog glob. The same assemblies shipped in their own packages (IceRpc.dll in the IceRpc package, and so on) are signed too. Only the copies packed into tools/ are not.

#4814 narrowed the original finding to the MSBuild task assembly and stated that the dependency copies were not affected. That statement was wrong; #4942 fixes the task assembly only.

The same globs exist on 0.6.x.

Reproduction

After dotnet build --configuration Release, emulate the catalog:

for d in src/*/; do n=$(basename "$d"); find "$d" -path "*/bin/Release/net*/$n.dll"; done

and list the first-party assemblies in the globbed bin folders:

ls src/IceRpc.Protobuf.BuildTelemetry/bin/Release/net10.0 src/IceRpc.Slice.BuildTelemetry/bin/Release/net10.0 \
   src/ZeroC.Slice.Generator/bin/Release/net10.0 src/IceRpc.Slice.Generator/bin/Release/net10.0 | grep -E '^(IceRpc|ZeroC)'

The catalog lists each first-party assembly once, at its own project's bin. The copies in the four folders above are absent from it, and they are the files dotnet pack puts into tools/.

Possible fixes

  • Widen the catalog to every first-party assembly under src/*/bin/Release/net*/ (IceRpc*.dll and ZeroC.*.dll), so the copy-local copies are signed in place. This is the smallest change.
  • Alternatively, stop globbing bin folders for tools/ and pack the payload from an explicit list of signed paths, which also stops third-party copies from drifting in unnoticed.

Severity: Medium.

Activity

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

Metadata

Metadata

Assignees

Labels

ai-auditAI-generated audit finding — needs human triagebuild-system

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions