@@ -52,6 +52,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5252 }
5353}
5454
55+ // sanitizeRedirectPath ensures redirect targets do not lead to open redirects.
56+ func sanitizeRedirectPath (p string ) string {
57+ if len (p ) > 1 && p [0 ] == '/' && p [1 ] != '/' && p [1 ] != '\\' {
58+ return p
59+ }
60+ return "/"
61+ }
62+
5563func (h * Handler ) serveGet (w http.ResponseWriter , r * http.Request , log * slog.Logger ) {
5664 path := r .URL .Path
5765 if strings .HasSuffix (path , "/" ) {
@@ -70,14 +78,14 @@ func (h *Handler) serveGet(w http.ResponseWriter, r *http.Request, log *slog.Log
7078 // Can't get the entrypoint, but since it's a directory
7179 // (only with unsaved changes), redirect to the directory itself
7280 // that will in the end load the index file if present.
73- http .Redirect (w , r , r .URL .Path + "/" , http .StatusTemporaryRedirect )
81+ http .Redirect (w , r , sanitizeRedirectPath ( r .URL .Path + "/" ) , http .StatusTemporaryRedirect )
7482 return
7583 case h .handleHTTPError (err , w , log , "Error finding entrypoint" ):
7684 return
7785 }
7886
7987 if fileEP .IsDir () {
80- http .Redirect (w , r , r .URL .Path + "/" , http .StatusTemporaryRedirect )
88+ http .Redirect (w , r , sanitizeRedirectPath ( r .URL .Path + "/" ) , http .StatusTemporaryRedirect )
8189 return
8290 }
8391
0 commit comments