VYPR
Low severity3.3NVD Advisory· Published Mar 26, 2026· Updated Apr 2, 2026

CVE-2026-33529

CVE-2026-33529

Description

Zoraxy is a general purpose HTTP reverse proxy and forwarding tool. Prior to version 3.3.2, an authenticated path traversal vulnerability in the configuration import endpoint allows an authenticated user to write arbitrary files outside the config directory, which can lead to RCE by creating a plugin. Version 3.3.2 patches the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/tobychui/zoraxyGo
< 3.3.23.3.2

Affected products

1
  • cpe:2.3:a:zoraxy:zoraxy:*:*:*:*:*:*:*:*
    Range: <3.3.2

Patches

1
69ac755aeec5

Update config unzip implementation

https://github.com/tobychui/zoraxyToby ChuiMar 14, 2026via ghsa
3 files changed · +27 13
  • .gitignore+1 0 modified
    @@ -66,3 +66,4 @@ www/html/index.html
     /build
     src/zoraxy.exe~
     /src/www
    +/src/conf.old_*
    
  • src/config.go+22 12 modified
    @@ -318,26 +318,35 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
     		}
     		defer rc.Close()
     
    -		// Create the corresponding file on disk
    -		zipFile.Name = strings.ReplaceAll(zipFile.Name, "../", "")
    -		fmt.Println("Restoring: " + strings.ReplaceAll(zipFile.Name, "\\", "/"))
    -		if zipFile.Name == "sys.db" {
    +		// Sanitize the file name to prevent path traversal (zip-slip)
    +		cleanedName := filepath.Clean(filepath.FromSlash(zipFile.Name))
    +		cleanedNameSlash := filepath.ToSlash(cleanedName)
    +		fmt.Println("Restoring: " + cleanedNameSlash)
    +		if cleanedNameSlash == "sys.db" {
     			//Sysdb replacement. Close the database and restore
     			sysdb.Close()
     			restoreDatabase = true
    -		} else if !strings.HasPrefix(strings.ReplaceAll(zipFile.Name, "\\", "/"), "conf/") {
    +		} else if !strings.HasPrefix(cleanedNameSlash, "conf/") {
     			//Malformed zip file.
    -			http.Error(w, fmt.Sprintf("Invalid zip file structure or version too old"), http.StatusInternalServerError)
    +			http.Error(w, "Invalid zip file structure or version too old", http.StatusInternalServerError)
    +			return
    +		}
    +
    +		// Resolve to absolute path and verify it stays within the target directory
    +		absTargetDir, _ := filepath.Abs(targetDir)
    +		absFilePath, _ := filepath.Abs(cleanedName)
    +		if cleanedNameSlash != "sys.db" && !strings.HasPrefix(absFilePath, absTargetDir+string(os.PathSeparator)) {
    +			http.Error(w, "Invalid file path in zip", http.StatusBadRequest)
     			return
     		}
     
     		//Check if parent dir exists
    -		if !utils.FileExists(filepath.Dir(zipFile.Name)) {
    -			os.MkdirAll(filepath.Dir(zipFile.Name), 0775)
    +		if !utils.FileExists(filepath.Dir(cleanedName)) {
    +			os.MkdirAll(filepath.Dir(cleanedName), 0775)
     		}
     
     		//Create the file
    -		newFile, err := os.Create(zipFile.Name)
    +		newFile, err := os.Create(cleanedName)
     		if err != nil {
     			http.Error(w, fmt.Sprintf("Failed to create file: %v", err), http.StatusInternalServerError)
     			return
    @@ -369,11 +378,12 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
     }
     
     func handleLoggerConfig(w http.ResponseWriter, r *http.Request) {
    -	if r.Method == http.MethodGet {
    +	switch r.Method {
    +	case http.MethodGet:
     		logger.HandleGetLogConfig(CONF_LOG_CONFIG)(w, r)
    -	} else if r.Method == http.MethodPost {
    +	case http.MethodPost:
     		logger.HandleUpdateLogConfig(CONF_LOG_CONFIG, SystemWideLogger)(w, r)
    -	} else {
    +	default:
     		utils.SendErrorResponse(w, "Method not allowed")
     	}
     }
    
  • src/mod/info/logviewer/logviewer.go+4 1 modified
    @@ -285,7 +285,10 @@ func (v *Viewer) senatizeLogFilenameInput(filename string) string {
     	filename = strings.TrimSuffix(filename, ".log.gz")
     	filename = strings.TrimSuffix(filename, ".log")
     	filename = filepath.ToSlash(filename)
    -	filename = strings.ReplaceAll(filename, "../", "")
    +	filename = filepath.Clean(filename)
    +	if strings.Contains(filename, "..") {
    +		return ""
    +	}
     	//Check if .log.gz or .log exists
     	if utils.FileExists(filepath.Join(v.option.RootFolder, filename+".log")) {
     		return filepath.Join(v.option.RootFolder, filename+".log")
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.