mirror of
https://codeberg.org/davrot/forgejo.git
synced 2025-05-17 14:00:01 +02:00
fix: ensure correct ssh public key is used for authentication
- The root cause is described in b4f1988a35
- 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.
This commit is contained in:
parent
80179a373d
commit
3e1b03838e
3 changed files with 13 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue