fix(agent/get.ps1): narrow overly-broad TLS-failure classification regex (#962) #31

Merged
amiryahaya merged 1 commit from fix/962-tls-classification-regex into main 2026-09-23 14:27:01 +02:00
Owner

Fixes the bug behind mirrored triton-repo issue #962 (read-only, from
git.antrapol.tech — not edited/commented/closed there; this PR is the
record).

The bug

$TlsDetail -match 'inner exception|CERT_AUTHORITY_INVALID|CA' was
unintentionally unconditional: PowerShell wraps every .NET
method-invocation exception in boilerplate text like Exception calling "AuthenticateAsClient" with "1" argument(s): — and
"AuthenticateAsClient" itself contains the substring "ca"
(case-insensitive) — so the bare CA alternative matched literally
any exception this call site could throw, not just a genuine CA/trust
mismatch. inner exception is equally generic — SSPI auth failures
routinely wrap with "see inner exception" regardless of cause.

Confirmed empirically, not guessed: a synthetic "connection forcibly
closed" exception (nothing to do with CA trust) matched the old
pattern too, in a real pwsh test.

The fix

Narrowed to the actual, verified message
System.Net.Security.SslStream's own cross-platform managed code
produces specifically when the custom RemoteCertificateValidationCallback
returns $false:

The remote certificate was rejected by the provided RemoteCertificateValidationCallback.

Confirmed by direct testing against a real SslStream handshake
(self-signed cert + TcpListener + a callback that deliberately
returns false) — not assumed from documentation. Since this message
comes from .NET's shared managed layer (not the OS-specific
SChannel/OpenSSL backend), it should be reliable on Windows too. Kept
CERT_AUTHORITY_INVALID as a secondary fallback (a specific
CAPI/Win32 error constant, low false-positive risk).

Caveat: I could not empirically verify Windows/SChannel's exact
text for the benign "no client cert yet" mTLS-rejection case without a
real Windows box — on this Mac's OpenSSL-backed .NET runtime that case
doesn't even throw client-side at all, so cross-platform testing has a
real limit here. The fix doesn't need to positively match that case,
only to stop false-matching it: narrowing away the generic inner exception/bare-CA alternatives achieves that regardless of what
Windows's actual benign-case text turns out to be.

$TlsDetail is used only for this one classification check, never
displayed to the user, so no other code path is affected.

Testing

This repo has no test harness for .ps1 files. Verified via a
throwaway pwsh script (not committed): the old pattern matches both
a real captured CA-rejection message and a synthetic unrelated one;
the new pattern matches only the former. PowerShell AST parse clean;
PSScriptAnalyzer shows only pre-existing warnings unrelated to this
change. $SCRIPT_VERSION bumped 1.3.9 → 1.3.10.

🤖 Generated with Claude Code

Fixes the bug behind mirrored triton-repo issue #962 (read-only, from git.antrapol.tech — not edited/commented/closed there; this PR is the record). ## The bug `$TlsDetail -match 'inner exception|CERT_AUTHORITY_INVALID|CA'` was unintentionally unconditional: PowerShell wraps every .NET method-invocation exception in boilerplate text like `Exception calling "AuthenticateAsClient" with "1" argument(s):` — and **"AuthenticateAsClient" itself contains the substring "ca"** (case-insensitive) — so the bare `CA` alternative matched literally any exception this call site could throw, not just a genuine CA/trust mismatch. `inner exception` is equally generic — SSPI auth failures routinely wrap with "see inner exception" regardless of cause. Confirmed empirically, not guessed: a synthetic "connection forcibly closed" exception (nothing to do with CA trust) matched the old pattern too, in a real `pwsh` test. ## The fix Narrowed to the actual, verified message `System.Net.Security.SslStream`'s own **cross-platform managed code** produces specifically when the custom `RemoteCertificateValidationCallback` returns `$false`: > The remote certificate was rejected by the provided RemoteCertificateValidationCallback. Confirmed by direct testing against a real `SslStream` handshake (self-signed cert + `TcpListener` + a callback that deliberately returns false) — not assumed from documentation. Since this message comes from .NET's shared managed layer (not the OS-specific SChannel/OpenSSL backend), it should be reliable on Windows too. Kept `CERT_AUTHORITY_INVALID` as a secondary fallback (a specific CAPI/Win32 error constant, low false-positive risk). **Caveat:** I could not empirically verify Windows/SChannel's exact text for the benign "no client cert yet" mTLS-rejection case without a real Windows box — on this Mac's OpenSSL-backed .NET runtime that case doesn't even throw client-side at all, so cross-platform testing has a real limit here. The fix doesn't need to positively match that case, only to stop false-matching it: narrowing away the generic `inner exception`/bare-`CA` alternatives achieves that regardless of what Windows's actual benign-case text turns out to be. `$TlsDetail` is used only for this one classification check, never displayed to the user, so no other code path is affected. ## Testing This repo has no test harness for `.ps1` files. Verified via a throwaway `pwsh` script (not committed): the old pattern matches both a real captured CA-rejection message *and* a synthetic unrelated one; the new pattern matches only the former. PowerShell AST parse clean; `PSScriptAnalyzer` shows only pre-existing warnings unrelated to this change. `$SCRIPT_VERSION` bumped 1.3.9 → 1.3.10. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
$TlsDetail -match 'inner exception|CERT_AUTHORITY_INVALID|CA' was
unintentionally unconditional: PowerShell wraps every .NET
method-invocation exception in boilerplate text like 'Exception
calling "AuthenticateAsClient" with "1" argument(s):' -- and
"AuthenticateAsClient" itself contains the substring "ca"
(case-insensitive) -- so the bare 'CA' alternative matched literally
any exception this call site could throw, not just a genuine
CA/trust mismatch. Confirmed empirically, not guessed: a synthetic
"connection forcibly closed" exception (nothing to do with CA trust)
matched the old pattern too.

Fix: narrow to the actual, verified message
System.Net.Security.SslStream's own cross-platform managed code
produces specifically when the custom RemoteCertificateValidationCallback
above returns $false -- "The remote certificate was rejected by the
provided RemoteCertificateValidationCallback." Confirmed by direct
testing against a real SslStream handshake (self-signed cert +
TcpListener + a callback that deliberately returns false), not
assumed from documentation. Kept CERT_AUTHORITY_INVALID as a
secondary fallback (a specific CAPI/Win32 error constant, low
false-positive risk).

Could not empirically verify Windows/SChannel's exact text for the
benign "no client cert yet" mTLS-rejection case without a real
Windows box -- on this Mac's OpenSSL-backed .NET runtime that case
doesn't even throw client-side at all, so cross-platform testing has
a real limit here. The fix doesn't need to positively match that
case, only to stop false-matching it: narrowing away the generic
'inner exception'/bare-'CA' alternatives achieves that regardless of
what Windows's actual benign-case text turns out to be.

$TlsDetail is used only for this one classification check, never
displayed to the user, so no other code path is affected.

Fixes mirrored issue #962 (read-only, from git.antrapol.tech -- not
edited/commented/closed here; this commit message is the record).
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
primatekuntech/triton-install!31
No description provided.