CVE-2021-29432 (Other, published 2021-04-15T21:15Z)
Description: value: Sydent is a reference matrix identity server. A malicious user could abuse Sydent to send out arbitrary emails from the Sydent email address. This could be used to construct plausible phishing emails, for example. This issue has been fixed in 4469d1d.
Severity: LOW (CVSS v3 base score: 5.7)
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/matrix-org/sydent
Files changed:
res/matrix-org/invite_template.eml
res/matrix-org/verification_template.eml
res/vector-im/invite_template.eml
res/vector-im/verification_template.eml
sydent/http/servlets/store_invite_servlet.py
sydent/util/emailutils.py
Commit message: Randomise multipart boundary, and include mxids in invite email notifs


Vulnerable code:
Content-Type: multipart/alternative; 
	boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
%(sender_display_name)s has invited you into a room %(bracketed_room_name)s on
Matrix. To join the conversation, either pick a Matrix client from
https://matrix.org/docs/projects/try-matrix-now.html or use the single-click
link below to join via Element (requires Chrome, Firefox, Safari, iOS or Android)
Content-Type: multipart/related;
	boundary="M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR";
	type="text/html"

<p>%(sender_display_name_forhtml)s has invited you into a room %(bracketed_room_name_forhtml)s on
Content-Type: multipart/alternative; 
	boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
Content-Type: multipart/alternative; 
	boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
%(sender_display_name)s has invited you into a room %(bracketed_room_name)s on
Element. To join the conversation please follow the link below.
Content-Type: multipart/related;
	boundary="M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR";
	type="text/html"

<p>%(sender_display_name_forhtml)s has invited you into a room %(bracketed_room_name_forhtml)s on
Element.</p>
Content-Type: multipart/alternative; 
	boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
Content-Type: multipart/related;
	boundary="M3yzHl5YZehm9v4bAM8sKEdcOoVnRnKR";
	type="text/html"

from sydent.http.servlets import get_args, send_cors, jsonwrap

        if self.require_auth:
            authV2(self.sydent, request)

            substitutions["bracketed_room_name"] = "(%s)" % substitutions["room_name"]

Fixed code:
Content-Type: multipart/alternative;
	boundary="%(multipart_boundary)s"
--%(multipart_boundary)s
%(sender_display_name)s %(bracketed_verified_sender)shas invited you into a room
%(bracketed_room_name)son Matrix. To join the conversation, either pick a
Matrix client from https://matrix.org/docs/projects/try-matrix-now.html or use
the single-click link below to join via Element (requires Chrome, Firefox,
Safari, iOS or Android)
--%(multipart_boundary)s
#low-contrast {
    color: #666666
}

<p>%(sender_display_name_forhtml)s <span class="low-contrast">%(bracketed_verified_sender_for_html)s</span> has invited you into a room %(bracketed_room_name_forhtml)s on
--%(multipart_boundary)s--
Content-Type: multipart/alternative;
	boundary="%(multipart_boundary)s"
--%(multipart_boundary)s
--%(multipart_boundary)s
--%(multipart_boundary)s--
Content-Type: multipart/alternative;
	boundary="%(multipart_boundary)s"
--%(multipart_boundary)s
%(sender_display_name)s %(bracketed_verified_sender)shas invited you into a room
%(bracketed_room_name)son Element. To join the conversation please follow the
link below.
--%(multipart_boundary)s
#low-contrast {
    color: #666666
}

<p>%(sender_display_name_forhtml)s <span class="low-contrast">%(bracketed_verified_sender_for_html)s</span> has invited you into a
room %(bracketed_room_name_forhtml)s on Element.</p>
--%(multipart_boundary)s--
Content-Type: multipart/alternative;
	boundary="%(multipart_boundary)s"
--%(multipart_boundary)s
--%(multipart_boundary)s
--%(multipart_boundary)s--
from sydent.http.servlets import get_args, send_cors, jsonwrap, MatrixRestError
        verified_sender = None
        if self.require_auth:
            account = authV2(self.sydent, request)
            verified_sender = sender
            if account.userId != sender:
                raise MatrixRestError(403, "M_UNAUTHORIZED", "'sender' doesn't match")

        substitutions["bracketed_verified_sender"] = ""
        if verified_sender:
            substitutions["bracketed_verified_sender"] = "(%s) " % (verified_sender,)

            substitutions["bracketed_room_name"] = "(%s) " % substitutions["room_name"]
from sydent.util.tokenutils import generateAlphanumericTokenOfLength
    # We add randomize the multipart boundary to stop user input from
    # conflicting with it.
    allSubstitutions["multipart_boundary"] = generateAlphanumericTokenOfLength(32)