|
28 | 28 | import java.nio.ByteBuffer; |
29 | 29 | import java.nio.file.Files; |
30 | 30 | import java.nio.file.Path; |
| 31 | +import java.nio.file.Paths; |
31 | 32 | import java.nio.file.StandardCopyOption; |
32 | 33 | import java.nio.file.StandardOpenOption; |
33 | 34 | import java.util.HashMap; |
@@ -92,6 +93,14 @@ public static Map<String, Object> addMultipleuploadForProduct(DispatchContext dc |
92 | 93 | "image.management.path", delegator), context); |
93 | 94 | String imageServerUrl = FlexibleStringExpander.expandString(EntityUtilProperties.getPropertyValue("catalog", |
94 | 95 | "image.management.url", delegator), context); |
| 96 | + // Guard against path traversal via productId |
| 97 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 98 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 99 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 100 | + Debug.logError("Path traversal attempt detected in image management upload, productId: " + productId, MODULE); |
| 101 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 102 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale)); |
| 103 | + } |
95 | 104 | String rootTargetDirectory = imageServerPath; |
96 | 105 | File rootTargetDir = new File(rootTargetDirectory); |
97 | 106 | if (!rootTargetDir.exists()) { |
@@ -306,11 +315,20 @@ public static Map<String, Object> removeImageFileForImageManagement(DispatchCont |
306 | 315 | String contentId = (String) context.get("contentId"); |
307 | 316 | String dataResourceName = (String) context.get("dataResourceName"); |
308 | 317 | Delegator delegator = dctx.getDelegator(); |
| 318 | + Locale locale = (Locale) context.get("locale"); |
309 | 319 |
|
310 | 320 | try { |
311 | 321 | if (UtilValidate.isNotEmpty(contentId)) { |
312 | 322 | String imageServerPath = FlexibleStringExpander.expandString(EntityUtilProperties.getPropertyValue("catalog", |
313 | 323 | "image.management.path", delegator), context); |
| 324 | + // Guard against path traversal via productId or dataResourceName |
| 325 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 326 | + Path resolvedFilePath = Paths.get(imageServerPath, productId, dataResourceName).normalize(); |
| 327 | + if (!resolvedFilePath.startsWith(imageServerNormalizedPath)) { |
| 328 | + Debug.logError("Path traversal attempt detected in image management remove, productId: " + productId, MODULE); |
| 329 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 330 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedFilePath.toString()), locale)); |
| 331 | + } |
314 | 332 | File file = new File(imageServerPath + "/" + productId + "/" + dataResourceName); |
315 | 333 | if (!file.delete()) { |
316 | 334 | Debug.logError("File :" + file.getName() + ", couldn't be deleted", MODULE); |
@@ -369,7 +387,16 @@ private static Map<String, Object> scaleImageMangementInAllSize(DispatchContext |
369 | 387 | "image.management.path", dctx.getDelegator()), context); |
370 | 388 | String imageServerUrl = FlexibleStringExpander.expandString(EntityUtilProperties.getPropertyValue("catalog", |
371 | 389 | "image.management.url", dctx.getDelegator()), context); |
372 | | - |
| 390 | + // Guard against path traversal via productId |
| 391 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 392 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 393 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 394 | + Debug.logError("Path traversal attempt detected in image management scale, productId: " + productId, MODULE); |
| 395 | + String errMsg = UtilProperties.getMessage(RES_ERROR, |
| 396 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale); |
| 397 | + result.put(ModelService.ERROR_MESSAGE, errMsg); |
| 398 | + return result; |
| 399 | + } |
373 | 400 |
|
374 | 401 | /* get original BUFFERED IMAGE */ |
375 | 402 | resultBufImgMap.putAll(ImageTransform.getBufferedImage(imageServerPath + "/" + productId + "/" + filenameToUse, locale)); |
@@ -536,6 +563,14 @@ public static Map<String, Object> createContentThumbnail(DispatchContext dctx, M |
536 | 563 | "image.management.path", delegator), context); |
537 | 564 | String nameOfThumb = FlexibleStringExpander.expandString(EntityUtilProperties.getPropertyValue("catalog", |
538 | 565 | "image.management.nameofthumbnail", delegator), context); |
| 566 | + // Guard against path traversal via productId |
| 567 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 568 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 569 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 570 | + Debug.logError("Path traversal attempt detected in image management thumbnail, productId: " + productId, MODULE); |
| 571 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 572 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale)); |
| 573 | + } |
539 | 574 |
|
540 | 575 | // Create content for thumbnail |
541 | 576 | Map<String, Object> contentThumb = new HashMap<>(); |
@@ -729,6 +764,14 @@ public static Map<String, Object> createNewImageThumbnail(DispatchContext dctx, |
729 | 764 | String contentId = (String) context.get("contentId"); |
730 | 765 | String dataResourceName = (String) context.get("dataResourceName"); |
731 | 766 | String width = (String) context.get("sizeWidth"); |
| 767 | + // Guard against path traversal via productId |
| 768 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 769 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 770 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 771 | + Debug.logError("Path traversal attempt detected in create new image thumbnail, productId: " + productId, MODULE); |
| 772 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 773 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale)); |
| 774 | + } |
732 | 775 | String imageType = ".jpg"; |
733 | 776 | int resizeWidth = Integer.parseInt(width); |
734 | 777 | int resizeHeight = resizeWidth; |
@@ -801,6 +844,14 @@ public static Map<String, Object> resizeImageOfProduct(DispatchContext dctx, Map |
801 | 844 | String width = (String) context.get("resizeWidth"); |
802 | 845 | int resizeWidth = Integer.parseInt(width); |
803 | 846 | int resizeHeight = resizeWidth; |
| 847 | + // Guard against path traversal via productId |
| 848 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 849 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 850 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 851 | + Debug.logError("Path traversal attempt detected in resize image, productId: " + productId, MODULE); |
| 852 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 853 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale)); |
| 854 | + } |
804 | 855 |
|
805 | 856 | try { |
806 | 857 | BufferedImage bufImg = ImageIO.read(new File(imageServerPath + "/" + productId + "/" + dataResourceName)); |
@@ -831,6 +882,14 @@ public static Map<String, Object> renameImage(DispatchContext dctx, Map<String, |
831 | 882 | String productId = (String) context.get("productId"); |
832 | 883 | String contentId = (String) context.get("contentId"); |
833 | 884 | String filenameToUse = (String) context.get("drDataResourceName"); |
| 885 | + // Guard against path traversal via productId |
| 886 | + Path imageServerNormalizedPath = Paths.get(imageServerPath).normalize(); |
| 887 | + Path resolvedProductDir = Paths.get(imageServerPath, productId).normalize(); |
| 888 | + if (!resolvedProductDir.startsWith(imageServerNormalizedPath)) { |
| 889 | + Debug.logError("Path traversal attempt detected in rename image, productId: " + productId, MODULE); |
| 890 | + return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, |
| 891 | + "ProductImageViewUnableWriteFile", UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale)); |
| 892 | + } |
834 | 893 | String imageType = filenameToUse.substring(filenameToUse.lastIndexOf('.')); |
835 | 894 | String imgExtension = filenameToUse.substring(filenameToUse.length() - 3, filenameToUse.length()); |
836 | 895 | String imageUrl = imageServerUrl + "/" + productId + "/" + filenameToUse; |
|
0 commit comments