feat/updates #1

Merged
Snider merged 51 commits from feat/updates into dev 2026-02-16 05:54:07 +00:00
2 changed files with 64 additions and 2 deletions
Showing only changes of commit f28259bb13 - Show all commits

View file

@ -106,7 +106,23 @@ func loadEthicsGuard(ctx context.Context, rootHint string) *EthicsGuard {
}
func (g *EthicsGuard) SanitizeEnv(value string) string {
return sanitizeInline(value, maxEnvRunes)
return stripShellMeta(sanitizeInline(value, maxEnvRunes))
}
// stripShellMeta removes shell metacharacters that could allow command
// injection when a value is interpolated inside a shell environment variable.
func stripShellMeta(s string) string {
var b strings.Builder
b.Grow(len(s))
for _, r := range s {
switch r {
case '`', '$', ';', '|', '&', '(', ')', '{', '}', '<', '>', '!', '\\', '\'', '"', '\n', '\r':
continue
default:
b.WriteRune(r)
}
}
return strings.TrimSpace(b.String())
}
func (g *EthicsGuard) SanitizeTitle(value string) string {

View file

@ -1,6 +1,8 @@
package bugseti
import "testing"
import (
"testing"
)
func TestSanitizeInline_Good(t *testing.T) {
input := "Hello world"
@ -26,3 +28,47 @@ func TestSanitizeMultiline_Ugly(t *testing.T) {
t.Fatalf("expected %q, got %q", "ab\ncd", output)
}
}
func TestSanitizeEnv_Good(t *testing.T) {
g := &EthicsGuard{}
input := "owner/repo-name"
output := g.SanitizeEnv(input)
if output != input {
t.Fatalf("expected %q, got %q", input, output)
}
}
func TestSanitizeEnv_Bad(t *testing.T) {
g := &EthicsGuard{}
tests := []struct {
name string
input string
expected string
}{
{"backtick", "owner/repo`whoami`", "owner/repowhoami"},
{"dollar", "owner/repo$(id)", "owner/repoid"},
{"semicolon", "owner/repo;rm -rf /", "owner/reporm -rf /"},
{"pipe", "owner/repo|cat /etc/passwd", "owner/repocat /etc/passwd"},
{"ampersand", "owner/repo&&echo pwned", "owner/repoecho pwned"},
{"mixed", "`$;|&(){}<>!\\'\"\n\r", ""},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
output := g.SanitizeEnv(tc.input)
if output != tc.expected {
t.Fatalf("expected %q, got %q", tc.expected, output)
}
})
}
}
func TestStripShellMeta_Ugly(t *testing.T) {
// All metacharacters should be stripped, leaving empty string
input := "`$;|&(){}<>!\\'\""
output := stripShellMeta(input)
if output != "" {
t.Fatalf("expected empty string, got %q", output)
}
}