diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index fa5d3ae474a870002b5f78040381c02d9c2dc3de..dedc58f482bc331b2bd1d964dd6504077014cf61 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -36,6 +36,14 @@ module EmailsHelper nil end + def sanitize_name(name) + if name =~ URI::DEFAULT_PARSER.regexp[:URI_REF] + name.tr('.', '_') + else + name + end + end + def password_reset_token_valid_time valid_hours = Devise.reset_password_within / 60 / 60 if valid_hours >= 24 diff --git a/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml b/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml index 3d0a1f622a53e62fdb998ad292098e2cd919f2b0..ccc3e734276644f5cc2d051a4ebf5806bb2d784f 100644 --- a/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml +++ b/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml @@ -1,5 +1,5 @@ #content - = email_default_heading("#{@resource.user.name}, you've added an additional email!") + = email_default_heading("#{sanitize_name(@resource.user.name)}, you've added an additional email!") %p Click the link below to confirm your email address (#{@resource.email}) #cta = link_to 'Confirm your email address', confirmation_url(@resource, confirmation_token: @token) diff --git a/app/views/notify/_note_email.text.erb b/app/views/notify/_note_email.text.erb index 50209c46ed149901877668b0a2f62c89f7a471ef..5a67214059c2ecd8315fed01213b3f5e7c6ed0a6 100644 --- a/app/views/notify/_note_email.text.erb +++ b/app/views/notify/_note_email.text.erb @@ -3,7 +3,7 @@ <% discussion = note.discussion if note.part_of_discussion? -%> <% if discussion && !discussion.individual_note? -%> -<%= note.author_name -%> +<%= sanitize_name(note.author_name) -%> <% if discussion.new_discussion? -%> <%= " started a new discussion" -%> <% else -%> @@ -16,7 +16,7 @@ <% elsif Gitlab::CurrentSettings.email_author_in_body -%> -<%= "#{note.author_name} commented:" -%> +<%= "#{sanitize_name(note.author_name)} commented:" -%> <% end -%> diff --git a/app/views/notify/autodevops_disabled_email.text.erb b/app/views/notify/autodevops_disabled_email.text.erb index 695780c3145ebc75d7484ab873ae8210de2047a5..bf863952478494d836ea067a708b1e336a8fb8d4 100644 --- a/app/views/notify/autodevops_disabled_email.text.erb +++ b/app/views/notify/autodevops_disabled_email.text.erb @@ -3,7 +3,7 @@ Auto DevOps pipeline was disabled for <%= @project.name %> The Auto DevOps pipeline failed for pipeline <%= @pipeline.iid %> (<%= pipeline_url(@pipeline) %>) and has been disabled for <%= @project.name %>. In order to use the Auto DevOps pipeline with your project, please review the currently supported languagues (https://docs.gitlab.com/ee/topics/autodevops/#currently-supported-languages), adjust your project accordingly, and turn on the Auto DevOps pipeline within your CI/CD project settings (<%= project_settings_ci_cd_url(@project) %>). <% if @pipeline.user -%> - Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= @pipeline.user.name %> ( <%= user_url(@pipeline.user) %> ) + Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> ) <% else -%> Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API <% end -%> diff --git a/app/views/notify/closed_issue_email.html.haml b/app/views/notify/closed_issue_email.html.haml index b7284dd819b25a308d9ee929d249ca3c3e561e83..eb148d72da15155e96aea78c333d86356083ad74 100644 --- a/app/views/notify/closed_issue_email.html.haml +++ b/app/views/notify/closed_issue_email.html.haml @@ -1,2 +1,2 @@ %p - Issue was closed by #{@updated_by.name} + Issue was closed by #{sanitize_name(@updated_by.name)} diff --git a/app/views/notify/closed_issue_email.text.haml b/app/views/notify/closed_issue_email.text.haml index b35d4b7502d57341cb650a2cce387c725cba12aa..b1f0a3f37ecb748f22e47e034a2a3df59fad9d1d 100644 --- a/app/views/notify/closed_issue_email.text.haml +++ b/app/views/notify/closed_issue_email.text.haml @@ -1,3 +1,3 @@ -Issue was closed by #{@updated_by.name} +Issue was closed by #{sanitize_name(@updated_by.name)} Issue ##{@issue.iid}: #{project_issue_url(@issue.project, @issue)} diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml index 44e018304e1e13f0ccf0e746d142daafb4893cec..2aa753e0d5557c526e8533207d440e656eeeecae 100644 --- a/app/views/notify/closed_merge_request_email.html.haml +++ b/app/views/notify/closed_merge_request_email.html.haml @@ -1,2 +1,2 @@ %p - Merge Request #{@merge_request.to_reference} was closed by #{@updated_by.name} + Merge Request #{@merge_request.to_reference} was closed by #{sanitize_name(@updated_by.name)} diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml index c4e06cb3cb1967a359b7b0900b14e3b7745e74b3..1094d584a1c0c1e419d3380e21efb472699c070d 100644 --- a/app/views/notify/closed_merge_request_email.text.haml +++ b/app/views/notify/closed_merge_request_email.text.haml @@ -1,8 +1,8 @@ -Merge Request #{@merge_request.to_reference} was closed by #{@updated_by.name} +Merge Request #{@merge_request.to_reference} was closed by #{sanitize_name(@updated_by.name)} Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} = merge_path_description(@merge_request, 'to') -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} +Author: #{sanitize_name(@merge_request.author_name)} +Assignee: #{sanitize_name(@merge_request.assignee_name)} diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml index b6051b11cea3ddaae03bd0d8cecc4fac3fd3fadb..66e73a9b03f69c2b3ff777b31bb34af87df998c6 100644 --- a/app/views/notify/issue_status_changed_email.html.haml +++ b/app/views/notify/issue_status_changed_email.html.haml @@ -1,2 +1,2 @@ %p - Issue was #{@issue_status} by #{@updated_by.name} + Issue was #{@issue_status} by #{sanitize_name(@updated_by.name)} diff --git a/app/views/notify/issue_status_changed_email.text.erb b/app/views/notify/issue_status_changed_email.text.erb index 4200881f7e8a009086be96aac46dcc8b8b41accd..f38b09e98207dc5ebb73017f933af9894f35ded2 100644 --- a/app/views/notify/issue_status_changed_email.text.erb +++ b/app/views/notify/issue_status_changed_email.text.erb @@ -1,4 +1,4 @@ -Issue was <%= @issue_status %> by <%= @updated_by.name %> +Issue was <%= @issue_status %> by <%= sanitize_name(@updated_by.name) %> Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> diff --git a/app/views/notify/member_access_requested_email.text.erb b/app/views/notify/member_access_requested_email.text.erb index 9c5ee0eaf26a4a9f4c05d2e164c680f985b6aa1a..ddb4a7b3d2ce6a476ac6dc75d25e0a7be23bcb63 100644 --- a/app/views/notify/member_access_requested_email.text.erb +++ b/app/views/notify/member_access_requested_email.text.erb @@ -1,3 +1,3 @@ -<%= member.user.name %> (<%= user_url(member.user) %>) requested <%= member.human_access %> access to the <%= member_source.human_name %> <%= member_source.model_name.singular %>. +<%= sanitize_name(member.user.name) %> (<%= user_url(member.user) %>) requested <%= member.human_access %> access to the <%= member_source.human_name %> <%= member_source.model_name.singular %>. <%= polymorphic_url([member_source, :members]) %> diff --git a/app/views/notify/member_invite_accepted_email.text.erb b/app/views/notify/member_invite_accepted_email.text.erb index cef87101427e3310fc4d43f9cf10ef04325794cc..c824533eac24b6732e69f3d5d00cd83484a0e5f2 100644 --- a/app/views/notify/member_invite_accepted_email.text.erb +++ b/app/views/notify/member_invite_accepted_email.text.erb @@ -1,3 +1,3 @@ -<%= member.invite_email %>, now known as <%= member.user.name %>, has accepted your invitation to join the <%= member_source.human_name %> <%= member_source.model_name.singular %>. +<%= member.invite_email %>, now known as <%= sanitize_name(member.user.name) %>, has accepted your invitation to join the <%= member_source.human_name %> <%= member_source.model_name.singular %>. <%= member_source.web_url %> diff --git a/app/views/notify/member_invited_email.text.erb b/app/views/notify/member_invited_email.text.erb index 0a6393355be535c32ff49159e51ed7f413291dc1..d944c3b4a50379405951d8b0c18211b55d9e889c 100644 --- a/app/views/notify/member_invited_email.text.erb +++ b/app/views/notify/member_invited_email.text.erb @@ -1,4 +1,4 @@ -You have been invited <%= "by #{member.created_by.name} " if member.created_by %>to join the <%= member_source.human_name %> <%= member_source.model_name.singular %> as <%= member.human_access %>. +You have been invited <%= "by #{sanitize_name(member.created_by.name)} " if member.created_by %>to join the <%= member_source.human_name %> <%= member_source.model_name.singular %> as <%= member.human_access %>. Accept invitation: <%= invite_url(@token) %> Decline invitation: <%= decline_invite_url(@token) %> diff --git a/app/views/notify/merge_request_status_email.html.haml b/app/views/notify/merge_request_status_email.html.haml index b487e26b12208a6a3a9bba9c75b41f7626eb6458..ffb416abf72e3724f1459bbf092b47e5f9b7cbce 100644 --- a/app/views/notify/merge_request_status_email.html.haml +++ b/app/views/notify/merge_request_status_email.html.haml @@ -1,2 +1,2 @@ %p - Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{@updated_by.name} + Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{sanitize_name(@updated_by.name)} diff --git a/app/views/notify/merge_request_status_email.text.haml b/app/views/notify/merge_request_status_email.text.haml index ae2a29338651af37fbb7b7f893773d0a33c745a0..b9b9e0c3ad720b4ecdc26d9b42e3dfbc7d2993b4 100644 --- a/app/views/notify/merge_request_status_email.text.haml +++ b/app/views/notify/merge_request_status_email.text.haml @@ -1,8 +1,8 @@ -Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{@updated_by.name} +Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{sanitize_name(@updated_by.name)} Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} = merge_path_description(@merge_request, 'to') -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} +Author: #{sanitize_name(@merge_request.author_name)} +Assignee: #{sanitize_name(@merge_request.assignee_name)} diff --git a/app/views/notify/merge_request_unmergeable_email.text.haml b/app/views/notify/merge_request_unmergeable_email.text.haml index dcdd6db69d6dd45ce37a91aaf4356c8c5a82e32d..0c7bf1bb044ddc6cc852ba09232beb16993fe4ed 100644 --- a/app/views/notify/merge_request_unmergeable_email.text.haml +++ b/app/views/notify/merge_request_unmergeable_email.text.haml @@ -4,5 +4,5 @@ Merge Request url: #{project_merge_request_url(@merge_request.target_project, @m = merge_path_description(@merge_request, 'to') -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} +Author: #{sanitize_name(@merge_request.author_name)} +Assignee: #{sanitize_name(@merge_request.assignee_name)} diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml index 661c23bcbe20e678b6341ea30301f502fab1a8ad..045a43cbc8401a0f4e490bcdc8a7b912c08b0e3e 100644 --- a/app/views/notify/merged_merge_request_email.text.haml +++ b/app/views/notify/merged_merge_request_email.text.haml @@ -4,5 +4,5 @@ Merge Request url: #{project_merge_request_url(@merge_request.target_project, @m = merge_path_description(@merge_request, 'to') -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} +Author: #{sanitize_name(@merge_request.author_name)} +Assignee: #{sanitize_name(@merge_request.assignee_name)} diff --git a/app/views/notify/new_gpg_key_email.html.haml b/app/views/notify/new_gpg_key_email.html.haml index 4b9350c4e8820707901c95da3586568215f25fdb..b857705e01f5eed82e69dbd8c638cc9f68c1f54c 100644 --- a/app/views/notify/new_gpg_key_email.html.haml +++ b/app/views/notify/new_gpg_key_email.html.haml @@ -1,5 +1,5 @@ %p - Hi #{@user.name}! + Hi #{sanitize_name(@user.name)}! %p A new GPG key was added to your account: %p diff --git a/app/views/notify/new_gpg_key_email.text.erb b/app/views/notify/new_gpg_key_email.text.erb index 80b5a1fd7ff8f58bcd774ed65fcbc232ce57fb3f..92ea851eee4c0f24dcdd5a5833a4aadf4755f766 100644 --- a/app/views/notify/new_gpg_key_email.text.erb +++ b/app/views/notify/new_gpg_key_email.text.erb @@ -1,4 +1,4 @@ -Hi <%= @user.name %>! +Hi <%= sanitize_name(@user.name) %>! A new GPG key was added to your account: diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb index 3c716f772967e0375410fd85e9d52486b05cdae7..58a2bcbe5eb195d949181dd2b44b6a829fa20a46 100644 --- a/app/views/notify/new_issue_email.text.erb +++ b/app/views/notify/new_issue_email.text.erb @@ -1,7 +1,7 @@ New Issue was created. Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> -Author: <%= @issue.author_name %> +Author: <%= sanitize_name(@issue.author_name) %> Assignee: <%= @issue.assignee_list %> <%= @issue.description %> diff --git a/app/views/notify/new_mention_in_issue_email.text.erb b/app/views/notify/new_mention_in_issue_email.text.erb index 23213106c5b295fa77ee1f26e145c1532f25382f..173091e4a8058068c24acee93980f9d52e8a7200 100644 --- a/app/views/notify/new_mention_in_issue_email.text.erb +++ b/app/views/notify/new_mention_in_issue_email.text.erb @@ -1,7 +1,7 @@ You have been mentioned in an issue. Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> -Author: <%= @issue.author_name %> -Assignee: <%= @issue.assignee_list %> +Author: <%= sanitize_name(@issue.author_name) %> +Assignee: <%= sanitize_name(@issue.assignee_list) %> <%= @issue.description %> diff --git a/app/views/notify/new_mention_in_merge_request_email.text.erb b/app/views/notify/new_mention_in_merge_request_email.text.erb index 6fcebb22fc426c8e2897b77cafae0ea208f040e2..96a4f3f9eacc903f8d1548a40fc4d4df877d9dfb 100644 --- a/app/views/notify/new_mention_in_merge_request_email.text.erb +++ b/app/views/notify/new_mention_in_merge_request_email.text.erb @@ -3,7 +3,7 @@ You have been mentioned in Merge Request <%= @merge_request.to_reference %> <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> <%= merge_path_description(@merge_request, 'to') %> -Author: <%= @merge_request.author_name %> -Assignee: <%= @merge_request.assignee_name %> +Author: <%= sanitize_name(@merge_request.author_name) %> +Assignee: <%= sanitize_name(@merge_request.assignee_name) %> <%= @merge_request.description %> diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 5acd45b74a7dafeaf684b07376b9af4c860aa246..db23447dd392a7a97cdff7ac7602baa40ac55b13 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -7,7 +7,7 @@ - if @merge_request.assignee_id.present? %p - Assignee: #{@merge_request.assignee_name} + Assignee: #{sanitize_name(@merge_request.assignee_name)} = render_if_exists 'notify/merge_request_approvers', presenter: @mr_presenter diff --git a/app/views/notify/new_ssh_key_email.html.haml b/app/views/notify/new_ssh_key_email.html.haml index 63b0cbbd2051a7deaf9bb7519848f382ed15621f..d031842be956c5f49cef8d0f16382a2963afddcd 100644 --- a/app/views/notify/new_ssh_key_email.html.haml +++ b/app/views/notify/new_ssh_key_email.html.haml @@ -1,5 +1,5 @@ %p - Hi #{@user.name}! + Hi #{sanitize_name(@user.name)}! %p A new public key was added to your account: %p diff --git a/app/views/notify/new_ssh_key_email.text.erb b/app/views/notify/new_ssh_key_email.text.erb index 05b551c89a02cddd9826da2ac0aed6129fd9b9d9..690357d69ed8fa45fc59838a6226d51a8289d591 100644 --- a/app/views/notify/new_ssh_key_email.text.erb +++ b/app/views/notify/new_ssh_key_email.text.erb @@ -1,4 +1,4 @@ -Hi <%= @user.name %>! +Hi <%= sanitize_name(@user.name) %>! A new public key was added to your account: diff --git a/app/views/notify/new_user_email.html.haml b/app/views/notify/new_user_email.html.haml index db4424a01f939c3199628969bab2c27d0e1771f5..dfbb5c75bd3eca48fa4437a45824b15828b5c68c 100644 --- a/app/views/notify/new_user_email.html.haml +++ b/app/views/notify/new_user_email.html.haml @@ -1,5 +1,5 @@ %p - Hi #{@user['name']}! + Hi #{sanitize_name(@user['name'])}! %p - if Gitlab::CurrentSettings.allow_signup? Your account has been created successfully. diff --git a/app/views/notify/new_user_email.text.erb b/app/views/notify/new_user_email.text.erb index dd9b71e3b84f959957a56e2dd9584eb98499d62a..f3f20f3bfba04d54b887778a1ce2d1efdeada348 100644 --- a/app/views/notify/new_user_email.text.erb +++ b/app/views/notify/new_user_email.text.erb @@ -1,4 +1,4 @@ -Hi <%= @user.name %>! +Hi <%= sanitize_name(@user.name) %>! The Administrator created an account for you. Now you are a member of the company GitLab application. diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb index 294238eee5135c19e08e5078d9498639bc09cfe1..722eedf90be5286e40eec820920362a9bacd734c 100644 --- a/app/views/notify/pipeline_failed_email.text.erb +++ b/app/views/notify/pipeline_failed_email.text.erb @@ -10,20 +10,20 @@ Commit: <%= @pipeline.short_sha %> ( <%= commit_url(@pipeline) %> ) Commit Message: <%= @pipeline.git_commit_message.truncate(50) %> <% commit = @pipeline.commit -%> <% if commit.author -%> -Commit Author: <%= commit.author.name %> ( <%= user_url(commit.author) %> ) +Commit Author: <%= sanitize_name(commit.author.name) %> ( <%= user_url(commit.author) %> ) <% else -%> Commit Author: <%= commit.author_name %> <% end -%> <% if commit.different_committer? -%> <% if commit.committer -%> -Committed by: <%= commit.committer.name %> ( <%= user_url(commit.committer) %> ) +Committed by: <%= sanitize_name(commit.committer.name) %> ( <%= user_url(commit.committer) %> ) <% else -%> Committed by: <%= commit.committer_name %> <% end -%> <% end -%> <% if @pipeline.user -%> -Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= @pipeline.user.name %> ( <%= user_url(@pipeline.user) %> ) +Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> ) <% else -%> Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API <% end -%> diff --git a/app/views/notify/pipeline_success_email.text.erb b/app/views/notify/pipeline_success_email.text.erb index 39622cf7f0205e03588e5c55da5e36d0300c0d39..9aadf380f79bf681e6180ba381d360eb754d1c51 100644 --- a/app/views/notify/pipeline_success_email.text.erb +++ b/app/views/notify/pipeline_success_email.text.erb @@ -10,13 +10,13 @@ Commit: <%= @pipeline.short_sha %> ( <%= commit_url(@pipeline) %> ) Commit Message: <%= @pipeline.git_commit_message.truncate(50) %> <% commit = @pipeline.commit -%> <% if commit.author -%> -Commit Author: <%= commit.author.name %> ( <%= user_url(commit.author) %> ) +Commit Author: <%= sanitize_name(commit.author.name) %> ( <%= user_url(commit.author) %> ) <% else -%> Commit Author: <%= commit.author_name %> <% end -%> <% if commit.different_committer? -%> <% if commit.committer -%> -Committed by: <%= commit.committer.name %> ( <%= user_url(commit.committer) %> ) +Committed by: <%= sanitize_name(commit.committer.name) %> ( <%= user_url(commit.committer) %> ) <% else -%> Committed by: <%= commit.committer_name %> <% end -%> @@ -25,7 +25,7 @@ Committed by: <%= commit.committer_name %> <% job_count = @pipeline.total_size -%> <% stage_count = @pipeline.stages_count -%> <% if @pipeline.user -%> -Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= @pipeline.user.name %> ( <%= user_url(@pipeline.user) %> ) +Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> ) <% else -%> Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API <% end -%> diff --git a/app/views/notify/push_to_merge_request_email.html.haml b/app/views/notify/push_to_merge_request_email.html.haml index 67744ec1cee00c8619ec459a877224e2332401e0..97258833cfc83865ce335f3150dc6e3fb1937001 100644 --- a/app/views/notify/push_to_merge_request_email.html.haml +++ b/app/views/notify/push_to_merge_request_email.html.haml @@ -1,5 +1,5 @@ %h3 - = @updated_by_user.name + = sanitize_name(@updated_by_user.name) pushed new commits to merge request = link_to(@merge_request.to_reference, project_merge_request_url(@merge_request.target_project, @merge_request)) diff --git a/app/views/notify/push_to_merge_request_email.text.haml b/app/views/notify/push_to_merge_request_email.text.haml index 95759d127e2443c9806656df306ddd39ec71353b..10c8e158846f079baa10f7a13adc1bebb0f29ced 100644 --- a/app/views/notify/push_to_merge_request_email.text.haml +++ b/app/views/notify/push_to_merge_request_email.text.haml @@ -1,4 +1,4 @@ -#{@updated_by_user.name} pushed new commits to merge request #{@merge_request.to_reference} +#{sanitize_name(@updated_by_user.name)} pushed new commits to merge request #{@merge_request.to_reference} \ #{url_for(project_merge_request_url(@merge_request.target_project, @merge_request))} \ diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml index ee2f40e1683a4bebf787e0539ce49aab9cad0e48..6d25488a7e2ae42a9011b7fd8b703b3e04985ca4 100644 --- a/app/views/notify/reassigned_issue_email.html.haml +++ b/app/views/notify/reassigned_issue_email.html.haml @@ -2,7 +2,7 @@ Assignee changed - if @previous_assignees.any? from - %strong= @previous_assignees.map(&:name).to_sentence + %strong= sanitize_name(@previous_assignees.map(&:name).to_sentence) to - if @issue.assignees.any? %strong= @issue.assignee_list diff --git a/app/views/notify/reassigned_issue_email.text.erb b/app/views/notify/reassigned_issue_email.text.erb index 6c357f1074a4841690b76b9d05d7f4a2271d7c38..7bf2e8e6ce30b8c790c99dfa8b8b07ef23be9ceb 100644 --- a/app/views/notify/reassigned_issue_email.text.erb +++ b/app/views/notify/reassigned_issue_email.text.erb @@ -2,5 +2,5 @@ Reassigned Issue <%= @issue.iid %> <%= url_for([@issue.project.namespace.becomes(Namespace), @issue.project, @issue, { only_path: false }]) %> -Assignee changed <%= "from #{@previous_assignees.map(&:name).to_sentence}" if @previous_assignees.any? -%> +Assignee changed <%= "from #{sanitize_name(@previous_assignees.map(&:name).to_sentence)}" if @previous_assignees.any? -%> to <%= "#{@issue.assignees.any? ? @issue.assignee_list : 'Unassigned'}" %> diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml index 24c2b08810b45a4b2acbadc575434071ce2b16eb..e4f19bc3200d2448e200910051bda256b3c7554f 100644 --- a/app/views/notify/reassigned_merge_request_email.html.haml +++ b/app/views/notify/reassigned_merge_request_email.html.haml @@ -2,9 +2,9 @@ Assignee changed - if @previous_assignee from - %strong= @previous_assignee.name + %strong= sanitize_name(@previous_assignee.name) to - if @merge_request.assignee_id - %strong= @merge_request.assignee_name + %strong= sanitize_name(@merge_request.assignee_name) - else %strong Unassigned diff --git a/app/views/notify/reassigned_merge_request_email.text.erb b/app/views/notify/reassigned_merge_request_email.text.erb index 998a40fefdeb339c8fb684969635eb08c56475e3..96c770b521963c54b1fbeaa3eb27a3167907f572 100644 --- a/app/views/notify/reassigned_merge_request_email.text.erb +++ b/app/views/notify/reassigned_merge_request_email.text.erb @@ -2,5 +2,5 @@ Reassigned Merge Request <%= @merge_request.iid %> <%= url_for([@merge_request.project.namespace.becomes(Namespace), @merge_request.project, @merge_request, { only_path: false }]) %> -Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%> - to <%= "#{@merge_request.assignee_id ? @merge_request.assignee_name : 'Unassigned'}" %> +Assignee changed <%= "from #{sanitize_name(@previous_assignee.name)}" if @previous_assignee -%> + to <%= "#{@merge_request.assignee_id ? sanitize_name(@merge_request.assignee_name) : 'Unassigned'}" %> diff --git a/app/views/notify/resolved_all_discussions_email.html.haml b/app/views/notify/resolved_all_discussions_email.html.haml index 522421b7cc351d449faa60d0fbd91dea1cce9930..502b8f21e35d0e5ff7446eb521d00ce8ed61a92a 100644 --- a/app/views/notify/resolved_all_discussions_email.html.haml +++ b/app/views/notify/resolved_all_discussions_email.html.haml @@ -1,2 +1,2 @@ %p - All discussions on Merge Request #{@merge_request.to_reference} were resolved by #{@resolved_by.name} + All discussions on Merge Request #{@merge_request.to_reference} were resolved by #{sanitize_name(@resolved_by.name)} diff --git a/app/views/notify/resolved_all_discussions_email.text.erb b/app/views/notify/resolved_all_discussions_email.text.erb index 2881f3e699efe0b4ec7652c294300419946ceb54..c4b36bfe1a8bb43e6d8e9109da5fbc0aa4e33ffb 100644 --- a/app/views/notify/resolved_all_discussions_email.text.erb +++ b/app/views/notify/resolved_all_discussions_email.text.erb @@ -1,3 +1,3 @@ -All discussions on Merge Request <%= @merge_request.to_reference %> were resolved by <%= @resolved_by.name %> +All discussions on Merge Request <%= @merge_request.to_reference %> were resolved by <%= sanitize_name(@resolved_by.name) %> <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> diff --git a/changelogs/unreleased/security-22076-sanitize-url-in-names.yml b/changelogs/unreleased/security-22076-sanitize-url-in-names.yml new file mode 100644 index 0000000000000000000000000000000000000000..4e0ad4dd4c431bae585ecde38b13141c12447c24 --- /dev/null +++ b/changelogs/unreleased/security-22076-sanitize-url-in-names.yml @@ -0,0 +1,6 @@ +--- +title: Sanitize user full name to clean up any URL to prevent mail clients from auto-linking + URLs +merge_request: 2793 +author: +type: security diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index 3820cf5cb9d501f3716cc99595526be72fe7476e..23d7e41803e3012c399139308354097ff78cc972 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -1,6 +1,20 @@ require 'spec_helper' describe EmailsHelper do + describe 'sanitize_name' do + context 'when name contains a valid URL string' do + it 'returns name with `.` replaced with `_` to prevent mail clients from auto-linking URLs' do + expect(sanitize_name('https://about.gitlab.com')).to eq('https://about_gitlab_com') + expect(sanitize_name('www.gitlab.com')).to eq('www_gitlab_com') + expect(sanitize_name('//about.gitlab.com/handbook/security/#best-practices')).to eq('//about_gitlab_com/handbook/security/#best-practices') + end + + it 'returns name as it is when it does not contain a URL' do + expect(sanitize_name('Foo Bar')).to eq('Foo Bar') + end + end + end + describe 'password_reset_token_valid_time' do def validate_time_string(time_limit, expected_string) Devise.reset_password_within = time_limit diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index f2d99872401a2fb3dc8ca14091db047bf74ee486..ec3972ac8dbcd2311ed5ba62d2f74ccaf177774a 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -9,8 +9,10 @@ describe Notify do include_context 'gitlab email notification' + let(:current_user_sanitized) { 'www_example_com' } + set(:user) { create(:user) } - set(:current_user) { create(:user, email: "current@email.com") } + set(:current_user) { create(:user, email: "current@email.com", name: 'www.example.com') } set(:assignee) { create(:user, email: 'assignee@example.com', name: 'John Doe') } set(:merge_request) do @@ -182,7 +184,7 @@ describe Notify do aggregate_failures do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_body_text(status) - is_expected.to have_body_text(current_user.name) + is_expected.to have_body_text(current_user_sanitized) is_expected.to have_body_text(project_issue_path project, issue) end end @@ -361,7 +363,7 @@ describe Notify do aggregate_failures do is_expected.to have_referable_subject(merge_request, reply: true) is_expected.to have_body_text(status) - is_expected.to have_body_text(current_user.name) + is_expected.to have_body_text(current_user_sanitized) is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end