Mistyped algorithm list silently falls back to permissive defaults

Summary

When every entry in kex_algorithms, ciphers, or macs is unrecognized, gitlab-sshd silently restores the full default list. An administrator who mistypes a hardening list ends up with a more permissive server than they started with, including SHA-1 algorithms, with no error and no log warning.

Detail

SetDefaults() runs twice on the server config:

  1. internal/sshd/server_config.go calls sshCfg.SetDefaults() at the end of buildServerConfig.
  2. x/crypto/ssh calls fullConf.SetDefaults() again inside NewServerConn.

In x/crypto/ssh/common.go, the filter loop starts from a nil slice and appends only recognized names:

var ciphers []string
for _, c := range c.Ciphers {
    if cipherModes[c] != nil {
        // Ignore the cipher if we have no cipherModes definition.
        ciphers = append(ciphers, c)
    }
}
c.Ciphers = ciphers

If nothing matches, the field ends up nil. The second SetDefaults() then reads nil as "unset" and restores defaultCiphers, defaultKexAlgos, or the default MAC list.

Steps to reproduce

Set macs: [bogus-mac] in the sshd section of config.yml and start gitlab-sshd, then scan the port:

ssh -vv -o BatchMode=yes -p <port> git@127.0.0.1 2>&1 | grep -i 'MACs'

Observed: all six default MACs are offered, including hmac-sha1 and hmac-sha1-96.

Verified against gitlab-shell 14.56.1 with golang.org/x/crypto v0.54.0.

Expected

Refuse to start, or at minimum log a warning, when a configured algorithm list resolves to zero recognized entries. Silently falling back to defaults is the least safe outcome, because these settings exist specifically to remove algorithms.

Partial typos are a milder version of the same problem: the name is dropped without a warning, so the resulting set differs from what was written.

Context

Found while documenting these settings in gitlab!252085 (merged).