oscerd commented on code in PR #26661:
URL: https://github.com/apache/camel/pull/26661#discussion_r4080634049


##########
components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java:
##########
@@ -417,7 +418,12 @@ private String getAttachmentKey(BodyPart bp) throws 
MessagingException, Unsuppor
         if (key == null) {
             key = UUID.randomUUID() + "@camel.apache.org";
         }
-        return MimeUtility.decodeText(key);
+        key = MimeUtility.decodeText(key);
+        // The name is chosen by the sender of the message being unmarshalled, 
so normalise it the same
+        // way MailBinding.extractAndNormalizeFileName does before it is used 
to identify the attachment:
+        // strip control characters, then reduce it to a leaf name so it 
cannot carry path components.
+        key = key.replaceAll("[\n\r\t]", "_");
+        return FileUtil.stripPath(key);

Review Comment:
   Fixed in 55b4ad6 — `getAttachmentKey` now reduces the key to a leaf name 
only when it comes from the sender-chosen file name. A Content-ID (or a 
generated id) is decoded but left intact, so `<a/[email protected]>` keeps its 
`/` and `cid:` references in a `multipart/related` message are not broken. 
Added `unmarshalContentIdKeyKeepsSlashesBecauseItIsNotAPath`, which fails 
against the strip-everything version (verified), while the file-name traversal 
test still passes.
   
   _Claude Code on behalf of oscerd_
   



##########
components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java:
##########
@@ -724,8 +725,12 @@ protected void addAttachmentsToMultipart(
                         LOG.trace("Attachment #{}: Using content type 
resolver: {} resolved content type as: {}", i,
                                 contentTypeResolver, contentType);
                         if (contentType != null) {
-                            String value = contentType + "; name=" + 
attachmentFilename;
-                            messageBodyPart.setHeader("Content-Type", value);
+                            // The file name comes from the message being 
relayed, so it must go out as a
+                            // parameter value rather than be concatenated 
into the header. ParameterList
+                            // quotes and escapes anything that would 
otherwise change the header's structure.
+                            ContentType parsed = new ContentType(contentType);

Review Comment:
   Good question — to be precise about the before/after: previously 
`contentType + "; name=" + attachmentFilename` was written to the header raw, 
so an unparsable content type produced an *invalid* `Content-Type` header. That 
was "successfully ignored" only when the receiving mail client happened to be 
lenient; a strict one failed later. The new parse both closes a 
header-injection vector (the sender-chosen file name was being concatenated 
into the header structure) and, as @davsclaus noted, surfaces a genuinely 
invalid content type at marshal time rather than downstream.
   
   I've kept the fail-fast — reverting to raw concatenation would reopen the 
injection — and documented the behaviour change in the 4.23 upgrade guide (new 
`camel-mail` note), so a custom `ContentTypeResolver` returning an unparsable 
value is a known migration point. Ordinary resolvers returning valid MIME types 
are unaffected.
   
   _Claude Code on behalf of oscerd_
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to