diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java index 211f81244..9f7de51c8 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java @@ -209,6 +209,9 @@ public ResponseEntity retriveImage(String patientUuid) { @Override public ResponseEntity retriveImageWithoutDefault(String patientUuid) { File file = getPatientImageFileWithoutDefault(patientUuid); + if (file == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } return readImage(file); } @@ -261,7 +264,12 @@ private File getPatientImageFile(String patientUuid) { } private File getPatientImageFileWithoutDefault(String patientUuid) { - return new File(String.format("%s/%s.%s", BahmniCoreProperties.getProperty("bahmnicore.images.directory"), patientUuid, patientImagesFormat)); + Path base = Paths.get(BahmniCoreProperties.getProperty("bahmnicore.images.directory")).toAbsolutePath().normalize(); + Path resolved = base.resolve(patientUuid + "." + patientImagesFormat).normalize(); + if (!resolved.startsWith(base)) { + return null; + } + return resolved.toFile(); } private ResponseEntity readImage(File file) { diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java index c1611333b..90f80ddff 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java @@ -89,6 +89,17 @@ public void shouldCreateRightDirectoryAccordingToPatientId() { absoluteFileDirectory.delete(); } + @Test + public void shouldReturn404WhenPathTraversalAttemptedViaPatientUuidOnV2() { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.images.directory")).thenReturn("/bahmni_data/patient_images"); + patientDocumentService = new PatientDocumentServiceImpl(); + + ResponseEntity responseEntity = patientDocumentService.retriveImageWithoutDefault("../../../../tmp/secret"); + + assertEquals(404, responseEntity.getStatusCode().value()); + } + @Test public void shouldGetImageNotFoundForIfNoImageCapturedForPatientAndNoDefaultImageNotPresent() throws Exception { final FileInputStream fileInputStreamMock = PowerMockito.mock(FileInputStream.class);