Monorepo for Tangled tangled.org

knotserver: add path-traversal check to NewRepo

this will come in handy when we create repos from firehose records.

Changed files
+39 -1
knotserver
+1 -1
flake.nix
··· 49 49 inherit (gitignore.lib) gitignoreSource; 50 50 in { 51 51 overlays.default = final: prev: let 52 - goModHash = "sha256-CmBuvv3duQQoc8iTW4244w1rYLGeqMQS+qQ3wwReZZg="; 52 + goModHash = "sha256-mCn5yrqWTVd2UTZibGcMHClIGQOTossj69iRruXiCuw="; 53 53 buildCmdPackage = name: 54 54 final.buildGoModule { 55 55 pname = name;
+38
knotserver/routes.go
··· 600 600 name := data.Name 601 601 defaultBranch := data.DefaultBranch 602 602 603 + if err := validateRepoName(name); err != nil { 604 + l.Error("creating repo", "error", err.Error()) 605 + writeError(w, err.Error(), http.StatusBadRequest) 606 + return 607 + } 608 + 603 609 relativeRepoPath := filepath.Join(did, name) 604 610 repoPath, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, relativeRepoPath) 605 611 err := git.InitBare(repoPath, defaultBranch) ··· 1078 1084 func (h *Handle) Health(w http.ResponseWriter, r *http.Request) { 1079 1085 w.Write([]byte("ok")) 1080 1086 } 1087 + 1088 + func validateRepoName(name string) error { 1089 + // check for path traversal attempts 1090 + if name == "." || name == ".." || 1091 + strings.Contains(name, "/") || strings.Contains(name, "\\") { 1092 + return fmt.Errorf("Repository name contains invalid path characters") 1093 + } 1094 + 1095 + // check for sequences that could be used for traversal when normalized 1096 + if strings.Contains(name, "./") || strings.Contains(name, "../") || 1097 + strings.HasPrefix(name, ".") || strings.HasSuffix(name, ".") { 1098 + return fmt.Errorf("Repository name contains invalid path sequence") 1099 + } 1100 + 1101 + // then continue with character validation 1102 + for _, char := range name { 1103 + if !((char >= 'a' && char <= 'z') || 1104 + (char >= 'A' && char <= 'Z') || 1105 + (char >= '0' && char <= '9') || 1106 + char == '-' || char == '_' || char == '.') { 1107 + return fmt.Errorf("Repository name can only contain alphanumeric characters, periods, hyphens, and underscores") 1108 + } 1109 + } 1110 + 1111 + // additional check to prevent multiple sequential dots 1112 + if strings.Contains(name, "..") { 1113 + return fmt.Errorf("Repository name cannot contain sequential dots") 1114 + } 1115 + 1116 + // if all checks pass 1117 + return nil 1118 + }