-
Notifications
You must be signed in to change notification settings - Fork 900
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
Fix to reject any unintended parameters in multipart request. #5569
base: main
Are you sure you want to change the base?
Conversation
I'm concerned that the behavior of pulling values from ServiceRequestContext is not clean. |
final AttributeKey<List<String>> PARAM_LIST_KEY = AttributeKey.valueOf(List.class, "names"); | ||
final List<String> names = resolvers.stream() | ||
.map(AnnotatedValueResolver::httpElementName) | ||
.collect(Collectors.toList()); | ||
ctx.setAttr(PARAM_LIST_KEY, names); |
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.
- We could just pass the param list as an additional parameter of
aggregateMultipart()
. - We could collect this information when creating an
AnnotatedService
instance, not every time service each request.
Motivation: this resolves line#5549 Modifications: - Fix(AnnotatedServiceMultipartTest): Add test for upload multipart file with unexpected parameters in AnnotatedServiceMultipartTest. - Fix(AnnotatedService): Fix to include a list of intended parameters in the ServiceRequestContext. - Fix(FileAggregatedMultipart): Fix to check if any variables are passed in the list of intended parameters and throw an acceptance if not. Result: Multipart requests with unintended parameters will no longer create files.
Resolved all comments PTAL @trustin |
Fixed missing GPG signature. |
Fixed it all. 🙂 |
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.
Thanks! I left my opinion. 😉
core/src/main/java/com/linecorp/armeria/internal/server/annotation/DefaultAnnotatedService.java
Outdated
Show resolved
Hide resolved
final Path destination = ctx.config().multipartUploadsLocation(); | ||
return Multipart.from(req).collect(bodyPart -> { | ||
final String name = bodyPart.name(); | ||
assert name != null; | ||
if (!parameters.isEmpty() && !parameters.contains(name)) { |
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.
I prefer to silently discard it because it might already process all the necessary files.
Let's say that there are 10 files and the last one is the one that the service doesnt' need.
This will reject the request after processing all the necessary files.
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.
Rather than rejecting it by throwing an exception (the loud way), I'll modify it to ignore unintended files (the quiet way)
📝 leaves memo for myself to remember later.
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.
I think it's fine to discard them as long as we don't write them into filesystem. Do we?
…tion/DefaultAnnotatedService.java Co-authored-by: minux <[email protected]>
Motivation: If an unintended file was entered, it threw an exception and terminated. This behavior was frustrating to the user, so changed to a calmer method that simply ignores the file. Modification: - Fix(AnnotatedServiceMultipartTest): Change from BAD REQUEST to OK, and change the file name to be more distinguishable. - Fix(FileAggregatedMultipart): Add filtering - Fix(Multipart): Add filtering. I wanted to name the filtering method filter, but because the StreamMessage interface already has a filter function, and because the DefaultMultipart class implements both the multipart interface and the StreamMessage interface, I used a different name. Result: It no longer raises an acceptance. Instead, unintended files are filtered out before they are written to disk.
Resolves all! PTAL |
* @param predicate certain conditions | ||
* @return multipart matching the condition | ||
*/ | ||
default Multipart filterBodyParts(Predicate<? super BodyPart> predicate) { |
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.
How about renaming to filter()
?
private static boolean shouldSkip(BodyPart bodyPart, List<String> parameters) { | ||
final String name = bodyPart.name(); | ||
assert name != null; | ||
return !parameters.isEmpty() && !parameters.contains(name); |
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.
Maybe I misunderstood, but should we return true
if parameters
is empty?
final Path destination = ctx.config().multipartUploadsLocation(); | ||
return Multipart.from(req).collect(bodyPart -> { | ||
return Multipart.from(req) | ||
.filterBodyParts(bodyPart -> !shouldSkip(bodyPart, parameters)).collect(bodyPart -> { |
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.
If we always negate the result of shouldSkip()
, we could maybe replace !shouldSkip()
with shouldHandle()
?
final AggregatedHttpResponse response = | ||
server.blockingWebClient().execute(multipart.toHttpRequest(path)); | ||
assertEquals(HttpStatus.OK, response.status()); |
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.
This doesn't make sure the multipartFile3
has been either discarded or processed at all. What about writing a new endpoint in MyAnnotatedService
that makes sure the file is not created for multipartFile3
in the directory that contains multipartFile1
and multipartFile2
.
Motivation:
this resolves #5549
Modifications:
Result:
Multipart requests with unintended parameters will no longer create files.