From bb0e2121a3f060601e6f5cf2d201f44588d8bf21 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 23 Mar 2022 13:18:11 +0000 Subject: [PATCH] Try to prevent autolinking of displaynames by email readers (#19169) (#19183) Backport #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 9a72ed7520cb..c0b67b3cf86a 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -633,6 +633,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 e0a454d4983b..7e5f531c8ff5 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -77,8 +77,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 @@ -127,8 +128,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 @@ -157,8 +159,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 @@ -190,8 +193,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 @@ -273,8 +277,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 ee4c6f3a59cd..ff0e14c47a42 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -74,8 +74,9 @@ func mailNewRelease(lang string, tos []string, rel *models.Release) { "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 24e6d671f488..0abc666f1aef 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 31e9a9688276..5de3967bc4f1 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 8bd037ae4f68..5c79798821f2 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 45ca95f2c3e0..a32d8ce99280 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 bf10c1f96787..028d911a9938 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"}}