fix(deps): pin SSH.NET to 2026.0.0 to clear the transitive advisory - #536
Merged
Conversation
Every backend build failed at restore:
Proxytrace.Messaging.Tests.csproj : error NU1903: Warning As Error: Package
'SSH.NET' 2025.1.0 has a known high severity vulnerability
NuGet's audit flags CVE-2026-48798 (GHSA-q939-rpr3-3284, high, CVSS 7.1) against
every SSH.NET at or below 2025.1.0: ScpClient.Download() does not validate
server-supplied filenames on a recursive download, so a malicious server can
traverse out of the target directory. TreatWarningsAsErrors promotes the warning
to an error, so one test project's transitive dependency failed the whole
solution build — and with it every open pull request.
The package is not referenced by any code here. It arrives as
Testcontainers.Redis -> Docker.DotNet -> SSH.NET, because Docker.DotNet supports
reaching a daemon over SSH, which this project's Testcontainers usage does not
do. So the practical exposure is nil: test-only, never in a runtime image, no
SCP anywhere. The build breakage was the whole problem.
Testcontainers.Redis 4.13.0 is the newest release, so there is no upstream bump
to take and the fix is a direct pin overriding the transitive resolution.
Docker.DotNet's constraint is a lower bound, so 2026.0.0 satisfies it and no
NU1608 is raised. Documented in docs/testing.md with the condition for removing
it, in the same shape as the manual's Vite override.
Verified without -p:NuGetAudit=false: restore and the solution build are clean,
SSH.NET resolves to 2026.0.0 in project.assets.json, and the full backend suite
passes (3,003 passed, 8 skipped, 0 failed).
Note on coverage: Docker is unavailable in this environment, so the
container-backed Redis tests skipped — the one path that actually exercises
Docker.DotNet, and therefore the only place a major SSH.NET bump could plausibly
bite, was not run locally. CI has Docker and sets
PROXYTRACE_REQUIRE_DOCKER_TESTS=true, so those tests are hard-required there.
No CHANGELOG entry: the dependency is test-only and ships in nothing.
Closes #534
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VA7JB61dw77kiymoNoeGqt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #534.
masteris red and every open PR with it. Restore fails before anything is compiled:What is actually wrong
CVE-2026-48798 — high, CVSS 7.1 — against every
SSH.NETat or below 2025.1.0:ScpClient.Download()does not validate server-supplied filenames on a recursive download, so a malicious server can traverse out of the target directory. First patched version is 2026.0.0.Nothing in this repository references SSH.NET. It arrives as:
Proxytrace.Messaging.Tests→Testcontainers.Redis4.13.0 →Docker.DotNet→SSH.NETbecause Docker.DotNet supports reaching a daemon over SSH — which this project's Testcontainers usage does not do.
So the security exposure here is nil: test-only dependency, never in a runtime image, no SCP anywhere in the codebase. The build breakage was total, because
TreatWarningsAsErrorsturns the audit warning into an error and one test project's transitive dependency then fails the whole solution.The fix
Testcontainers.Redis4.13.0 is the newest release, so there is no upstream bump to take — this is a direct pin overriding the transitive resolution. Docker.DotNet's constraint on SSH.NET is a lower bound, so 2026.0.0 satisfies it and noNU1608is raised.The pin carries its own removal condition, in the comment and in
docs/testing.md: drop it once aTestcontainers.Redisrelease resolves SSH.NET ≥ 2026.0.0 on its own. Same shape as the manual's existing Vite override — a pin that exists only to get ahead of a transitive advisory and should be deleted rather than maintained.Verification
All of the following without
-p:NuGetAudit=false, which is what was needed before this change:dotnet restore Proxytrace.sln --forceNU1903, noNU1608dotnet build Proxytrace.slnproject.assets.jsonSSH.NET/2026.0.0dotnet test Proxytrace.slnFull suite rather than just
Messaging.Tests, because a package bump changes dependency resolution for everything.Note
What I could not verify locally: Docker is unavailable in this environment, so the container-backed Redis tests skipped. That is the one path that actually exercises Docker.DotNet, and therefore the only place a major SSH.NET version bump could plausibly bite. CI has Docker and sets
PROXYTRACE_REQUIRE_DOCKER_TESTS=true, sobackendhard-requires those tests — the green tick on this PR is the real confirmation, not my local run.Not included
No CHANGELOG entry: the dependency is test-only and ships in nothing, so there is no user-facing change to describe.
Unblocks #535, which is red on this and nothing else.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VA7JB61dw77kiymoNoeGqt
Generated by Claude Code