Forwarded message sends the WRONG attachment after changing the sender
Maintainers usually reply within 1 day
@GretaD is already working on this.
Since Jun 30, 2026.
Assessment
This issue has not been assessed yet.
Description
Steps to reproduce
Forward an email that has attachments, then change the sender (alias) before sending.
The message is sent with a different attachment than the one displayed — a file
the user never selected, attached, or downloaded. This is a data-confidentiality
issue: the wrong file (potentially another message's attachment) can be transmitted
to the recipient.
- Open a received email that has one or more attachments.
- Forward it. The original attachments are shown attached to the forward.
- Change the From / sender alias on the compose form.
- Send.
- The sent message (check Sent folder) carries a different attachment than the one shown in the composer.
Expected behavior
The correct Attachment(s) should be sent
Actual behavior
Observed on this instance (server-side evidence)
From nextcloud.log, a forward (subject "Fwd: …", account_id 13) during an active
sender change:
| Time (UTC) | Request | Result |
|---|---|---|
| 12:30:41 | POST /api/drafts |
InvalidArgumentException: Attachment does not have a type (LocalMessage 131) |
| 12:31:10 | POST /api/drafts |
same error (LocalMessage 132) |
The draft auto-save threw (same type-missing path as Bug #1), but the send path is
separate and did not error, so the message was sent anyway — with a substituted
attachment.
Root cause (analysis)
Forwarded attachments are not copied at forward time. They are stored as a
reference and fetched lazily from IMAP at draft-save / send time:
// AttachmentService::handleForwardedAttachment (lines 376-401)
$mailbox = $this->mailManager->getMailbox($account->getUserId(), $attachment['mailboxId']);
$imapAttachment = $this->messageMapper->getAttachment(
$client,
$mailbox->getName(),
(int)$attachment['uid'], // source IMAP UID
$attachment['id'], // MIME part id
$account->getUserId(),
);
The reference is {mailboxId, uid, part-id}. IMAP UIDs and MIME part-ids are not
content-pinned: they identify a coordinate, not a file. When the sender/alias is
changed, the whole local message is re-serialized and these references are re-resolved
against IMAP. If the re-sent reference points at a different UID/part than the original
(stale frontend state, UIDVALIDITY change, part-id collision, or the same type-loss
corruption from Bug #1 mangling the attachment descriptor), getAttachment() returns
whatever file currently lives at that coordinate — which may be an unrelated
message's attachment. That file is then attached and sent.
Impact
- Confidentiality: a file the sender never selected can be transmitted to a third
party. If the substituted file belongs to a different message, this is an
unintended disclosure. - Silent: the send path does not surface the draft-save error to the user.
Suggested fixes
- Materialize forwarded attachments into local storage at forward time (as Bug #1's
local uploads are), rather than resolving an IMAP coordinate at send time; or pin the
reference to an immutable identifier (UIDVALIDITY + UID + part, validated before
fetch). - Make
handleAttachments()tolerant of a missingtypefor already-persisted
attachments instead of throwing, and treat any unresolved reference as a hard send
failure (never silently substitute). - Do not let a draft-save attachment error be bypassed by the send path.
Workaround
Do not change the sender/alias on a forward (or any message) that carries attachments.
On this instance the Mail app has been disabled pending a fix.
Mail app version
5.10.3
Nextcloud version
34.0.0.12
Mailserver or service
Exim4 and Dovecot
Operating system
Debian (Linux 6.12) / Docker (nextcloud:34-apache)
PHP engine version
Other
Nextcloud memory caching
Memcache
Web server
Apache (supported)
Database
MariaDB
Additional info
PHP 8.4.22, Apache
Accounts authenticated via IMAP/SMTP (app-password); LDAP backend for user accounts
MariaDB 11.8
- Dominant language
- JavaScript
- Stars
- 1k
- Forks
- 364
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 102
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nextcloud/mail
-
1. to develop enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
nextcloud/mail#13841 · 3 comments ·
Maintainers usually reply within 1 day
-
1. to develop enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
nextcloud/mail#13828 · 1 comment ·
Maintainers usually reply within 1 day
-
Show email next to name in Search dropdownPossibly taken @vansh-nagar claimed this 21 days ago. Open1. to develop enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
nextcloud/mail#13703 · 1 comment ·
Maintainers usually reply within 1 day
-
ISO-2022-JP emails are garbled in Mail 5.10.12 [Minimal fix available]Possibly taken @neconohitomi claimed this 41 days ago. Open1. to develop bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
nextcloud/mail#13472 · 1 comment ·
Maintainers usually reply within 1 day
-
1. to develop technical debt
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
Similar issues
-
data
Difficulty 1/5 Under an hour Newbie friendliness 74/100
gaseous-project/hasheous#637 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
gramps-project/gramps-web#1549 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
change request evaluating
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
sindresorhus/eslint-plugin-unicorn#3907 ·
Maintainers usually reply within 1 day
-
Priority: Low Production Type: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
GrottoCenter/grottocenter-api#1903 ·
Maintainers usually reply within 1 day