-
Notifications
You must be signed in to change notification settings - Fork 9
Validate supplied mimeType against acceptable media types #863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,6 +60,54 @@ public static void validateMediaAttachments( | |
| Map<String, Set<String>> fileNamesByElementName = | ||
| AttachmentDataExtractor.extractAndValidateFileNamesByElement(entity, data); | ||
| validateAttachmentMediaTypes(fileNamesByElementName, allowedTypesByElementName); | ||
|
|
||
| // validate the explicitly supplied mime types as well. The file name check alone can be | ||
| // bypassed by pairing an allowed file name (e.g. "report.pdf") with a disallowed MIME type | ||
| // (e.g. "text/html") that is persisted and served inline. | ||
| Map<String, Set<String>> mimeTypesByElementName = | ||
| AttachmentDataExtractor.extractMimeTypesByElement(entity, data); | ||
| validateAttachmentMimeTypes(mimeTypesByElementName, allowedTypesByElementName); | ||
| } | ||
|
|
||
| private static void validateAttachmentMimeTypes( | ||
| Map<String, Set<String>> mimeTypesByElementName, | ||
| Map<String, List<String>> acceptableMediaTypesByElementName) { | ||
|
|
||
| Map<String, List<String>> invalidMimeTypes = | ||
| findInvalidMimeTypesByElementName( | ||
| mimeTypesByElementName, acceptableMediaTypesByElementName); | ||
|
|
||
| if (!invalidMimeTypes.isEmpty()) { | ||
| throw buildUnsupportedFileTypeMessage(acceptableMediaTypesByElementName, invalidMimeTypes); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Please provide feedback on the review comment by checking the appropriate box:
|
||
| } | ||
| } | ||
|
|
||
| private static Map<String, List<String>> findInvalidMimeTypesByElementName( | ||
| Map<String, Set<String>> mimeTypesByElementName, | ||
| Map<String, List<String>> acceptableMediaTypesByElementName) { | ||
| if (mimeTypesByElementName == null || mimeTypesByElementName.isEmpty()) { | ||
| return Map.of(); | ||
| } | ||
| Map<String, List<String>> invalidMimeTypes = new HashMap<>(); | ||
| mimeTypesByElementName.forEach( | ||
| (elementName, mimeTypes) -> { | ||
| List<String> acceptableTypes = acceptableMediaTypesByElementName.get(elementName); | ||
| if (acceptableTypes == null) { | ||
| return; | ||
| } | ||
|
Comment on lines
+94
to
+97
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logic Error: When This is only safe if the two maps are guaranteed to be keyed identically. However, Please provide feedback on the review comment by checking the appropriate box:
|
||
|
|
||
| List<String> invalid = | ||
| mimeTypes.stream() | ||
| .filter( | ||
| mimeType -> !MediaTypeService.isMimeTypeAllowed(acceptableTypes, mimeType)) | ||
| .toList(); | ||
|
|
||
| if (!invalid.isEmpty()) { | ||
| invalidMimeTypes.put(elementName, invalid); | ||
| } | ||
| }); | ||
|
|
||
| return invalidMimeTypes; | ||
| } | ||
|
|
||
| private static void validateAttachmentMediaTypes( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,6 +82,28 @@ void shouldRejectAttachment_whenFileNameIsEmpty() throws Exception { | |
| status().isBadRequest()); | ||
| } | ||
|
|
||
| @Test | ||
| void shouldRejectAttachment_whenAllowedFileNameCarriesDisallowedMimeType() throws Exception { | ||
| String rootId = createRootAndReturnId(); | ||
| String attachmentMetadata = | ||
| objectMapper.writeValueAsString(Map.of("fileName", "image.jpg", "mimeType", "text/html")); | ||
|
|
||
| requestHelper.assertPostStatus( | ||
| createUrl(rootId, MEDIA_VALIDATED_ATTACHMENTS), | ||
| attachmentMetadata, | ||
| status().isUnsupportedMediaType()); | ||
| } | ||
|
|
||
| @Test | ||
| void shouldAcceptAttachment_whenAllowedFileNameAndAllowedMimeType() throws Exception { | ||
| String rootId = createRootAndReturnId(); | ||
| String attachmentMetadata = | ||
| objectMapper.writeValueAsString(Map.of("fileName", "image.jpg", "mimeType", "image/jpeg")); | ||
|
|
||
| requestHelper.assertPostStatus( | ||
| createUrl(rootId, MEDIA_VALIDATED_ATTACHMENTS), attachmentMetadata, status().isCreated()); | ||
|
Comment on lines
+97
to
+104
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Best Practice: The new test Please provide feedback on the review comment by checking the appropriate box:
|
||
| } | ||
|
|
||
| @Test | ||
| void shouldAcceptUppercaseExtension_whenMimeTypeIsAllowed() throws Exception { | ||
| String rootId = createRootAndReturnId(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic Error: Unit tests for
validateAttachmentMimeTypesdo not stubextractMimeTypesByElement, causing it to returnnullin the mock context and silently skip MIME-type validation.In
doesNotThrow_whenNoFilesand both parametrized test methods (doesNotThrow_whenFilesAreValid,throwsException_whenFilesAreInvalid),AttachmentDataExtractor.extractMimeTypesByElementis never stubbed. When the static mock is active it returnsnullby default, andfindInvalidMimeTypesByElementNameshort-circuits on thenullguard at line 88, so the new validation path is never exercised by the unit tests. The happy-path and rejection tests may both pass for the wrong reason. The existing mocked-static setup in each test should also stubextractMimeTypesByElementand include scenarios where it returns a disallowed MIME type.Please provide feedback on the review comment by checking the appropriate box: