Problem
When JMAP email bodies are fetched on-demand, the server-provided jmap_email_id is interpolated directly into a filename with no sanitization or path-component validation.
A malicious or non-conforming JMAP server could return IDs containing path separators, NUL bytes, or control characters, causing writes outside the intended maildir.
Location
src-tauri/src/mail/jmap_sync.rs:438-440
let filename = format!(\"{}:2,{}\", jmap_email_id, flags_to_maildir_suffix(flags));
let msg_path = maildir_base.join(\"cur\").join(&filename);
std::fs::write(&msg_path, &body)?;
Proposed fix
- Validate
jmap_email_id against a safe charset (e.g. [A-Za-z0-9._-]) before using in filenames.
- After joining, canonicalize and verify the final path is contained within the expected maildir root (same defensive pattern as the attachment-save code).
Source: Copilot security audit, finding B (Medium).
Problem
When JMAP email bodies are fetched on-demand, the server-provided
jmap_email_idis interpolated directly into a filename with no sanitization or path-component validation.A malicious or non-conforming JMAP server could return IDs containing path separators, NUL bytes, or control characters, causing writes outside the intended maildir.
Location
src-tauri/src/mail/jmap_sync.rs:438-440Proposed fix
jmap_email_idagainst a safe charset (e.g.[A-Za-z0-9._-]) before using in filenames.Source: Copilot security audit, finding B (Medium).