Skip to content

Commit

Permalink
feat(remote): improve input validation and security in remote operations
Browse files Browse the repository at this point in the history
- Change file permissions from `0o700` to `0o600` in `WriteKey` function
- Import `regexp` package in `remote.go`
- Add `sanitizeInput` and `isValidInput` functions for input validation
- Use sanitized inputs in `RemotePushNamedBranch` function
- Add unit tests for `sanitizeInput` function in new `remote_test.go` file

Signed-off-by: appleboy <[email protected]>
  • Loading branch information
appleboy committed Nov 16, 2024
1 parent ad145ca commit aa4ae84
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
2 changes: 1 addition & 1 deletion repo/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func WriteKey(privateKey string) error {
_ = os.WriteFile(
confpath,
[]byte("StrictHostKeyChecking no\n"),
0o700)
0o600)

return os.WriteFile(
privpath,
Expand Down
23 changes: 21 additions & 2 deletions repo/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repo

import (
"os/exec"
"regexp"
)

// RemoteRemove drops the defined remote from a git repo.
Expand Down Expand Up @@ -43,13 +44,31 @@ func RemotePullRebaseNamedBranch(remote, branch string) *exec.Cmd {
return cmd
}

var validBranchName = regexp.MustCompile(`^[\w\.\-\/]+$`)

func sanitizeInput(input string) string {
if isValidInput(input) {
return input
}
return ""
}

func isValidInput(input string) bool {
return validBranchName.MatchString(input)
}

// RemotePushNamedBranch puchs changes from a local to a remote branch.
func RemotePushNamedBranch(remote, localbranch string, branch string, force bool, followtags bool) *exec.Cmd {
sanitizedRemote := sanitizeInput(remote)
sanitizedLocalBranch := sanitizeInput(localbranch)
sanitizedBranch := sanitizeInput(branch)

cmd := exec.Command(
"git",
"push",
remote,
localbranch+":"+branch)
sanitizedRemote,
sanitizedLocalBranch+":"+sanitizedBranch,
)

if force {
cmd.Args = append(
Expand Down
47 changes: 47 additions & 0 deletions repo/remote_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package repo

import (
"testing"
)

func TestSanitizeInput(t *testing.T) {
tests := []struct {
name string
input string
want string
}{
{
name: "valid input with alphanumeric characters",
input: "feature-branch",
want: "feature-branch",
},
{
name: "valid input with dots and slashes",
input: "release/1.0.0",
want: "release/1.0.0",
},
{
name: "invalid input with spaces",
input: "invalid branch",
want: "",
},
{
name: "invalid input with special characters",
input: "invalid@branch!",
want: "",
},
{
name: "empty input",
input: "",
want: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := sanitizeInput(tt.input); got != tt.want {
t.Errorf("sanitizeInput() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit aa4ae84

Please sign in to comment.