diff --git a/pkg/backend/access_token.go b/pkg/backend/access_token.go index 281ad8f174a1c67896594485c1958820fd2ac668..b8db671a1c3c78b78ea12c8620e0ac791310e2bc 100644 --- a/pkg/backend/access_token.go +++ b/pkg/backend/access_token.go @@ -7,12 +7,14 @@ import ( "github.com/charmbracelet/soft-serve/pkg/db" "github.com/charmbracelet/soft-serve/pkg/proto" + "github.com/charmbracelet/soft-serve/pkg/utils" ) // CreateAccessToken creates an access token for user. func (b *Backend) CreateAccessToken(ctx context.Context, user proto.User, name string, expiresAt time.Time) (string, error) { token := GenerateToken() tokenHash := HashToken(token) + name = utils.Sanitize(name) if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error { _, err := b.store.CreateAccessToken(ctx, tx, name, user.ID(), tokenHash, expiresAt) diff --git a/pkg/backend/repo.go b/pkg/backend/repo.go index bacc8993848b638d4090b79e9f50a348446aa99a..e4eb3a7e12b4c290fad610cbeb9895fe1d17be43 100644 --- a/pkg/backend/repo.go +++ b/pkg/backend/repo.go @@ -544,6 +544,7 @@ func (d *Backend) SetHidden(ctx context.Context, name string, hidden bool) error // It implements backend.Backend. func (d *Backend) SetDescription(ctx context.Context, name string, desc string) error { name = utils.SanitizeRepo(name) + desc = utils.Sanitize(desc) rp := filepath.Join(d.repoPath(name)) // Delete cache @@ -617,6 +618,7 @@ func (d *Backend) SetPrivate(ctx context.Context, name string, private bool) err // It implements backend.Backend. func (d *Backend) SetProjectName(ctx context.Context, repo string, name string) error { repo = utils.SanitizeRepo(repo) + name = utils.Sanitize(name) // Delete cache d.cache.Delete(repo) diff --git a/pkg/backend/user.go b/pkg/backend/user.go index 4ad846c263df2dd42840a937b69d1850051e614f..736842f9fdddbc7fc83501ad02da1c5bd5f063f9 100644 --- a/pkg/backend/user.go +++ b/pkg/backend/user.go @@ -279,6 +279,7 @@ func (d *Backend) AddPublicKey(ctx context.Context, username string, pk ssh.Publ // // It implements backend.Backend. func (d *Backend) CreateUser(ctx context.Context, username string, opts proto.UserOptions) (proto.User, error) { + username = utils.Sanitize(username) username = strings.ToLower(username) if err := utils.ValidateUsername(username); err != nil { return nil, err diff --git a/pkg/backend/webhooks.go b/pkg/backend/webhooks.go index cd3eb07e78ce3016c835c6ae00976f5b33fd427c..f217c30337f374f7ff0b1aace8c19a86bfb19073 100644 --- a/pkg/backend/webhooks.go +++ b/pkg/backend/webhooks.go @@ -9,6 +9,7 @@ import ( "github.com/charmbracelet/soft-serve/pkg/db/models" "github.com/charmbracelet/soft-serve/pkg/proto" "github.com/charmbracelet/soft-serve/pkg/store" + "github.com/charmbracelet/soft-serve/pkg/utils" "github.com/charmbracelet/soft-serve/pkg/webhook" "github.com/google/uuid" ) @@ -17,6 +18,7 @@ import ( func (b *Backend) CreateWebhook(ctx context.Context, repo proto.Repository, url string, contentType webhook.ContentType, secret string, events []webhook.Event, active bool) error { dbx := db.FromContext(ctx) datastore := store.FromContext(ctx) + url = utils.Sanitize(url) return dbx.TransactionContext(ctx, func(tx *db.Tx) error { lastID, err := datastore.CreateWebhook(ctx, tx, repo.ID(), url, secret, int(contentType), active) diff --git a/pkg/ssh/cmd/commit.go b/pkg/ssh/cmd/commit.go index ad2020d36a2076e540f71c3eba380909fd7756b9..2dceace252e1552700926ccbb1d6b256465d416c 100644 --- a/pkg/ssh/cmd/commit.go +++ b/pkg/ssh/cmd/commit.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/soft-serve/pkg/backend" "github.com/charmbracelet/soft-serve/pkg/ui/common" "github.com/charmbracelet/soft-serve/pkg/ui/styles" + "github.com/charmbracelet/soft-serve/pkg/utils" "github.com/spf13/cobra" ) @@ -59,9 +60,9 @@ func commitCommand() *cobra.Command { s := strings.Builder{} commitLine := "commit " + commitSHA - authorLine := "Author: " + commit.Author.Name + authorLine := "Author: " + utils.Sanitize(commit.Author.Name) dateLine := "Date: " + commit.Committer.When.UTC().Format(time.UnixDate) - msgLine := strings.ReplaceAll(commit.Message, "\r\n", "\n") + msgLine := strings.ReplaceAll(utils.Sanitize(commit.Message), "\r\n", "\n") statsLine := renderStats(diff, commonStyle, color) diffLine := renderDiff(patch, color) diff --git a/pkg/ssh/cmd/webhooks.go b/pkg/ssh/cmd/webhooks.go index ca6e8978929c1ca283d3b5aff470ffed34358132..742127052107d2a8bd99f904d5e132e718e0a685 100644 --- a/pkg/ssh/cmd/webhooks.go +++ b/pkg/ssh/cmd/webhooks.go @@ -7,6 +7,7 @@ import ( "github.com/charmbracelet/lipgloss/v2/table" "github.com/charmbracelet/soft-serve/pkg/backend" + "github.com/charmbracelet/soft-serve/pkg/utils" "github.com/charmbracelet/soft-serve/pkg/webhook" "github.com/dustin/go-humanize" "github.com/google/uuid" @@ -69,7 +70,7 @@ func webhookListCommand() *cobra.Command { table = table.Row( strconv.FormatInt(h.ID, 10), - h.URL, + utils.Sanitize(h.URL), strings.Join(events, ","), strconv.FormatBool(h.Active), humanize.Time(h.CreatedAt), @@ -122,7 +123,8 @@ func webhookCreateCommand() *cobra.Command { return webhook.ErrInvalidContentType } - return be.CreateWebhook(ctx, repo, strings.TrimSpace(args[1]), ct, secret, evs, active) + url := utils.Sanitize(args[1]) + return be.CreateWebhook(ctx, repo, strings.TrimSpace(url), ct, secret, evs, active) }, } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 559e8e1b70324bdcfc049d3a4140dd1bf0e7f6aa..2fb66e55dc3a5f745f55e6d1b80b4cc2177209f3 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -5,10 +5,13 @@ import ( "path" "strings" "unicode" + + "github.com/charmbracelet/x/ansi" ) // SanitizeRepo returns a sanitized version of the given repository name. func SanitizeRepo(repo string) string { + repo = Sanitize(repo) // We need to use an absolute path for the path to be cleaned correctly. repo = strings.TrimPrefix(repo, "/") repo = "/" + repo @@ -20,6 +23,11 @@ func SanitizeRepo(repo string) string { return repo[1:] } +// Sanitize strips ANSI escape codes from the given string. +func Sanitize(s string) string { + return ansi.Strip(s) +} + // ValidateUsername returns an error if any of the given usernames are invalid. func ValidateUsername(username string) error { if username == "" {