Commit b7a47b15 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/security/gitlab@13-9-stable-ee

parent fa206403
# frozen_string_literal: true
module WikiPageVersionHelper
def wiki_page_version_author_url(wiki_page_version)
user = wiki_page_version.author
user.nil? ? "mailto:#{wiki_page_version.author_email}" : Gitlab::UrlBuilder.build(user)
end
def wiki_page_version_author_avatar(wiki_page_version)
image_tag(avatar_icon_for_email(wiki_page_version.author_email, 24), class: "avatar s24 float-none gl-mr-0!")
end
def wiki_page_version_author_header(wiki_page_version)
avatar = wiki_page_version_author_avatar(wiki_page_version)
name = "<strong>".html_safe + wiki_page_version.author_name + "</strong>".html_safe
link_start = "<a href='".html_safe + wiki_page_version_author_url(wiki_page_version) + "'>".html_safe
html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: avatar, name: name, link_start: link_start, link_end: '</a>'.html_safe }
end
end
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.nav-text.flex-fill .nav-text.flex-fill
%span.wiki-last-edit-by %span.wiki-last-edit-by
- if @page.last_version - if @page.last_version
= html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: image_tag(avatar_icon_for_email(@page.last_version.author_email, 24), class: "avatar s24 float-none gl-mr-0!"), name: "<strong>#{@page.last_version.author_name}</strong>".html_safe, link_start: "<a href='#{@page.last_version.author_url}'>".html_safe, link_end: '</a>'.html_safe } = wiki_page_version_author_header(@page.last_version)
= time_ago_with_tooltip(@page.last_version.authored_date) = time_ago_with_tooltip(@page.last_version.authored_date)
.nav-controls.pb-md-3.pb-lg-0 .nav-controls.pb-md-3.pb-lg-0
......
---
title: Fix XSS in wiki author email and name
merge_request:
author:
type: security
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
module Gitlab module Gitlab
module Git module Git
class WikiPageVersion class WikiPageVersion
include Gitlab::Utils::StrongMemoize
attr_reader :commit, :format attr_reader :commit, :format
def initialize(commit, format) def initialize(commit, format)
...@@ -12,9 +14,10 @@ module Gitlab ...@@ -12,9 +14,10 @@ module Gitlab
delegate :message, :sha, :id, :author_name, :author_email, :authored_date, to: :commit delegate :message, :sha, :id, :author_name, :author_email, :authored_date, to: :commit
def author_url def author
user = ::User.find_by_any_email(author_email) strong_memoize(:author) do
user.nil? ? "mailto:#{author_email}" : Gitlab::UrlBuilder.build(user) ::User.find_by_any_email(author_email)
end
end end
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe WikiPageVersionHelper do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user, username: 'foo') }
let(:commit_with_user) { create(:commit, project: project, author: user)}
let(:commit_without_user) { create(:commit, project: project, author_name: 'Foo', author_email: 'foo@example.com')}
let(:wiki_page_version) { Gitlab::Git::WikiPageVersion.new(commit, nil) }
describe '#wiki_page_version_author_url' do
subject { helper.wiki_page_version_author_url(wiki_page_version) }
context 'when user exists' do
let(:commit) { commit_with_user }
it 'returns the link to the user profile' do
expect(subject).to eq('http://localhost/foo')
end
end
context 'when user does not exist' do
let(:commit) { commit_without_user }
it 'returns the mailto link' do
expect(subject).to eq "mailto:#{commit_without_user.author_email}"
end
end
end
describe '#wiki_page_version_author_avatar' do
let(:commit) { commit_with_user }
subject { helper.wiki_page_version_author_avatar(wiki_page_version) }
it 'returns the user avatar', :aggregate_failures do
avatar = Nokogiri::HTML.parse(subject)
expect(avatar.css('img')[0].attr('class')).to eq('avatar s24 float-none gl-mr-0! lazy')
expect(avatar.css('img')[0].attr('data-src')).not_to be_empty
expect(avatar.css('img')[0].attr('src')).not_to be_empty
end
end
describe '#wiki_page_version_author_header', :aggregate_failures do
let(:commit_with_xss) { create(:commit, project: project, author_email: "#' style=animation-name:blinking-dot onanimationstart=alert(document.domain) other", author_name: "<i>foo</i>") }
let(:header) { Nokogiri::HTML.parse(subject) }
subject { helper.wiki_page_version_author_header(wiki_page_version) }
context 'when user exists' do
let(:commit) { commit_with_user }
it 'renders commit header with user info' do
expect(header.css('a')[0].attr('href')).to eq("http://localhost/foo")
expect(header.css('a')[0].children[2].to_s).to eq("<strong>#{user.name}</strong>")
end
end
context 'when user does not exist' do
let(:commit) { commit_without_user }
it 'renders commit header with info from commit' do
expect(header.css('a')[0].attr('href')).to eq("mailto:#{commit.author_email}")
expect(header.css('a')[0].children[2].to_s).to eq("<strong>#{wiki_page_version.author_name}</strong>")
end
end
context 'when user info has XSS' do
let(:commit) { commit_with_xss }
it 'sets the right href and escapes HTML chars' do
expect(header.css('a')[0].attr('href')).to eq("mailto:#{commit.author_email}")
expect(header.css('a')[0].children[2].to_s).to eq("<strong>&lt;i&gt;foo&lt;/i&gt;</strong>")
end
end
end
end
...@@ -4,24 +4,24 @@ require 'spec_helper' ...@@ -4,24 +4,24 @@ require 'spec_helper'
RSpec.describe Gitlab::Git::WikiPageVersion do RSpec.describe Gitlab::Git::WikiPageVersion do
let_it_be(:project) { create(:project, :public, :repository) } let_it_be(:project) { create(:project, :public, :repository) }
let(:user) { create(:user, username: 'someone') } let_it_be(:user) { create(:user, username: 'someone') }
describe '#author_url' do describe '#author' do
subject(:author_url) { described_class.new(commit, nil).author_url } subject(:author) { described_class.new(commit, nil).author }
context 'user exists in gitlab' do context 'user exists in gitlab' do
let(:commit) { create(:commit, project: project, author: user) } let(:commit) { create(:commit, project: project, author: user) }
it 'returns the profile link of the user' do it 'returns the user' do
expect(author_url).to eq('http://localhost/someone') expect(author).to eq user
end end
end end
context 'user does not exist in gitlab' do context 'user does not exist in gitlab' do
let(:commit) { create(:commit, project: project, author_email: "someone@somewebsite.com") } let(:commit) { create(:commit, project: project, author_email: "someone@somewebsite.com") }
it 'returns a mailto: url' do it 'returns nil' do
expect(author_url).to eq('mailto:someone@somewebsite.com') expect(author).to be_nil
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment