Skip to content

Commit 69ac755

Browse files
committed
Update config unzip implementation
1 parent 515905f commit 69ac755

3 files changed

Lines changed: 27 additions & 13 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ www/html/index.html
6666
/build
6767
src/zoraxy.exe~
6868
/src/www
69+
/src/conf.old_*

src/config.go

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,26 +318,35 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
318318
}
319319
defer rc.Close()
320320

321-
// Create the corresponding file on disk
322-
zipFile.Name = strings.ReplaceAll(zipFile.Name, "../", "")
323-
fmt.Println("Restoring: " + strings.ReplaceAll(zipFile.Name, "\\", "/"))
324-
if zipFile.Name == "sys.db" {
321+
// Sanitize the file name to prevent path traversal (zip-slip)
322+
cleanedName := filepath.Clean(filepath.FromSlash(zipFile.Name))
323+
cleanedNameSlash := filepath.ToSlash(cleanedName)
324+
fmt.Println("Restoring: " + cleanedNameSlash)
325+
if cleanedNameSlash == "sys.db" {
325326
//Sysdb replacement. Close the database and restore
326327
sysdb.Close()
327328
restoreDatabase = true
328-
} else if !strings.HasPrefix(strings.ReplaceAll(zipFile.Name, "\\", "/"), "conf/") {
329+
} else if !strings.HasPrefix(cleanedNameSlash, "conf/") {
329330
//Malformed zip file.
330-
http.Error(w, fmt.Sprintf("Invalid zip file structure or version too old"), http.StatusInternalServerError)
331+
http.Error(w, "Invalid zip file structure or version too old", http.StatusInternalServerError)
332+
return
333+
}
334+
335+
// Resolve to absolute path and verify it stays within the target directory
336+
absTargetDir, _ := filepath.Abs(targetDir)
337+
absFilePath, _ := filepath.Abs(cleanedName)
338+
if cleanedNameSlash != "sys.db" && !strings.HasPrefix(absFilePath, absTargetDir+string(os.PathSeparator)) {
339+
http.Error(w, "Invalid file path in zip", http.StatusBadRequest)
331340
return
332341
}
333342

334343
//Check if parent dir exists
335-
if !utils.FileExists(filepath.Dir(zipFile.Name)) {
336-
os.MkdirAll(filepath.Dir(zipFile.Name), 0775)
344+
if !utils.FileExists(filepath.Dir(cleanedName)) {
345+
os.MkdirAll(filepath.Dir(cleanedName), 0775)
337346
}
338347

339348
//Create the file
340-
newFile, err := os.Create(zipFile.Name)
349+
newFile, err := os.Create(cleanedName)
341350
if err != nil {
342351
http.Error(w, fmt.Sprintf("Failed to create file: %v", err), http.StatusInternalServerError)
343352
return
@@ -369,11 +378,12 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
369378
}
370379

371380
func handleLoggerConfig(w http.ResponseWriter, r *http.Request) {
372-
if r.Method == http.MethodGet {
381+
switch r.Method {
382+
case http.MethodGet:
373383
logger.HandleGetLogConfig(CONF_LOG_CONFIG)(w, r)
374-
} else if r.Method == http.MethodPost {
384+
case http.MethodPost:
375385
logger.HandleUpdateLogConfig(CONF_LOG_CONFIG, SystemWideLogger)(w, r)
376-
} else {
386+
default:
377387
utils.SendErrorResponse(w, "Method not allowed")
378388
}
379389
}

src/mod/info/logviewer/logviewer.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,10 @@ func (v *Viewer) senatizeLogFilenameInput(filename string) string {
285285
filename = strings.TrimSuffix(filename, ".log.gz")
286286
filename = strings.TrimSuffix(filename, ".log")
287287
filename = filepath.ToSlash(filename)
288-
filename = strings.ReplaceAll(filename, "../", "")
288+
filename = filepath.Clean(filename)
289+
if strings.Contains(filename, "..") {
290+
return ""
291+
}
289292
//Check if .log.gz or .log exists
290293
if utils.FileExists(filepath.Join(v.option.RootFolder, filename+".log")) {
291294
return filepath.Join(v.option.RootFolder, filename+".log")

0 commit comments

Comments
 (0)