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