fix(connection): trust MSIX-packaged wslrelay.exe when Authenticode check fails - #1177
fix(connection): trust MSIX-packaged wslrelay.exe when Authenticode check fails#1177larroy wants to merge 1 commit into
Conversation
…heck fails Modern WSL distributes as an MSIX package (Program Files\WSL / WindowsApps), which doesn't embed per-file Authenticode/catalog signatures on its EXEs -- trust is established at the package level instead. This caused genuine Microsoft wslrelay.exe binaries to be rejected during setup's loopback listener provenance check with "WSL relay Authenticode verification failed (Unsigned)". Add a fallback in WindowsAuthenticodeVerifier: when the classic Authenticode check fails and the file is wslrelay.exe, corroborate trust via the installed AppX package instead. Requires an exact match on the known WSL package family name (MicrosoftCorporationII.WindowsSubsystemForLinux_8wekyb3d8bbwe, whose suffix is derived from the publisher's signing cert), a real SignatureKind, and a Microsoft publisher (reusing the existing HasMicrosoftPublisherIdentity check). Looked up via a PowerShell Get-AppxPackage shell-out, matching this file's existing pattern for invoking schtasks.exe/wsl.exe. The primary Authenticode/catalog check is unchanged and always consulted first; the fallback narrows to wslrelay.exe specifically and never weakens the trust bar for any other binary.
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Codex review: needs real behavior proof before merge. Reviewed August 21, 2026, 2:28 PM ET / 18:28 UTC. ClawSweeper reviewWhat this changesThis PR adds an AppX package-metadata fallback for Merge readiness⛔ Blocked until real behavior proof from a real setup is added - 9 items remain Keep open. The useful MSIX compatibility goal remains unimplemented on current main, but the unchanged PR fallback still trusts package metadata without proving that the inspected relay belongs to that package, which can weaken the credential-protection boundary. Priority: P0 Review scores
Verification
Live VerificationCommand: Result: FAIL (failed) — execution before step 1 Assertions:
How this fits togetherLoopback listener provenance verifies that a local WSL relay actually fronts the managed gateway before shared or bootstrap credentials may be used. The proposed fallback sits between relay-path validation and that credential gate. flowchart LR
A[Loopback listener] --> B[Relay path review]
B --> C[Authenticode verification]
C -->|Signed| E[WSL gateway provenance]
C -->|Unsigned MSIX relay| D[Package ownership proof]
D --> E
E --> F[Shared credential gate]
Before merge
Findings
Agent review detailsSecurityNeeds attention: The package-level fallback can authenticate metadata for a genuine WSL package without authenticating the listener relay bytes that receive trusted provenance. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Preserve the compatibility fallback only after it proves the exact listener relay is owned by the trusted installed WSL package and shows that result on an affected MSIX installation. Do we have a high-confidence way to reproduce the issue? No. Source proves that a failed individual-file signature is rejected on current main, but this review has no observed affected MSIX relay from the current PR head. Is this the best way to solve the issue? No. Package family, publisher, and signature kind alone do not establish that the inspected relay is the package-owned file; exact path and package binding are required. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d3ed6c78bf14. LabelsLabel justifications:
EvidenceSecurity concerns:
Acceptance criteria:
What I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (1 earlier review cycle)
|
|
The compatibility issue is real: some Store/MSIX WSL installations can report the genuine The current fallback cannot merge because it disconnects the file being trusted from the package being verified. A genuine WSL package can be installed while a different Please change the fallback contract to receive the inspected path and prove package ownership:
Observed on this host: The goal is good. The package-level fallback just needs to prove that the package owns or authoritatively installed the exact relay bytes before those bytes can pass the credential-protection gate. |
|
Pedro, thank you for finding and addressing the underlying WSL compatibility problem. The important observation in this PR is correct: Windows can trust an MSIX package even when one of its executable files does not present the per-file Authenticode evidence we normally expect from a Win32 binary. We took this over in maintainer PR #1201 because this check sits on a credential boundary and the remaining work needed fairly deep Windows provenance and ACL handling. Your original commit and authorship are preserved as the first commit in that PR. The key Windows mental model is:
The original fallback established package identity, publisher, and signature kind, but the inspected relay path was not passed into that decision. That meant a genuine WSL package could be installed while a different relay under the broad canonical-path rule inherited the package's trust. The maintainer patch keeps your primary design and adds the missing binding:
There were also two subtle Windows ACL details worth calling out:
We also changed the tests so the primary Authenticode outcome is injected. On the maintainer host, WSL 2.9.4's external relay is already validly Microsoft-signed. Without injection, tests intended for package fallback can accidentally pass through the primary path and never test the fallback. #1201 includes the full history, threat model, implementation walkthrough, validation counts, current-head live package/ACL/version proof, and the proof limitation. The final structured security review is clean. Closing this PR as superseded by #1201. Thank you again for surfacing the compatibility issue and for providing the initial implementation that the maintainer patch builds on. |
Problem
Setup fails on machines running the modern MSIX-distributed WSL (
Program Files\WSL, e.g. the Store/GitHub-released package) with:MSIX packages don't embed per-file Authenticode/catalog signatures on their EXEs — trust is established at the package level instead (verified by Windows at install time). So
wslrelay.exe,wsl.exe,wslhost.exe, etc. from this distribution reportUnsignedviaWinVerifyTrust/FileSignatureInfo, even though they're genuine, unmodified Microsoft binaries (confirmed viaGet-AppxPackage:Publisher = CN=Microsoft Corporation, O=Microsoft Corporation, ...).Fix
Add a fallback to
WindowsAuthenticodeVerifier.VerifyMicrosoftSignedFile: when the primary Authenticode/catalog check fails and the file iswslrelay.exe, corroborate trust via the installed AppX package instead of rejecting outright. The fallback requires all of:MicrosoftCorporationII.WindowsSubsystemForLinux_8wekyb3d8bbwe(the suffix is derived from the publisher's signing certificate, so an impostor package re-signed with a different cert would get a different family name).SignatureKind(notNone) — proves Windows cryptographically validated the package at install time.HasMicrosoftPublisherIdentitycheck unchanged.Looked up via a
powershell.exe -Command "Get-AppxPackage ... | ConvertTo-Json"shell-out, matching this file's existing pattern for invokingschtasks.exe/wsl.exeelsewhere inManagedLocalGatewayPortProvenanceService.cs.The primary Authenticode/catalog check is unchanged, always runs first, and is never bypassed — the fallback only narrows scope to
wslrelay.exeand never weakens the trust bar for any other binary. No.csproj/TFM changes; no changes to the canonical-path allowlist.Testing
dotnet build src/OpenClaw.Connection/OpenClaw.Connection.csproj— succeeds, 0 warnings/errors.dotnet test tests/OpenClaw.Connection.Tests/OpenClaw.Connection.Tests.csproj— 638/638 passing, including 6 new tests covering: trusted-via-fallback, no-package-found, family-name mismatch, unsigned package, non-Microsoft publisher, and a regression test proving the fallback is never consulted when Authenticode already succeeds.🤖 Generated with Claude Code