Commit d35a23da authored by Jacob Vosmaer's avatar Jacob Vosmaer

Check repository path before proceeding

The path must exist and not contain '/../' (traversal).
parent 643fe8c8
...@@ -22,6 +22,7 @@ type gitHandler struct { ...@@ -22,6 +22,7 @@ type gitHandler struct {
} }
var http_client = &http.Client{} var http_client = &http.Client{}
var path_traversal = regexp.MustCompile(`/../`)
// Command-line options // Command-line options
var repo_root string var repo_root string
...@@ -52,6 +53,11 @@ func git_handler(w http.ResponseWriter, r *http.Request) { ...@@ -52,6 +53,11 @@ func git_handler(w http.ResponseWriter, r *http.Request) {
for _, g := range git_handlers { for _, g := range git_handlers {
path_match := g.regexp.FindStringSubmatch(r.URL.Path) path_match := g.regexp.FindStringSubmatch(r.URL.Path)
if r.Method == g.method && path_match != nil { if r.Method == g.method && path_match != nil {
found_path := path_match[1]
if !valid_path(found_path) {
http.Error(w, "Not found", 404)
return
}
auth_response, err := do_auth_request(r) auth_response, err := do_auth_request(r)
if err != nil { if err != nil {
fail_500(w, err) fail_500(w, err)
...@@ -73,13 +79,25 @@ func git_handler(w http.ResponseWriter, r *http.Request) { ...@@ -73,13 +79,25 @@ func git_handler(w http.ResponseWriter, r *http.Request) {
fail_500(w, err) fail_500(w, err)
return return
} }
g.handle_func(user, g.rpc, path.Join(repo_root, path_match[1]), w, r) g.handle_func(user, g.rpc, path.Join(repo_root, found_path), w, r)
return return
} }
} }
http.Error(w, "Not found", 404) http.Error(w, "Not found", 404)
} }
func valid_path(p string) bool {
if path_traversal.MatchString(p) {
log.Printf("path traversal detected in %s", p)
return false
}
if _, err := os.Stat(path.Join(repo_root, p, "objects")); err != nil {
log.Print(err)
return false
}
return true
}
func do_auth_request(r *http.Request) (result *http.Response, err error) { func do_auth_request(r *http.Request) (result *http.Response, err error) {
url := fmt.Sprintf("%s%s", *auth_backend, r.URL.RequestURI()) url := fmt.Sprintf("%s%s", *auth_backend, r.URL.RequestURI())
auth_req, err := http.NewRequest(r.Method, url, nil) auth_req, err := http.NewRequest(r.Method, url, nil)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment