From 5248232c44f3819fbb8a6cdac258740afbb94823 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 23 Mar 2022 12:34:20 +0000 Subject: [PATCH] Try to prevent autolinking of displaynames by email readers (#19169) Unfortunately many email readers will (helpfully) detect url or url-like names and automatically create links to them, even in HTML emails. This is not ideal when usernames can have dots in them. This PR tries to prevent this behaviour by sticking ZWJ characters between dots and also set the meta tag to prevent format detection. Not every email template has been changed in this way - just the activation emails but it may be that we should be setting the above meta tag in all of our emails too. Signed-off-by: Andrew Thornton --- modules/templates/helper.go | 5 +++++ services/mailer/mail.go | 25 ++++++++++++++---------- services/mailer/mail_release.go | 5 +++-- services/mailer/mail_repo.go | 5 +++-- templates/mail/auth/activate.tmpl | 5 +++-- templates/mail/auth/activate_email.tmpl | 5 +++-- templates/mail/auth/register_notify.tmpl | 5 +++-- templates/mail/auth/reset_passwd.tmpl | 5 +++-- 8 files changed, 38 insertions(+), 22 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 63c165bc8..918a6523b 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -632,6 +632,11 @@ func JSEscape(raw string) string { return template.JSEscapeString(raw) } +// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls +func DotEscape(raw string) string { + return strings.ReplaceAll(raw, ".", "\u200d.\u200d") +} + // Sha1 returns sha1 sum of string func Sha1(str string) string { return base.EncodeSha1(str) diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 8e04e7e4d..1e90deb4c 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -78,8 +78,9 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s "Code": code, "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -128,8 +129,9 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) { "Email": email.Email, "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -158,8 +160,9 @@ func SendRegisterNotifyMail(u *user_model.User) { "Username": u.Name, "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -191,8 +194,9 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository) "Link": repo.HTMLURL(), "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -275,8 +279,9 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient "ReviewComments": reviewComments, "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var mailSubject bytes.Buffer diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index 76dceb238..b6bddeac0 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -75,8 +75,9 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *models. "Subject": subject, "Language": locale.Language(), // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } var mailBody bytes.Buffer diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go index 24e6d671f..0abc666f1 100644 --- a/services/mailer/mail_repo.go +++ b/services/mailer/mail_repo.go @@ -73,8 +73,9 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U "Language": locale.Language(), "Destination": destination, // helper - "i18n": locale, - "Str2html": templates.Str2html, + "i18n": locale, + "Str2html": templates.Str2html, + "DotEscape": templates.DotEscape, } if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil { diff --git a/templates/mail/auth/activate.tmpl b/templates/mail/auth/activate.tmpl index 31e9a9688..5de3967bc 100644 --- a/templates/mail/auth/activate.tmpl +++ b/templates/mail/auth/activate.tmpl @@ -2,12 +2,13 @@ - {{.i18n.Tr "mail.activate_account.title" .DisplayName}} + + {{.i18n.Tr "mail.activate_account.title" (.DisplayName|DotEscape)}} {{ $activate_url := printf "%suser/activate?code=%s" AppUrl (QueryEscape .Code)}} -

{{.i18n.Tr "mail.activate_account.text_1" .DisplayName AppName | Str2html}}


+

{{.i18n.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName | Str2html}}


{{.i18n.Tr "mail.activate_account.text_2" .ActiveCodeLives | Str2html}}

{{$activate_url}}


{{.i18n.Tr "mail.link_not_working_do_paste"}}

diff --git a/templates/mail/auth/activate_email.tmpl b/templates/mail/auth/activate_email.tmpl index 8bd037ae4..5c7979882 100644 --- a/templates/mail/auth/activate_email.tmpl +++ b/templates/mail/auth/activate_email.tmpl @@ -2,12 +2,13 @@ - {{.i18n.Tr "mail.activate_email.title" .DisplayName}} + + {{.i18n.Tr "mail.activate_email.title" (.DisplayName|DotEscape)}} {{ $activate_url := printf "%suser/activate_email?code=%s&email=%s" AppUrl (QueryEscape .Code) (QueryEscape .Email)}} -

{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}


+

{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}


{{.i18n.Tr "mail.activate_email.text" .ActiveCodeLives | Str2html}}

{{$activate_url}}


{{.i18n.Tr "mail.link_not_working_do_paste"}}

diff --git a/templates/mail/auth/register_notify.tmpl b/templates/mail/auth/register_notify.tmpl index 45ca95f2c..a32d8ce99 100644 --- a/templates/mail/auth/register_notify.tmpl +++ b/templates/mail/auth/register_notify.tmpl @@ -2,12 +2,13 @@ - {{.i18n.Tr "mail.register_notify.title" .DisplayName AppName}} + + {{.i18n.Tr "mail.register_notify.title" (.DisplayName|DotEscape) AppName}} {{$set_pwd_url := printf "%[1]suser/forgot_password" AppUrl}} -

{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}


+

{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}


{{.i18n.Tr "mail.register_notify.text_1" AppName}}


{{.i18n.Tr "mail.register_notify.text_2" .Username}}

{{AppUrl}}user/login


{{.i18n.Tr "mail.register_notify.text_3" ($set_pwd_url | Escape) | Str2html}}


diff --git a/templates/mail/auth/reset_passwd.tmpl b/templates/mail/auth/reset_passwd.tmpl index bf10c1f96..028d911a9 100644 --- a/templates/mail/auth/reset_passwd.tmpl +++ b/templates/mail/auth/reset_passwd.tmpl @@ -2,12 +2,13 @@ - {{.i18n.Tr "mail.reset_password.title" .DisplayName}} + + {{.i18n.Tr "mail.reset_password.title" (.DisplayName|DotEscape)}} {{ $recover_url := printf "%suser/recover_account?code=%s" AppUrl (QueryEscape .Code)}} -

{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}


+

{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}


{{.i18n.Tr "mail.reset_password.text" .ResetPwdCodeLives | Str2html}}

{{$recover_url}}


{{.i18n.Tr "mail.link_not_working_do_paste"}}