|
@@ -246,7 +246,30 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
|
|
if directDownload == true {
|
|
if directDownload == true {
|
|
if relpath != "" {
|
|
if relpath != "" {
|
|
//User specified a specific file within the directory. Escape the relpath
|
|
//User specified a specific file within the directory. Escape the relpath
|
|
- log.Println(shareOption.FileRealPath, relpath)
|
|
|
|
|
|
+ targetFilepath := filepath.Join(shareOption.FileRealPath, relpath)
|
|
|
|
+
|
|
|
|
+ //Check if file exists
|
|
|
|
+ if !fileExists(targetFilepath) {
|
|
|
|
+ http.NotFound(w, r)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Validate the absolute path to prevent path escape
|
|
|
|
+ absroot, _ := filepath.Abs(shareOption.FileRealPath)
|
|
|
|
+ abstarget, _ := filepath.Abs(targetFilepath)
|
|
|
|
+
|
|
|
|
+ if len(abstarget) <= len(absroot) || abstarget[:len(absroot)] != absroot {
|
|
|
|
+ //Directory escape detected
|
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
|
+ w.Write([]byte("400 - Bad Request: Invalid relative path"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Serve the target file
|
|
|
|
+ w.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''"+strings.ReplaceAll(url.QueryEscape(filepath.Base(targetFilepath)), "+", "%20"))
|
|
|
|
+ w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
|
|
|
|
+ http.ServeFile(w, r, targetFilepath)
|
|
|
|
+
|
|
sendOK(w)
|
|
sendOK(w)
|
|
} else {
|
|
} else {
|
|
//Download this folder as zip
|
|
//Download this folder as zip
|
|
@@ -329,16 +352,17 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
t := fasttemplate.New(string(content), "{{", "}}")
|
|
t := fasttemplate.New(string(content), "{{", "}}")
|
|
s := t.ExecuteString(map[string]interface{}{
|
|
s := t.ExecuteString(map[string]interface{}{
|
|
- "hostname": s.options.HostName,
|
|
|
|
- "reqid": id,
|
|
|
|
- "mime": "application/x-directory",
|
|
|
|
- "size": filesystem.GetFileDisplaySize(fsize, 2),
|
|
|
|
- "filecount": strconv.Itoa(fcount),
|
|
|
|
- "modtime": timeString,
|
|
|
|
- "downloadurl": "/share?id=" + id + "&download=true",
|
|
|
|
- "filename": filepath.Base(shareOption.FileRealPath),
|
|
|
|
- "reqtime": strconv.Itoa(int(time.Now().Unix())),
|
|
|
|
- "treelist": tl,
|
|
|
|
|
|
+ "hostname": s.options.HostName,
|
|
|
|
+ "reqid": id,
|
|
|
|
+ "mime": "application/x-directory",
|
|
|
|
+ "size": filesystem.GetFileDisplaySize(fsize, 2),
|
|
|
|
+ "filecount": strconv.Itoa(fcount),
|
|
|
|
+ "modtime": timeString,
|
|
|
|
+ "downloadurl": "./share?id=" + id + "&download=true",
|
|
|
|
+ "filename": filepath.Base(shareOption.FileRealPath),
|
|
|
|
+ "reqtime": strconv.Itoa(int(time.Now().Unix())),
|
|
|
|
+ "treelist": tl,
|
|
|
|
+ "downloaduuid": id,
|
|
})
|
|
})
|
|
|
|
|
|
w.Write([]byte(s))
|
|
w.Write([]byte(s))
|