diff options
author | Gusted <postmaster@gusted.xyz> | 2024-12-11 23:14:27 +0100 |
---|---|---|
committer | Earl Warren <contact@earl-warren.org> | 2024-12-12 05:54:07 +0100 |
commit | 3e1b03838e455d88089b4d6683443e1adfb4752e (patch) | |
tree | 72360b261429668bdcab44e64dcba612b89907e6 /modules | |
parent | Merge pull request 'Update dependency katex to v0.16.15 (forgejo)' (#6229) fr... (diff) | |
download | forgejo-3e1b03838e455d88089b4d6683443e1adfb4752e.tar.xz forgejo-3e1b03838e455d88089b4d6683443e1adfb4752e.zip |
fix: ensure correct ssh public key is used for authentication
- The root cause is described in https://github.com/golang/crypto/commit/b4f1988a35dee11ec3e05d6bf3e90b695fbd8909
- Move to a fork of `github.com/gliderlabs/ssh` that exposes the
permissions that was chosen by `x/crypto/ssh` after succesfully
authenticating, this is the recommended mitigation by the Golang
security team. The fork exposes this, since `gliderlabs/ssh` instead
relies on context values to do so, which is vulnerable to the same
attack, although partially mitigated by the fix in `x/crypto/ssh` it
would not be good practice and defense deep to rely on it.
- Existing tests covers that the functionality is preserved.
- No tests are added to ensure it fixes the described security, the
exploit relies on non-standard SSH behavior it would be too hard to
craft SSH packets to exploit this.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/ssh/ssh.go | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index f8e4f569b8..6ee10f718b 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -11,7 +11,6 @@ import ( "crypto/x509" "encoding/pem" "errors" - "fmt" "io" "net" "os" @@ -33,10 +32,6 @@ import ( gossh "golang.org/x/crypto/ssh" ) -type contextKey string - -const giteaKeyID = contextKey("gitea-key-id") - func getExitStatusFromError(err error) int { if err == nil { return 0 @@ -62,7 +57,7 @@ func getExitStatusFromError(err error) int { } func sessionHandler(session ssh.Session) { - keyID := fmt.Sprintf("%d", session.Context().Value(giteaKeyID).(int64)) + keyID := session.ConnPermissions().Extensions["forgejo-key-id"] command := session.RawCommand() @@ -238,7 +233,10 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { if log.IsDebug() { // <- FingerprintSHA256 is kinda expensive so only calculate it if necessary log.Debug("Successfully authenticated: %s Certificate Fingerprint: %s Principal: %s", ctx.RemoteAddr(), gossh.FingerprintSHA256(key), principal) } - ctx.SetValue(giteaKeyID, pkey.ID) + if ctx.Permissions().Extensions == nil { + ctx.Permissions().Extensions = map[string]string{} + } + ctx.Permissions().Extensions["forgejo-key-id"] = strconv.FormatInt(pkey.ID, 10) return true } @@ -266,7 +264,10 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { if log.IsDebug() { // <- FingerprintSHA256 is kinda expensive so only calculate it if necessary log.Debug("Successfully authenticated: %s Public Key Fingerprint: %s", ctx.RemoteAddr(), gossh.FingerprintSHA256(key)) } - ctx.SetValue(giteaKeyID, pkey.ID) + if ctx.Permissions().Extensions == nil { + ctx.Permissions().Extensions = map[string]string{} + } + ctx.Permissions().Extensions["forgejo-key-id"] = strconv.FormatInt(pkey.ID, 10) return true } |