[security] SSH gate accepts source-address certificates without enforcing them #111

Closed
opened 2026-09-02 04:38:20 +00:00 by a73x · 2 comments
a73x commented 2026-09-02 04:38:20 +00:00 (Migrated from git.a73x.sh)

[claude 2026-09-02] Found by whole-tree security audit.

internal/server/sshgate/gate.go:182 returns &ssh.Permissions{Extensions: ...} with no CriticalOptions. x/crypto's CheckCert deliberately skips source-address ("enforced by serverAuthenticate"), and serverAuthenticate only enforces it from the returned permissions. SupportedCriticalOptions is nil, so every other critical option is refused; source-address is the one silently dropped. Same in delegation.Complete, where enforcement is meaningless (the plane is the client) but the cert is accepted and guests then refuse it opaquely.

Nothing in eitri depends on the option and docs promise nothing about it, but a tenant CA that mints one expects it honoured: if we accept it, people will use it. Severity Low.

Fix: return Permissions{CriticalOptions: cert.CriticalOptions, Extensions: ...} from PublicKeyCallback so x/crypto enforces it at the gate. Test: cert with source-address=203.0.113.0/24 refused from 127.0.0.1, accepted from an address inside the range. In delegation.Complete, refuse source-address certs with a diagnostic (guest sees the host's bridge address, so the restriction cannot hold on the inner hop), matching the existing principal diagnostics. Note the plane runs hostNetwork so the gate sees the real client address.


Migrated from git-collab issue 39c0defe9ad3df545d95f18026327145e251d442.

Original author: a73x dev@a73x.sh.

Close reason: [claude 2026-09-02] Fixed in 81b4b6c on main via patch 3170f758.

Linked commit: 88e31bf37ec06e0b972e1e9b8390a2c8a5f824ec

Linked commit: 81b4b6c1ca2b07794222ef7cd452e02d7dec46b4

[claude 2026-09-02] Found by whole-tree security audit. `internal/server/sshgate/gate.go:182` returns `&ssh.Permissions{Extensions: ...}` with no `CriticalOptions`. x/crypto's `CheckCert` deliberately skips `source-address` ("enforced by serverAuthenticate"), and `serverAuthenticate` only enforces it from the *returned* permissions. `SupportedCriticalOptions` is nil, so every other critical option is refused; `source-address` is the one silently dropped. Same in `delegation.Complete`, where enforcement is meaningless (the plane is the client) but the cert is accepted and guests then refuse it opaquely. Nothing in eitri depends on the option and docs promise nothing about it, but a tenant CA that mints one expects it honoured: if we accept it, people will use it. Severity Low. Fix: return `Permissions{CriticalOptions: cert.CriticalOptions, Extensions: ...}` from PublicKeyCallback so x/crypto enforces it at the gate. Test: cert with `source-address=203.0.113.0/24` refused from 127.0.0.1, accepted from an address inside the range. In delegation.Complete, refuse source-address certs with a diagnostic (guest sees the host's bridge address, so the restriction cannot hold on the inner hop), matching the existing principal diagnostics. Note the plane runs hostNetwork so the gate sees the real client address. --- Migrated from git-collab issue `39c0defe9ad3df545d95f18026327145e251d442`. Original author: a73x <dev@a73x.sh>. Close reason: [claude 2026-09-02] Fixed in 81b4b6c on main via patch 3170f758. Linked commit: `88e31bf37ec06e0b972e1e9b8390a2c8a5f824ec` Linked commit: `81b4b6c1ca2b07794222ef7cd452e02d7dec46b4`
a73x commented 2026-09-02 04:39:44 +00:00 (Migrated from git.a73x.sh)

[claude 2026-09-02] Picking this up; branch audit-fixes, one commit per issue, boot-gate before merge.

[claude 2026-09-02] Picking this up; branch audit-fixes, one commit per issue, boot-gate before merge.
a73x commented 2026-09-02 04:54:08 +00:00 (Migrated from git.a73x.sh)

[claude 2026-09-02] Fixed in 88e31bf on branch audit-fixes; carried by patch 3170f758fa (whose --fixes is 08f40f15). Close on merge.

[claude 2026-09-02] Fixed in 88e31bf on branch audit-fixes; carried by patch 3170f758faf406897dcacc4e3d605a2a8ba1fb03 (whose --fixes is 08f40f15). Close on merge.
Sign in to join this conversation.
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
a73x/eitri#111
No description provided.