diff --git a/api/sftp_endpoints.go b/api/sftp_endpoints.go index f0f7df8..a626c07 100644 --- a/api/sftp_endpoints.go +++ b/api/sftp_endpoints.go @@ -4,7 +4,6 @@ import ( "encoding/json" "github.com/pkg/errors" "github.com/pterodactyl/sftp-server" - "go.uber.org/zap" ) func (r *PanelRequest) ValidateSftpCredentials(request sftp_server.AuthenticationRequest) (*sftp_server.AuthenticationResponse, error) { @@ -23,13 +22,10 @@ func (r *PanelRequest) ValidateSftpCredentials(request sftp_server.Authenticatio if r.HasError() { if r.HttpResponseCode() >= 400 && r.HttpResponseCode() < 500 { - zap.S().Debugw("failed to validate server credentials for SFTP", zap.String("error", r.Error().String())) - return nil, new(sftp_server.InvalidCredentialsError) } rerr := errors.New(r.Error().String()) - zap.S().Warnw("error validating SFTP credentials", zap.Error(rerr)) return nil, rerr } diff --git a/go.mod b/go.mod index 885a0a8..2a472a3 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.4.0 github.com/pkg/sftp v1.11.0 // indirect - github.com/pterodactyl/sftp-server v1.1.2 + github.com/pterodactyl/sftp-server v1.1.4 github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 github.com/smartystreets/goconvey v1.6.4 // indirect diff --git a/go.sum b/go.sum index f9ec8af..dcbbc06 100644 --- a/go.sum +++ b/go.sum @@ -263,6 +263,8 @@ github.com/pterodactyl/sftp-server v1.1.1 h1:IjuOy21BNZxfejKnXG1RgLxXAYylDqBVpbK github.com/pterodactyl/sftp-server v1.1.1/go.mod h1:b1VVWYv0RF9rxSZQqaD/rYXriiRMNPsbV//CKMXR4ag= github.com/pterodactyl/sftp-server v1.1.2 h1:5bI9upe0kBRn9ALDabn9S2GVU5gkYvSErYgs32dAKjk= github.com/pterodactyl/sftp-server v1.1.2/go.mod h1:KjSONrenRr1oCh94QIVAU6yEzMe+Hd7r/JHrh5/oQHs= +github.com/pterodactyl/sftp-server v1.1.4 h1:JESuEuZ+d2tajMjuQblPOlGISM9Uc2xOzk7irVF9PQ0= +github.com/pterodactyl/sftp-server v1.1.4/go.mod h1:KjSONrenRr1oCh94QIVAU6yEzMe+Hd7r/JHrh5/oQHs= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce h1:aP+C+YbHZfOQlutA4p4soHi7rVUqHQdWEVMSkHfDTqY= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= diff --git a/sftp/server.go b/sftp/server.go index c554ce9..8a9f243 100644 --- a/sftp/server.go +++ b/sftp/server.go @@ -8,6 +8,7 @@ import ( "github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/server" "go.uber.org/zap" + "regexp" ) func Initialize(config *config.Configuration) error { @@ -70,13 +71,36 @@ func validateDiskSpace(fs sftp_server.FileSystem) bool { return s.Filesystem.HasSpaceAvailable() } +var validUsernameRegexp = regexp.MustCompile(`^(?i)(.+)\.([a-z0-9]{8})$`) + // Validates a set of credentials for a SFTP login aganist Pterodactyl Panel and returns // the server's UUID if the credentials were valid. func validateCredentials(c sftp_server.AuthenticationRequest) (*sftp_server.AuthenticationResponse, error) { - resp, err := api.NewRequester().ValidateSftpCredentials(c) - log.WithFields(log.Fields{"subsystem": "sftp", "username": c.User}).Debug("validating credentials for SFTP connection") + + f := log.Fields{ + "subsystem": "sftp", + "username": c.User, + "ip": c.IP, + } + + // If the username doesn't meet the expected format that the Panel would even recognize just go ahead + // and bail out of the process here to avoid accidentially brute forcing the panel if a bot decides + // to connect to spam username attempts. + if !validUsernameRegexp.MatchString(c.User) { + log.WithFields(f).Warn("failed to validate user credentials (invalid format)") + + return nil, new(sftp_server.InvalidCredentialsError) + } + + resp, err := api.NewRequester().ValidateSftpCredentials(c) if err != nil { + if sftp_server.IsInvalidCredentialsError(err) { + log.WithFields(f).Warn("failed to validate user credentials (invalid username or password)") + } else { + log.WithFields(f).Error("encountered an error while trying to validate user credentials") + } + return resp, err } @@ -88,7 +112,7 @@ func validateCredentials(c sftp_server.AuthenticationRequest) (*sftp_server.Auth return resp, errors.New("no matching server with UUID found") } - s.Log().WithFields(log.Fields{"subsystem": "sftp", "username": c.User}).Debug("matched user to server instance, credentials successfully validated") + s.Log().WithFields(f).Debug("credentials successfully validated and matched user to server instance") return resp, err }