Monorepo for Tangled tangled.org

all: use securejoin

anirudh.fi d527fd0c 016e82c2

verified
Changed files
+27 -22
appview
pages
templates
state
cmd
repoguard
knotserver
+1
appview/pages/templates/knots.html
··· 24 24 25 25 <section class="mb-12"> 26 26 <h3 class="text-xl font-semibold mb-4">my knots</h3> 27 + <p>This is a list of knots</p> 27 28 <ul id="my-knots" class="space-y-6"> 28 29 {{ range .Registrations }} 29 30 {{ if .Registered }}
+3 -2
appview/state/repo.go
··· 6 6 "io" 7 7 "log" 8 8 "net/http" 9 - "path/filepath" 10 9 11 10 "github.com/bluesky-social/indigo/atproto/identity" 11 + securejoin "github.com/cyphar/filepath-securejoin" 12 12 "github.com/go-chi/chi/v5" 13 13 "github.com/sotangled/tangled/appview/auth" 14 14 "github.com/sotangled/tangled/appview/pages" ··· 419 419 } 420 420 421 421 func (f *FullyResolvedRepo) OwnerSlashRepo() string { 422 - return filepath.Join(f.OwnerDid(), f.RepoName) 422 + p, _ := securejoin.SecureJoin(f.OwnerDid(), f.RepoName) 423 + return p 423 424 } 424 425 425 426 func fullyResolvedRepo(r *http.Request) (*FullyResolvedRepo, error) {
+3 -2
appview/state/state.go
··· 9 9 "fmt" 10 10 "log" 11 11 "net/http" 12 - "path/filepath" 13 12 "strings" 14 13 "time" 15 14 ··· 17 16 "github.com/bluesky-social/indigo/atproto/syntax" 18 17 lexutil "github.com/bluesky-social/indigo/lex/util" 19 18 "github.com/bluesky-social/jetstream/pkg/models" 19 + securejoin "github.com/cyphar/filepath-securejoin" 20 20 "github.com/go-chi/chi/v5" 21 21 tangled "github.com/sotangled/tangled/api/tangled" 22 22 "github.com/sotangled/tangled/appview" ··· 529 529 } 530 530 531 531 // acls 532 - err = s.enforcer.AddRepo(user.Did, domain, filepath.Join(user.Did, repoName)) 532 + p, _ := securejoin.SecureJoin(domain, repoName) 533 + err = s.enforcer.AddRepo(user.Did, domain, p) 533 534 if err != nil { 534 535 s.pages.Notice(w, "repo", "Failed to set up repository permissions.") 535 536 return
+3 -4
cmd/repoguard/main.go
··· 9 9 "net/url" 10 10 "os" 11 11 "os/exec" 12 - "path/filepath" 13 12 "strings" 14 13 "time" 15 14 15 + securejoin "github.com/cyphar/filepath-securejoin" 16 16 "github.com/sotangled/tangled/appview" 17 17 ) 18 18 ··· 79 79 didOrHandle := components[0] 80 80 did := resolveToDid(didOrHandle) 81 81 repoName := components[1] 82 - qualifiedRepoName := filepath.Join(did, repoName) 82 + qualifiedRepoName, _ := securejoin.SecureJoin(did, repoName) 83 83 84 84 validCommands := map[string]bool{ 85 85 "git-receive-pack": true, ··· 100 100 } 101 101 } 102 102 103 - fullPath := filepath.Join(*baseDirFlag, qualifiedRepoName) 104 - fullPath = filepath.Clean(fullPath) 103 + fullPath, _ := securejoin.SecureJoin(*baseDirFlag, qualifiedRepoName) 105 104 106 105 logEvent("Processing command", map[string]interface{}{ 107 106 "user": *incomingUser,
+1 -1
go.mod
··· 10 10 github.com/bluesky-social/indigo v0.0.0-20250123072624-9e3b84fdbb20 11 11 github.com/bluesky-social/jetstream v0.0.0-20241210005130-ea96859b93d1 12 12 github.com/casbin/casbin/v2 v2.103.0 13 + github.com/cyphar/filepath-securejoin v0.3.3 13 14 github.com/dustin/go-humanize v1.0.1 14 15 github.com/gliderlabs/ssh v0.3.5 15 16 github.com/go-chi/chi/v5 v5.2.0 ··· 36 37 github.com/casbin/govaluate v1.3.0 // indirect 37 38 github.com/cespare/xxhash/v2 v2.3.0 // indirect 38 39 github.com/cloudflare/circl v1.4.0 // indirect 39 - github.com/cyphar/filepath-securejoin v0.3.3 // indirect 40 40 github.com/davecgh/go-spew v1.1.1 // indirect 41 41 github.com/emirpasic/gods v1.18.1 // indirect 42 42 github.com/felixge/httpsnoop v1.0.4 // indirect
+3 -2
knotserver/git.go
··· 6 6 "net/http" 7 7 "path/filepath" 8 8 9 + securejoin "github.com/cyphar/filepath-securejoin" 9 10 "github.com/go-chi/chi/v5" 10 11 "github.com/sotangled/tangled/knotserver/git/service" 11 12 ) ··· 13 14 func (d *Handle) InfoRefs(w http.ResponseWriter, r *http.Request) { 14 15 did := chi.URLParam(r, "did") 15 16 name := chi.URLParam(r, "name") 16 - repo := filepath.Join(d.c.Repo.ScanPath, did, name) 17 + repo, _ := securejoin.SecureJoin(d.c.Repo.ScanPath, filepath.Join(did, name)) 17 18 18 19 w.Header().Set("content-type", "application/x-git-upload-pack-advertisement") 19 20 w.WriteHeader(http.StatusOK) ··· 33 34 func (d *Handle) UploadPack(w http.ResponseWriter, r *http.Request) { 34 35 did := chi.URLParam(r, "did") 35 36 name := chi.URLParam(r, "name") 36 - repo := filepath.Join(d.c.Repo.ScanPath, did, name) 37 + repo, _ := securejoin.SecureJoin(d.c.Repo.ScanPath, filepath.Join(did, name)) 37 38 38 39 w.Header().Set("content-type", "application/x-git-upload-pack-result") 39 40 w.Header().Set("Connection", "Keep-Alive")
+11 -10
knotserver/routes.go
··· 14 14 "strconv" 15 15 "strings" 16 16 17 + securejoin "github.com/cyphar/filepath-securejoin" 17 18 "github.com/gliderlabs/ssh" 18 19 "github.com/go-chi/chi/v5" 19 20 "github.com/go-git/go-git/v5/plumbing" ··· 29 30 } 30 31 31 32 func (h *Handle) RepoIndex(w http.ResponseWriter, r *http.Request) { 32 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 33 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 33 34 l := h.l.With("path", path, "handler", "RepoIndex") 34 35 35 36 gr, err := git.Open(path, "") ··· 116 117 117 118 l := h.l.With("handler", "RepoTree", "ref", ref, "treePath", treePath) 118 119 119 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 120 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 120 121 gr, err := git.Open(path, ref) 121 122 if err != nil { 122 123 notFound(w) ··· 148 149 149 150 l := h.l.With("handler", "FileContent", "ref", ref, "treePath", treePath) 150 151 151 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 152 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 152 153 gr, err := git.Open(path, ref) 153 154 if err != nil { 154 155 notFound(w) ··· 192 193 setContentDisposition(w, filename) 193 194 setGZipMIME(w) 194 195 195 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 196 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 196 197 gr, err := git.Open(path, ref) 197 198 if err != nil { 198 199 notFound(w) ··· 222 223 223 224 func (h *Handle) Log(w http.ResponseWriter, r *http.Request) { 224 225 ref := chi.URLParam(r, "ref") 225 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 226 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 226 227 227 228 l := h.l.With("handler", "Log", "ref", ref, "path", path) 228 229 ··· 288 289 289 290 l := h.l.With("handler", "Diff", "ref", ref) 290 291 291 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 292 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 292 293 gr, err := git.Open(path, ref) 293 294 if err != nil { 294 295 notFound(w) ··· 312 313 } 313 314 314 315 func (h *Handle) Tags(w http.ResponseWriter, r *http.Request) { 315 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 316 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 316 317 l := h.l.With("handler", "Refs") 317 318 318 319 gr, err := git.Open(path, "") ··· 353 354 } 354 355 355 356 func (h *Handle) Branches(w http.ResponseWriter, r *http.Request) { 356 - path := filepath.Join(h.c.Repo.ScanPath, didPath(r)) 357 + path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 357 358 l := h.l.With("handler", "Branches") 358 359 359 360 gr, err := git.Open(path, "") ··· 445 446 name := data.Name 446 447 447 448 relativeRepoPath := filepath.Join(did, name) 448 - repoPath := filepath.Join(h.c.Repo.ScanPath, relativeRepoPath) 449 + repoPath, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, relativeRepoPath) 449 450 err := git.InitBare(repoPath) 450 451 if err != nil { 451 452 l.Error("initializing bare repo", "error", err.Error()) ··· 522 523 } 523 524 h.jc.AddDid(data.Did) 524 525 525 - repoName := filepath.Join(ownerDid, repo) 526 + repoName, _ := securejoin.SecureJoin(ownerDid, repo) 526 527 if err := h.e.AddCollaborator(data.Did, ThisServer, repoName); err != nil { 527 528 l.Error("adding repo collaborator", "error", err.Error()) 528 529 writeError(w, err.Error(), http.StatusInternalServerError)
+2 -1
knotserver/util.go
··· 5 5 "os" 6 6 "path/filepath" 7 7 8 + securejoin "github.com/cyphar/filepath-securejoin" 8 9 "github.com/go-chi/chi/v5" 9 10 "github.com/microcosm-cc/bluemonday" 10 11 ) ··· 16 17 func didPath(r *http.Request) string { 17 18 did := chi.URLParam(r, "did") 18 19 name := chi.URLParam(r, "name") 19 - path := filepath.Join(did, name) 20 + path, _ := securejoin.SecureJoin(did, name) 20 21 filepath.Clean(path) 21 22 return path 22 23 }