From 7f9400fe239b1dc47d97b83dbdf8a57a2362f083 Mon Sep 17 00:00:00 2001 From: dkayiwa Date: Thu, 21 Nov 2024 02:24:31 +0300 Subject: [PATCH] Validate image file contents --- .../attachments/AttachmentsContext.java | 3 +- .../attachments/rest/AttachmentResource.java | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/openmrs/module/attachments/AttachmentsContext.java b/api/src/main/java/org/openmrs/module/attachments/AttachmentsContext.java index d5081fd..8b74628 100644 --- a/api/src/main/java/org/openmrs/module/attachments/AttachmentsContext.java +++ b/api/src/main/java/org/openmrs/module/attachments/AttachmentsContext.java @@ -17,6 +17,7 @@ import java.util.Map; import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -310,7 +311,7 @@ public List getConceptComplexList() { ObjectMapper mapper = new ObjectMapper(); TypeReference> typeRef = new TypeReference>() {}; try { - list = mapper.readValue(globalProperty, typeRef); + list = mapper.readValue(StringEscapeUtils.unescapeHtml(globalProperty), typeRef); } catch (Exception e) { log.error("Could not parse global property '" + globalPropertyName + "' into a List.", e); diff --git a/omod/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource.java b/omod/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource.java index 5b450df..988e6a5 100644 --- a/omod/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource.java +++ b/omod/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource.java @@ -2,6 +2,7 @@ import static org.openmrs.module.attachments.AttachmentsContext.getContentFamily; +import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -11,6 +12,9 @@ import java.util.List; import java.util.stream.Collectors; +import javax.activation.MimetypesFileTypeMap; +import javax.imageio.ImageIO; + import io.swagger.models.Model; import io.swagger.models.ModelImpl; import io.swagger.models.properties.DateProperty; @@ -176,6 +180,14 @@ public Object upload(MultipartFile file, RequestContext context) throws Response } } + // Verify the file contents + // Just in case the magic bytes are manipulated, we are using the submitted file + // extension to get the mime type + String mimeType = new MimetypesFileTypeMap().getContentType(fileName); + if (mimeType.startsWith("image/") && !isValidImage(file.getInputStream())) { + throw new IllegalRequestException("The file has invalid content"); + } + if (visit != null && encounter == null) { encounter = ctx.getAttachmentEncounter(patient, visit, provider); } @@ -203,6 +215,26 @@ public Object upload(MultipartFile file, RequestContext context) throws Response new CustomRepresentation(AttachmentsConstants.REPRESENTATION_OBS)); } + private boolean isValidImage(InputStream fileStream) { + try { + BufferedImage image = ImageIO.read(fileStream); + image.getHeight(); + image.getWidth(); + return true; + } + catch (IOException e) { + return false; + } + finally { + if (fileStream.markSupported()) { + try { + fileStream.reset(); + } + catch (IOException e) {} + } + } + } + @Override public DelegatingResourceDescription getCreatableProperties() { DelegatingResourceDescription description = new DelegatingResourceDescription();