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

dahn pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 0edd577f4bb8a071cbc8c8bb066fa26e6b634101
Author: dahn <[email protected]>
AuthorDate: Fri Feb 20 17:27:34 2026 +0100

    Fix: KVM Direct Download URL injection
---
 .../direct/download/DirectTemplateDownloaderImpl.java         | 11 ++++++-----
 .../direct/download/MetalinkDirectTemplateDownloader.java     |  2 +-
 .../direct/download/NfsDirectTemplateDownloader.java          |  2 +-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git 
a/core/src/main/java/org/apache/cloudstack/direct/download/DirectTemplateDownloaderImpl.java
 
b/core/src/main/java/org/apache/cloudstack/direct/download/DirectTemplateDownloaderImpl.java
index a1485463eaa..05619e5632b 100644
--- 
a/core/src/main/java/org/apache/cloudstack/direct/download/DirectTemplateDownloaderImpl.java
+++ 
b/core/src/main/java/org/apache/cloudstack/direct/download/DirectTemplateDownloaderImpl.java
@@ -21,6 +21,7 @@ package org.apache.cloudstack.direct.download;
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.cloudstack.utils.security.DigestHelper;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
@@ -33,6 +34,7 @@ import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 public abstract class DirectTemplateDownloaderImpl implements 
DirectTemplateDownloader {
 
@@ -128,15 +130,14 @@ public abstract class DirectTemplateDownloaderImpl 
implements DirectTemplateDown
      */
     protected File createTemporaryDirectoryAndFile(String downloadDir) {
         createFolder(downloadDir);
-        return new File(downloadDir + File.separator + getFileNameFromUrl());
+        return new File(downloadDir + File.separator + getTemporaryFileName());
     }
 
     /**
-     * Return filename from url
+     * Return filename from the temporary download file
      */
-    public String getFileNameFromUrl() {
-        String[] urlParts = url.split("/");
-        return urlParts[urlParts.length - 1];
+    public String getTemporaryFileName() {
+        return String.format("%s.%s", UUID.randomUUID(), 
FilenameUtils.getExtension(url));
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/cloudstack/direct/download/MetalinkDirectTemplateDownloader.java
 
b/core/src/main/java/org/apache/cloudstack/direct/download/MetalinkDirectTemplateDownloader.java
index 2050b9ef09f..854c310cde9 100644
--- 
a/core/src/main/java/org/apache/cloudstack/direct/download/MetalinkDirectTemplateDownloader.java
+++ 
b/core/src/main/java/org/apache/cloudstack/direct/download/MetalinkDirectTemplateDownloader.java
@@ -97,7 +97,7 @@ public class MetalinkDirectTemplateDownloader extends 
DirectTemplateDownloaderIm
             DirectTemplateDownloader urlDownloader = 
createDownloaderForMetalinks(getUrl(), getTemplateId(), getDestPoolPath(),
                     getChecksum(), headers, connectTimeout, soTimeout, null, 
temporaryDownloadPath);
             try {
-                setDownloadedFilePath(downloadDir + File.separator + 
getFileNameFromUrl());
+                setDownloadedFilePath(downloadDir + File.separator + 
getTemporaryFileName());
                 File f = new File(getDownloadedFilePath());
                 if (f.exists()) {
                     f.delete();
diff --git 
a/core/src/main/java/org/apache/cloudstack/direct/download/NfsDirectTemplateDownloader.java
 
b/core/src/main/java/org/apache/cloudstack/direct/download/NfsDirectTemplateDownloader.java
index 21184ef07fe..6b0959b78ff 100644
--- 
a/core/src/main/java/org/apache/cloudstack/direct/download/NfsDirectTemplateDownloader.java
+++ 
b/core/src/main/java/org/apache/cloudstack/direct/download/NfsDirectTemplateDownloader.java
@@ -69,7 +69,7 @@ public class NfsDirectTemplateDownloader extends 
DirectTemplateDownloaderImpl {
         String mount = String.format(mountCommand, srcHost + ":" + srcPath, 
"/mnt/" + mountSrcUuid);
         Script.runSimpleBashScript(mount);
         String downloadDir = getDestPoolPath() + File.separator + 
getDirectDownloadTempPath(getTemplateId());
-        setDownloadedFilePath(downloadDir + File.separator + 
getFileNameFromUrl());
+        setDownloadedFilePath(downloadDir + File.separator + 
getTemporaryFileName());
         Script.runSimpleBashScript("cp /mnt/" + mountSrcUuid + srcPath + " " + 
getDownloadedFilePath());
         Script.runSimpleBashScript("umount /mnt/" + mountSrcUuid);
         return new Pair<>(true, getDownloadedFilePath());

Reply via email to