From ce3ce7e6fda17e226aa5a75ca672217b887e5b00 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Wed, 25 Sep 2024 12:58:30 -0700 Subject: [PATCH] Rename fileName to path to try and appease CodeQL (#852) --- pkg/wavebase/wavebase.go | 6 +++--- pkg/web/web.go | 42 +++++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/pkg/wavebase/wavebase.go b/pkg/wavebase/wavebase.go index e22434a5c..4eef981a9 100644 --- a/pkg/wavebase/wavebase.go +++ b/pkg/wavebase/wavebase.go @@ -53,16 +53,16 @@ func GetHomeDir() string { func ExpandHomeDir(pathStr string) (string, error) { if pathStr != "~" && !strings.HasPrefix(pathStr, "~/") { - return pathStr, nil + return filepath.Clean(pathStr), nil } homeDir := GetHomeDir() if pathStr == "~" { return homeDir, nil } - expandedPath := filepath.Join(homeDir, pathStr[2:]) + expandedPath := filepath.Clean(filepath.Join(homeDir, pathStr[2:])) absPath, err := filepath.Abs(filepath.Join(homeDir, expandedPath)) if err != nil || !strings.HasPrefix(absPath, homeDir) { - return "", fmt.Errorf("Potential path traversal detected for path %s", pathStr) + return "", fmt.Errorf("potential path traversal detected for path %s", pathStr) } return expandedPath, nil } diff --git a/pkg/web/web.go b/pkg/web/web.go index 83407dff7..9af8cadd4 100644 --- a/pkg/web/web.go +++ b/pkg/web/web.go @@ -218,30 +218,36 @@ func serveTransparentGIF(w http.ResponseWriter) { w.Write(gifBytes) } -func handleLocalStreamFile(w http.ResponseWriter, r *http.Request, fileName string, no404 bool) { +func handleLocalStreamFile(w http.ResponseWriter, r *http.Request, path string, no404 bool) { if no404 { - log.Printf("streaming file w/no404: %q\n", fileName) + log.Printf("streaming file w/no404: %q\n", path) // use the custom response writer rw := ¬FoundBlockingResponseWriter{w: w, headers: http.Header{}} + // Serve the file using http.ServeFile - http.ServeFile(rw, r, filepath.Clean(fileName)) - // if the file was not found, serve the transparent GIF - log.Printf("got streamfile status: %d\n", rw.status) - if rw.status == http.StatusNotFound { + path, err := wavebase.ExpandHomeDir(path) + if err == nil { + http.ServeFile(rw, r, filepath.Clean(path)) + // if the file was not found, serve the transparent GIF + log.Printf("got streamfile status: %d\n", rw.status) + if rw.status == http.StatusNotFound { + serveTransparentGIF(w) + } + } else { serveTransparentGIF(w) } } else { - fileName, err := wavebase.ExpandHomeDir(fileName) + path, err := wavebase.ExpandHomeDir(path) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) } - http.ServeFile(w, r, fileName) + http.ServeFile(w, r, path) } } -func handleRemoteStreamFile(w http.ResponseWriter, r *http.Request, conn string, fileName string, no404 bool) error { +func handleRemoteStreamFile(w http.ResponseWriter, r *http.Request, conn string, path string, no404 bool) error { client := wshserver.GetMainRpcClient() - streamFileData := wshrpc.CommandRemoteStreamFileData{Path: fileName} + streamFileData := wshrpc.CommandRemoteStreamFileData{Path: path} route := wshutil.MakeConnectionRouteId(conn) rtnCh := wshclient.RemoteStreamFileCommand(client, streamFileData, &wshrpc.RpcOpts{Route: route}) firstPk := true @@ -272,11 +278,11 @@ func handleRemoteStreamFile(w http.ResponseWriter, r *http.Request, conn string, serveTransparentGIF(w) return nil } else { - return fmt.Errorf("file not found: %q", fileName) + return fmt.Errorf("file not found: %q", path) } } if fileInfo.IsDir { - return fmt.Errorf("cannot stream directory: %q", fileName) + return fmt.Errorf("cannot stream directory: %q", path) } w.Header().Set(ContentTypeHeaderKey, fileInfo.MimeType) w.Header().Set(ContentLengthHeaderKey, fmt.Sprintf("%d", fileInfo.Size)) @@ -288,7 +294,7 @@ func handleRemoteStreamFile(w http.ResponseWriter, r *http.Request, conn string, decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewReader([]byte(respUnion.Response.Data64))) _, err := io.Copy(w, decoder) if err != nil { - log.Printf("error streaming file %q: %v\n", fileName, err) + log.Printf("error streaming file %q: %v\n", path, err) // not sure what to do here, the headers have already been sent. // just return return nil @@ -303,18 +309,18 @@ func handleStreamFile(w http.ResponseWriter, r *http.Request) { if conn == "" { conn = wshrpc.LocalConnName } - fileName := r.URL.Query().Get("path") - if fileName == "" { + path := r.URL.Query().Get("path") + if path == "" { http.Error(w, "path is required", http.StatusBadRequest) return } no404 := r.URL.Query().Get("no404") if conn == wshrpc.LocalConnName { - handleLocalStreamFile(w, r, fileName, no404 != "") + handleLocalStreamFile(w, r, path, no404 != "") } else { - err := handleRemoteStreamFile(w, r, conn, fileName, no404 != "") + err := handleRemoteStreamFile(w, r, conn, path, no404 != "") if err != nil { - log.Printf("error streaming remote file %q %q: %v\n", conn, fileName, err) + log.Printf("error streaming remote file %q %q: %v\n", conn, path, err) http.Error(w, fmt.Sprintf("error streaming file: %v", err), http.StatusInternalServerError) } }