summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorGusted <postmaster@gusted.xyz>2024-12-11 23:14:27 +0100
committerEarl Warren <contact@earl-warren.org>2024-12-12 05:54:07 +0100
commit3e1b03838e455d88089b4d6683443e1adfb4752e (patch)
tree72360b261429668bdcab44e64dcba612b89907e6 /modules
parentMerge pull request 'Update dependency katex to v0.16.15 (forgejo)' (#6229) fr... (diff)
downloadforgejo-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.go17
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
}