···
func (s *State) RemoveMember(w http.ResponseWriter, r *http.Request) {
604
+
func validateRepoName(name string) error {
605
+
// check for path traversal attempts
606
+
if name == "." || name == ".." ||
607
+
strings.Contains(name, "/") || strings.Contains(name, "\\") {
608
+
return fmt.Errorf("Repository name contains invalid path characters")
611
+
// check for sequences that could be used for traversal when normalized
612
+
if strings.Contains(name, "./") || strings.Contains(name, "../") ||
613
+
strings.HasPrefix(name, ".") || strings.HasSuffix(name, ".") {
614
+
return fmt.Errorf("Repository name contains invalid path sequence")
617
+
// then continue with character validation
618
+
for _, char := range name {
619
+
if !((char >= 'a' && char <= 'z') ||
620
+
(char >= 'A' && char <= 'Z') ||
621
+
(char >= '0' && char <= '9') ||
622
+
char == '-' || char == '_' || char == '.') {
623
+
return fmt.Errorf("Repository name can only contain alphanumeric characters, periods, hyphens, and underscores")
627
+
// additional check to prevent multiple sequential dots
628
+
if strings.Contains(name, "..") {
629
+
return fmt.Errorf("Repository name cannot contain sequential dots")
632
+
// if all checks pass
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))
646
-
// Check for valid repository name (GitHub-like rules)
647
-
// No spaces, only alphanumeric characters, dashes, and underscores
648
-
for _, char := range repoName {
649
-
if !((char >= 'a' && char <= 'z') ||
650
-
(char >= 'A' && char <= 'Z') ||
651
-
(char >= '0' && char <= '9') ||
652
-
char == '-' || char == '_' || char == '.') {
653
-
s.pages.Notice(w, "repo", "Repository name can only contain alphanumeric characters, periods, hyphens, and underscores.")
678
+
if err := validateRepoName(repoName); err != nil {
679
+
s.pages.Notice(w, "repo", err.Error())
defaultBranch := r.FormValue("branch")