You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by th...@apache.org on 2026/03/30 15:47:58 UTC

(incubator-kie-tools) branch main updated: kie-issues#2275: Fixes for CWE-22 Path/Directory Traversal on dev-deployment-upload-service (#3509)

This is an automated email from the ASF dual-hosted git repository.

thiagoelg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new 50d7118ecc8 kie-issues#2275: Fixes for CWE-22 Path/Directory Traversal on dev-deployment-upload-service (#3509)
50d7118ecc8 is described below

commit 50d7118ecc8ce7fc59e1844e86f1c2f622674d8a
Author: Thiago Lugli <th...@users.noreply.github.com>
AuthorDate: Mon Mar 30 12:47:53 2026 -0300

    kie-issues#2275: Fixes for CWE-22 Path/Directory Traversal on dev-deployment-upload-service (#3509)
---
 packages/dev-deployment-upload-service/main.go | 58 ++++++++++++++++----------
 1 file changed, 35 insertions(+), 23 deletions(-)

diff --git a/packages/dev-deployment-upload-service/main.go b/packages/dev-deployment-upload-service/main.go
index c09cdc07a58..2a107c8f67d 100644
--- a/packages/dev-deployment-upload-service/main.go
+++ b/packages/dev-deployment-upload-service/main.go
@@ -84,16 +84,23 @@ func main() {
 		os.Exit(1)
 	}
 
-	unzipAtPath := unzipAtArgString
+	// Validate and sanitize --unzip-at to prevent path traversal (CWE-22)
+	// Convert to absolute path and clean it
+	unzipAtPath, err := filepath.Abs(filepath.Clean(unzipAtArgString))
+	if err != nil {
+		fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Invalid path '%s': %+v\n", unzipAtArgString, err)
+		os.Exit(1)
+	}
+
 	// Validate --unzip-at
-	if _, err := os.Stat(unzipAtArgString); err == nil {
-		fmt.Fprintf(os.Stdout, LOG_PREFIX+"✅ Found directory '%s'.\n", unzipAtArgString)
-	} else if err := os.MkdirAll(filepath.Clean(unzipAtArgString), os.ModePerm); err != nil { // os.ModePerm == chmod 777
-		fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Creating directory '%s' failed:\n", unzipAtArgString)
+	if _, err := os.Stat(unzipAtPath); err == nil {
+		fmt.Fprintf(os.Stdout, LOG_PREFIX+"✅ Found directory '%s'.\n", unzipAtPath)
+	} else if err := os.MkdirAll(unzipAtPath, os.ModePerm); err != nil { // os.ModePerm == chmod 777
+		fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Creating directory '%s' failed:\n", unzipAtPath)
 		fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
 		os.Exit(1)
 	} else {
-		fmt.Fprintf(os.Stdout, LOG_PREFIX+"✅ Created directory '%s'.\n", unzipAtArgString)
+		fmt.Fprintf(os.Stdout, LOG_PREFIX+"✅ Created directory '%s'.\n", unzipAtPath)
 	}
 
 	// All validations passed. Start the program.
@@ -201,25 +208,33 @@ func main() {
 		}
 
 		for _, zipFile := range zipReader.File {
-			unzippedFileBytes, err := readZipFile(zipFile)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Reading zipped file '%s' failed:\n", zipFile.Name)
-				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
-				w.WriteHeader(http.StatusInternalServerError)
-				w.Write([]byte("500: Reading zipped file. " + html.EscapeString(zipFile.Name)))
 
-				shutdownWithErrorOnFileUpload(handler.Filename)
+			// [CWE-22: Path/Directory Traversal] Refuse symlinks before doing anything else with the entry
+			if zipFile.FileInfo().Mode()&os.ModeSymlink != 0 {
+				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Refusing to extract symlink entry '%s'.\n", zipFile.Name)
+				w.WriteHeader(http.StatusBadRequest)
+				w.Write([]byte("400: Zip contains symlink entries, which are not permitted."))
+				shutdownWithErrorOnFileUpload(zipFile.Name)
 				return
 			}
 
-			// Check for Zip Slip (directory traversal)
+			// [CWE-22: Path/Directory Traversal] Zip slip check
 			extractedZippedFilePath := filepath.Join(unzipAtPath, zipFile.Name)
 			if !strings.HasPrefix(extractedZippedFilePath, filepath.Clean(unzipAtPath)+string(os.PathSeparator)) {
 				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Illegal zipped file path '%s'.\n", zipFile.Name)
-				w.WriteHeader(http.StatusInternalServerError)
-				w.Write([]byte("500: Illegal zipped file path. " + html.EscapeString(extractedZippedFilePath)))
+				w.WriteHeader(http.StatusBadRequest)
+				w.Write([]byte("400: Illegal zipped file path. " + html.EscapeString(zipFile.Name)))
+				shutdownWithErrorOnFileUpload(zipFile.Name)
+				return
+			}
 
-				shutdownWithErrorOnFileUpload(handler.Filename)
+			unzippedFileBytes, err := readZipFile(zipFile)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: Reading zipped file '%s' failed:\n", zipFile.Name)
+				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
+				w.WriteHeader(http.StatusInternalServerError)
+				w.Write([]byte("500: Reading zipped file. " + html.EscapeString(zipFile.Name)))
+				shutdownWithErrorOnFileUpload(zipFile.Name)
 				return
 			}
 
@@ -229,8 +244,7 @@ func main() {
 				fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
 				w.WriteHeader(http.StatusInternalServerError)
 				w.Write([]byte("500: Creating directory failed. " + html.EscapeString(filepath.Dir(extractedZippedFilePath))))
-
-				shutdownWithErrorOnFileUpload(handler.Filename)
+				shutdownWithErrorOnFileUpload(zipFile.Name)
 				return
 			}
 
@@ -242,8 +256,7 @@ func main() {
 					fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
 					w.WriteHeader(http.StatusInternalServerError)
 					w.Write([]byte("500: Creating file failed. " + html.EscapeString(extractedZippedFilePath)))
-
-					shutdownWithErrorOnFileUpload(handler.Filename)
+					shutdownWithErrorOnFileUpload(zipFile.Name)
 					return
 				}
 				if _, err := f.Write(unzippedFileBytes); err != nil {
@@ -251,8 +264,7 @@ func main() {
 					fmt.Fprintf(os.Stderr, LOG_PREFIX+"❌ ERROR: %+v\n", err)
 					w.WriteHeader(http.StatusInternalServerError)
 					w.Write([]byte("500: Writing file failed. " + html.EscapeString(extractedZippedFilePath)))
-
-					shutdownWithErrorOnFileUpload(handler.Filename)
+					shutdownWithErrorOnFileUpload(zipFile.Name)
 					return
 				}
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org