From 0aedf80727df765e337b4080cf960eeec30e2919 Mon Sep 17 00:00:00 2001 From: dtookey Date: Mon, 31 Jul 2023 15:40:51 -0400 Subject: [PATCH] Fixing up some directory traversal attacks round 4 --- servlet/config.go | 4 ++-- servlet/dynamicRoute.go | 4 ++-- servlet/server.go | 33 ++++++++++++++++----------------- servlet/staticRoute.go | 22 +++++++++++----------- servlet/templateRoute.go | 8 ++++---- 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/servlet/config.go b/servlet/config.go index 9606d7a..55b4654 100644 --- a/servlet/config.go +++ b/servlet/config.go @@ -58,7 +58,7 @@ func CreateBlankConfig() *Config { return &conf } -func LoadConfig(pathlike string) *VinegarServlet { +func LoadConfig(pathlike string) *VinegarHttpServlet { contents, exists := vinegarUtil.GetDiskContent(pathlike) if exists { conf := Config{} @@ -86,7 +86,7 @@ func LoadConfig(pathlike string) *VinegarServlet { } } -func (e ConfigEntry) toRoute(serv *VinegarServlet) { +func (e ConfigEntry) toRoute(serv *VinegarHttpServlet) { constructor, err := getConstructorFunction(e.ConfigType) if err != nil { panic(err) diff --git a/servlet/dynamicRoute.go b/servlet/dynamicRoute.go index d63861f..6b5876a 100644 --- a/servlet/dynamicRoute.go +++ b/servlet/dynamicRoute.go @@ -7,7 +7,7 @@ import ( type ( ApiRoute struct { - VinegarRoute *VinegarRoute + VinegarRoute *VinegarWebRoute HttpMethodRoutes *map[HttpMethod]VinegarHandlerFunction } ) @@ -25,7 +25,7 @@ const ( UNDEFINED ) -func NewApiRoute(serv *VinegarServlet, pattern string) *ApiRoute { +func NewApiRoute(serv *VinegarHttpServlet, pattern string) *ApiRoute { functionMap := make(map[HttpMethod]VinegarHandlerFunction) ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap)) route := ApiRoute{ diff --git a/servlet/server.go b/servlet/server.go index e445a62..eaeddf0 100644 --- a/servlet/server.go +++ b/servlet/server.go @@ -25,20 +25,20 @@ type ErrorResponse struct { } type ( - // VinegarServlet is the main server struct that handles HTTP requests and routing. + // VinegarHttpServlet is the main server struct that handles HTTP requests and routing. // It contains the TCP port to listen on, the routes to match requests against, // and a map of status code to error handling routes. - VinegarServlet struct { + VinegarHttpServlet struct { Port string - Routes []*VinegarRoute + Routes []*VinegarWebRoute ErrorRoutes map[int]*TemplateRoute } - // VinegarRoute defines a single route in the router. + // VinegarWebRoute defines a single route in the router. // It contains a regex Pattern to match against the URL path, // a Handler function to call when the route matches, // and an optional Cache to enable caching for the route. - VinegarRoute struct { + VinegarWebRoute struct { Pattern *regexp.Regexp Handler VinegarHandlerFunction Cache vinegarUtil.Cache @@ -47,32 +47,31 @@ type ( VinegarHandlerFunction func(w http.ResponseWriter, req *http.Request) ) -func NewServlet(port string) *VinegarServlet { - errors := make(map[int]*TemplateRoute) - srv := VinegarServlet{Port: port, ErrorRoutes: errors} +func NewServlet(port string) *VinegarHttpServlet { + errs := make(map[int]*TemplateRoute) + srv := VinegarHttpServlet{Port: port, ErrorRoutes: errs} return &srv } -func NewServletRoute(routePattern string, handleFunc VinegarHandlerFunction) *VinegarRoute { - +func NewServletRoute(routePattern string, handleFunc VinegarHandlerFunction) *VinegarWebRoute { pattern := regexp.MustCompile(routePattern) - route := VinegarRoute{Pattern: pattern, Handler: handleFunc, Cache: vinegarUtil.NewLRU(defaultLruSize)} + route := VinegarWebRoute{Pattern: pattern, Handler: handleFunc, Cache: vinegarUtil.NewLRU(defaultLruSize)} return &route } -func (s *VinegarServlet) AddRoute(route *VinegarRoute) { +func (s *VinegarHttpServlet) AddRoute(route *VinegarWebRoute) { route.Announce() s.Routes = append(s.Routes, route) } -func (s *VinegarServlet) AddErrorRoute(code int, route *TemplateRoute) { +func (s *VinegarHttpServlet) AddErrorRoute(code int, route *TemplateRoute) { route.Announce() s.ErrorRoutes[code] = route } -func (s *VinegarServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) { +func (s *VinegarHttpServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) { path := req.URL.Path for _, route := range s.Routes { if route.Pattern.MatchString(path) { @@ -84,7 +83,7 @@ func (s *VinegarServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) { s.SendError(w, req, 404, "Couldn't find your content.", errors.New("failed to match route for ["+path+"]")) } -func (s *VinegarServlet) Start() { +func (s *VinegarHttpServlet) Start() { if len(s.Routes) < 1 { log.Fatal("No routes found for server. Nothing to listen and serve.") os.Exit(1) @@ -100,11 +99,11 @@ func (s *VinegarServlet) Start() { } -func (r *VinegarRoute) Announce() { +func (r *VinegarWebRoute) Announce() { log.Printf("Added route for [%s]\n", r.Pattern.String()) } -func (s *VinegarServlet) SendError(w http.ResponseWriter, req *http.Request, code int, msg string, aErr error) { +func (s *VinegarHttpServlet) SendError(w http.ResponseWriter, req *http.Request, code int, msg string, aErr error) { fmt.Printf("[%d][%s]. Rendering template for code %d with message: %s\n", code, req.URL.Path, code, msg) fmt.Println(aErr) tmpl, exists := s.ErrorRoutes[code] diff --git a/servlet/staticRoute.go b/servlet/staticRoute.go index b79c390..94ccf1c 100644 --- a/servlet/staticRoute.go +++ b/servlet/staticRoute.go @@ -15,10 +15,10 @@ type ( FileRoute struct { // VinegarRoute is the base route containing the URL pattern and handler. - VinegarRoute *VinegarRoute + VinegarRoute *VinegarWebRoute - // srv is the VinegarServlet instance that this route is attached to. - srv *VinegarServlet + // srv is the VinegarHttpServlet instance that this route is attached to. + srv *VinegarHttpServlet // fileRoot is the base file path to serve files from. fileRoot string @@ -31,7 +31,7 @@ type ( // //Params: // - //servlet - The VinegarServlet instance to add the route to + //servlet - The VinegarHttpServlet instance to add the route to // //urlPattern - The URL regex pattern for route to match // @@ -39,13 +39,13 @@ type ( // //useCache - Whether to use caching for this route // - // A RouteConstructor is a function that accepts a VinegarServlet, urlPattern, file path, and cache option. It uses + // A RouteConstructor is a function that accepts a VinegarHttpServlet, urlPattern, file path, and cache option. It uses // these to construct and return a FileRoute. // The return value is a FileRoute that will serve the files from the given path. // // This function signature allows encapsulating the creation of different types of FileRoutes. It is used to define // constructor functions for each file type, like NewTextRoute or NewImageRoute. - RouteConstructor func(servlet *VinegarServlet, urlPattern string, pathlike string, useCache bool) *FileRoute + RouteConstructor func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) *FileRoute ) // NewTextRoute creates a new FileRoute for serving text files. @@ -54,7 +54,7 @@ type ( // // Parameters: // -// servlet - The VinegarServlet instance to attach the route to. +// servlet - The VinegarHttpServlet instance to attach the route to. // // urlPattern - The URL regex pattern that triggers this route. // @@ -65,8 +65,8 @@ type ( // Returns: // // A FileRoute instance configured for serving text files, added to -// the provided VinegarServlet. -var NewTextRoute RouteConstructor = func(servlet *VinegarServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { +// the provided VinegarHttpServlet. +var NewTextRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { fileRoot := filepath.Clean(pathlike) if strings.Contains(fileRoot, "../") { panic("Traversing the directory is not allowed, use an absolute filepath instead") @@ -82,7 +82,7 @@ var NewTextRoute RouteConstructor = func(servlet *VinegarServlet, urlPattern str return &route } -var NewImageRoute RouteConstructor = func(servlet *VinegarServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { +var NewImageRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { fileRoot := filepath.Clean(pathlike) if strings.Contains(fileRoot, "../") { panic("Traversing the directory is not allowed, use an absolute filepath instead") @@ -96,7 +96,7 @@ var NewImageRoute RouteConstructor = func(servlet *VinegarServlet, urlPattern st return &route } -var NewSingleFileRoute RouteConstructor = func(servlet *VinegarServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { +var NewSingleFileRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) *FileRoute { route := FileRoute{ srv: servlet, fileRoot: pathlike, diff --git a/servlet/templateRoute.go b/servlet/templateRoute.go index 7234879..0818c1c 100644 --- a/servlet/templateRoute.go +++ b/servlet/templateRoute.go @@ -7,8 +7,8 @@ import ( type ( TemplateRoute struct { - *VinegarRoute - srv *VinegarServlet + *VinegarWebRoute + srv *VinegarHttpServlet fileRoot string TemplateManager *TemplateManager UseCache bool @@ -16,12 +16,12 @@ type ( TemplateRouteHandlerFunc func(w http.ResponseWriter, r *http.Request, tm *TemplateManager) ) -func NewTemplateRoute(servlet *VinegarServlet, urlPattern string, templatePath string, componentPath string, handler TemplateRouteHandlerFunc) *TemplateRoute { +func NewTemplateRoute(servlet *VinegarHttpServlet, urlPattern string, templatePath string, componentPath string, handler TemplateRouteHandlerFunc) *TemplateRoute { defaultPrune := strings.Replace(urlPattern, ".*", "", -1) tm := NewTemplateManager(templatePath, componentPath) rootRoute := NewServletRoute(defaultPrune, createTemplateRouteFunction(tm, handler)) route := TemplateRoute{ - VinegarRoute: rootRoute, + VinegarWebRoute: rootRoute, srv: servlet, fileRoot: "", TemplateManager: tm,