···
func (s *State) RemoveMember(w http.ResponseWriter, r *http.Request) {
func (s *State) NewRepo(w http.ResponseWriter, r *http.Request) {
ctx, span := s.t.TraceStart(r.Context(), "NewRepo")
···
span.SetAttributes(attribute.String("repo.name", repoName))
-
// Check for valid repository name (GitHub-like rules)
-
// No spaces, only alphanumeric characters, dashes, and underscores
-
for _, char := range repoName {
-
if !((char >= 'a' && char <= 'z') ||
-
(char >= 'A' && char <= 'Z') ||
-
(char >= '0' && char <= '9') ||
-
char == '-' || char == '_' || char == '.') {
-
s.pages.Notice(w, "repo", "Repository name can only contain alphanumeric characters, periods, hyphens, and underscores.")
defaultBranch := r.FormValue("branch")
···
func (s *State) RemoveMember(w http.ResponseWriter, r *http.Request) {
+
func validateRepoName(name string) error {
+
// check for path traversal attempts
+
if name == "." || name == ".." ||
+
strings.Contains(name, "/") || strings.Contains(name, "\\") {
+
return fmt.Errorf("Repository name contains invalid path characters")
+
// check for sequences that could be used for traversal when normalized
+
if strings.Contains(name, "./") || strings.Contains(name, "../") ||
+
strings.HasPrefix(name, ".") || strings.HasSuffix(name, ".") {
+
return fmt.Errorf("Repository name contains invalid path sequence")
+
// then continue with character validation
+
for _, char := range name {
+
if !((char >= 'a' && char <= 'z') ||
+
(char >= 'A' && char <= 'Z') ||
+
(char >= '0' && char <= '9') ||
+
char == '-' || char == '_' || char == '.') {
+
return fmt.Errorf("Repository name can only contain alphanumeric characters, periods, hyphens, and underscores")
+
// additional check to prevent multiple sequential dots
+
if strings.Contains(name, "..") {
+
return fmt.Errorf("Repository name cannot contain sequential dots")
func (s *State) NewRepo(w http.ResponseWriter, r *http.Request) {
ctx, span := s.t.TraceStart(r.Context(), "NewRepo")
···
span.SetAttributes(attribute.String("repo.name", repoName))
+
if err := validateRepoName(repoName); err != nil {
+
s.pages.Notice(w, "repo", err.Error())
defaultBranch := r.FormValue("branch")