Skip to content

Commit

Permalink
Added utils to verify paths
Browse files Browse the repository at this point in the history
  • Loading branch information
stratic-dev committed Mar 15, 2024
1 parent d123182 commit 295ff65
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 35 deletions.
86 changes: 51 additions & 35 deletions server/api/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,28 +297,36 @@ func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) {
}
func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
// Get the 'id' parameter from the URL
vars := mux.Vars(r)
token := vars["id"]
token := mux.Vars(r)["id"]
var tokenPattern = regexp.MustCompile(`[A-Za-z0-9]+`)

if !tokenPattern.MatchString(token) || token == "" {
http.Error(w, "Not Valid Token", http.StatusBadRequest)

}
// Open the image file
path := filepath.Join(s.erupeConfig.Screenshots.OutputDir, fmt.Sprintf("%s.jpg", token))
file, err := os.Open(path)
safePath := s.erupeConfig.Screenshots.OutputDir
path := filepath.Join(safePath, fmt.Sprintf("%s.jpg", token))
result, err := verifyPath(path, safePath)

if err != nil {
http.Error(w, "Image not found", http.StatusNotFound)
return
}
defer file.Close()
// Set content type header to image/jpeg
w.Header().Set("Content-Type", "image/jpeg")
// Copy the image content to the response writer
if _, err := io.Copy(w, file); err != nil {
http.Error(w, "Unable to send image", http.StatusInternalServerError)
return
fmt.Println("Error " + err.Error())
} else {
fmt.Println("Canonical: " + result)

file, err := os.Open(result)

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
if err != nil {
http.Error(w, "Image not found", http.StatusNotFound)
return
}
defer file.Close()
// Set content type header to image/jpeg
w.Header().Set("Content-Type", "image/jpeg")
// Copy the image content to the response writer
if _, err := io.Copy(w, file); err != nil {
http.Error(w, "Unable to send image", http.StatusInternalServerError)
return
}
}
}
func (s *APIServer) ScreenShot(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -355,33 +363,41 @@ func (s *APIServer) ScreenShot(w http.ResponseWriter, r *http.Request) {
result = Result{Code: "400"}
}

dir := filepath.Join(s.erupeConfig.Screenshots.OutputDir)
path := filepath.Join(s.erupeConfig.Screenshots.OutputDir, fmt.Sprintf("%s.jpg", token))
_, err = os.Stat(dir)
safePath := s.erupeConfig.Screenshots.OutputDir

path := filepath.Join(safePath, fmt.Sprintf("%s.jpg", token))
verified, err := verifyPath(path, safePath)

if err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(dir, os.ModePerm)
if err != nil {
s.logger.Error("Error writing screenshot, could not create folder")
result = Result{Code: "500"}
} else {

_, err = os.Stat(safePath)
if err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(safePath, os.ModePerm)
if err != nil {
s.logger.Error("Error writing screenshot, could not create folder")
result = Result{Code: "500"}
}
} else {
s.logger.Error("Error writing screenshot")
result = Result{Code: "500"}
}
} else {
s.logger.Error("Error writing screenshot")
}
// Create or open the output file
outputFile, err := os.Create(verified)

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
if err != nil {
result = Result{Code: "500"}
}
}
// Create or open the output file
outputFile, err := os.Create(path)
if err != nil {
result = Result{Code: "500"}
}
defer outputFile.Close()
defer outputFile.Close()

// Encode the image and write it to the file
err = jpeg.Encode(outputFile, img, &jpeg.Options{Quality: s.erupeConfig.Screenshots.UploadQuality})
if err != nil {
s.logger.Error("Error writing screenshot, could not write file", zap.Error(err))
result = Result{Code: "500"}
// Encode the image and write it to the file
err = jpeg.Encode(outputFile, img, &jpeg.Options{Quality: s.erupeConfig.Screenshots.UploadQuality})
if err != nil {
s.logger.Error("Error writing screenshot, could not write file", zap.Error(err))
result = Result{Code: "500"}
}
}
}
// Marshal the struct into XML
Expand Down
37 changes: 37 additions & 0 deletions server/api/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package api

import (
"errors"
"fmt"
"path/filepath"
)

func inTrustedRoot(path string, trustedRoot string) error {
for path != "/" {
path = filepath.Dir(path)
if path == trustedRoot {
return nil
}
}
return errors.New("path is outside of trusted root")
}

func verifyPath(path string, trustedRoot string) (string, error) {

c := filepath.Clean(path)
fmt.Println("Cleaned path: " + c)

r, err := filepath.EvalSymlinks(c)
if err != nil {
fmt.Println("Error " + err.Error())
return c, errors.New("Unsafe or invalid path specified")
}

err = inTrustedRoot(r, trustedRoot)
if err != nil {
fmt.Println("Error " + err.Error())
return r, errors.New("Unsafe or invalid path specified")
} else {
return r, nil
}
}

0 comments on commit 295ff65

Please sign in to comment.