summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-29 12:57:02 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-29 12:57:02 +0000
commite0ab280b774e34fcfd6fd031616247714230ca68 (patch)
tree472ee2dcef05f242e1b861caa47a0a5179e92f4c /app
parent60b56b48afb89ed1890409b6c425f16549c4d28b (diff)
downloadgitlab-ce-e0ab280b774e34fcfd6fd031616247714230ca68.tar.gz
Add latest changes from gitlab-org/security/gitlab@14-3-stable-ee
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js33
-rw-r--r--app/controllers/admin/users_controller.rb6
-rw-r--r--app/controllers/concerns/impersonation.rb6
-rw-r--r--app/controllers/import/gitea_controller.rb6
-rw-r--r--app/controllers/profiles/passwords_controller.rb8
-rw-r--r--app/models/user.rb3
-rw-r--r--app/services/projects/destroy_service.rb11
-rw-r--r--app/views/projects/_export.html.haml1
8 files changed, 58 insertions, 16 deletions
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 470c785f7e4..cb63c86a4fa 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import '~/lib/utils/jquery_at_who';
-import { escape, sortBy, template } from 'lodash';
+import { escape as lodashEscape, sortBy, template } from 'lodash';
import * as Emoji from '~/emoji';
import axios from '~/lib/utils/axios_utils';
import { s__, __, sprintf } from '~/locale';
@@ -11,8 +11,21 @@ import { spriteIcon } from './lib/utils/common_utils';
import { parsePikadayDate } from './lib/utils/datetime_utility';
import glRegexp from './lib/utils/regexp';
-function sanitize(str) {
- return str.replace(/<(?:.|\n)*?>/gm, '');
+/**
+ * Escapes user input before we pass it to at.js, which
+ * renders it as HTML in the autocomplete dropdown.
+ *
+ * at.js allows you to reference data using `${}` syntax
+ * (e.g. ${search}) which it replaces with the actual data
+ * before rendering it in the autocomplete dropdown.
+ * To prevent user input from executing this `${}` syntax,
+ * we also need to escape the $ character.
+ *
+ * @param string user input
+ * @return {string} escaped user input
+ */
+function escape(string) {
+ return lodashEscape(string).replace(/\$/g, '&dollar;');
}
function createMemberSearchString(member) {
@@ -44,8 +57,8 @@ export function membersBeforeSave(members) {
return {
username: member.username,
avatarTag: autoCompleteAvatar.length === 1 ? txtAvatar : imgAvatar,
- title: sanitize(title),
- search: sanitize(createMemberSearchString(member)),
+ title,
+ search: createMemberSearchString(member),
icon: avatarIcon,
availability: member?.availability,
};
@@ -366,7 +379,7 @@ class GfmAutoComplete {
}
return {
id: i.iid,
- title: sanitize(i.title),
+ title: i.title,
reference: i.reference,
search: `${i.iid} ${i.title}`,
};
@@ -404,7 +417,7 @@ class GfmAutoComplete {
return {
id: m.iid,
- title: sanitize(m.title),
+ title: m.title,
search: m.title,
expired,
dueDate,
@@ -456,7 +469,7 @@ class GfmAutoComplete {
}
return {
id: m.iid,
- title: sanitize(m.title),
+ title: m.title,
reference: m.reference,
search: `${m.iid} ${m.title}`,
};
@@ -492,7 +505,7 @@ class GfmAutoComplete {
beforeSave(merges) {
if (GfmAutoComplete.isLoading(merges)) return merges;
return $.map(merges, (m) => ({
- title: sanitize(m.title),
+ title: m.title,
color: m.color,
search: m.title,
set: m.set,
@@ -586,7 +599,7 @@ class GfmAutoComplete {
}
return {
id: m.id,
- title: sanitize(m.title),
+ title: m.title,
search: `${m.id} ${m.title}`,
};
});
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 9c556d16913..55e03503ba9 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -45,7 +45,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def impersonate
- if can?(user, :log_in)
+ if can?(user, :log_in) && !impersonation_in_progress?
session[:impersonator_id] = current_user.id
warden.set_user(user, scope: :user)
@@ -57,7 +57,9 @@ class Admin::UsersController < Admin::ApplicationController
redirect_to root_path
else
flash[:alert] =
- if user.blocked?
+ if impersonation_in_progress?
+ _("You are already impersonating another user")
+ elsif user.blocked?
_("You cannot impersonate a blocked user")
elsif user.internal?
_("You cannot impersonate an internal user")
diff --git a/app/controllers/concerns/impersonation.rb b/app/controllers/concerns/impersonation.rb
index a4f2c263eb4..0764fbc8eb3 100644
--- a/app/controllers/concerns/impersonation.rb
+++ b/app/controllers/concerns/impersonation.rb
@@ -14,7 +14,7 @@ module Impersonation
protected
def check_impersonation_availability
- return unless session[:impersonator_id]
+ return unless impersonation_in_progress?
unless Gitlab.config.gitlab.impersonation_enabled
stop_impersonation
@@ -31,6 +31,10 @@ module Impersonation
current_user
end
+ def impersonation_in_progress?
+ session[:impersonator_id].present?
+ end
+
def log_impersonation_event
Gitlab::AppLogger.info("User #{impersonator.username} has stopped impersonating #{current_user.username}")
end
diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb
index 5a4eef352b8..32c9da67e90 100644
--- a/app/controllers/import/gitea_controller.rb
+++ b/app/controllers/import/gitea_controller.rb
@@ -66,11 +66,13 @@ class Import::GiteaController < Import::GithubController
override :client_options
def client_options
- { host: provider_url, api_version: 'v1' }
+ verified_url, provider_hostname = verify_blocked_uri
+
+ { host: verified_url.scheme == 'https' ? provider_url : verified_url.to_s, api_version: 'v1', hostname: provider_hostname }
end
def verify_blocked_uri
- Gitlab::UrlBlocker.validate!(
+ @verified_url_and_hostname ||= Gitlab::UrlBlocker.validate!(
provider_url,
allow_localhost: allow_local_requests?,
allow_local_network: allow_local_requests?,
diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb
index 85e901eb3eb..c8c2dd1c7d6 100644
--- a/app/controllers/profiles/passwords_controller.rb
+++ b/app/controllers/profiles/passwords_controller.rb
@@ -47,6 +47,8 @@ class Profiles::PasswordsController < Profiles::ApplicationController
password_attributes[:password_automatically_set] = false
unless @user.password_automatically_set || @user.valid_password?(user_params[:current_password])
+ handle_invalid_current_password_attempt!
+
redirect_to edit_profile_password_path, alert: _('You must provide a valid current password')
return
end
@@ -85,6 +87,12 @@ class Profiles::PasswordsController < Profiles::ApplicationController
render_404 unless @user.allow_password_authentication?
end
+ def handle_invalid_current_password_attempt!
+ Gitlab::AppLogger.info(message: 'Invalid current password when attempting to update user password', username: @user.username, ip: request.remote_ip)
+
+ @user.increment_failed_attempts!
+ end
+
def user_params
params.require(:user).permit(:current_password, :password, :password_confirmation)
end
diff --git a/app/models/user.rb b/app/models/user.rb
index b5f0251f639..a4c8d606911 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1883,7 +1883,8 @@ class User < ApplicationRecord
def password_expired_if_applicable?
return false if bot?
- return false unless password_expired? && password_automatically_set?
+ return false unless password_expired?
+ return false if password_automatically_set?
return false unless allow_password_authentication?
true
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index e27ea7c07e5..afa8de04fca 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -117,6 +117,7 @@ module Projects
trash_relation_repositories!
trash_project_repositories!
destroy_web_hooks!
+ destroy_project_bots!
# Rails attempts to load all related records into memory before
# destroying: https://github.com/rails/rails/issues/22510
@@ -149,6 +150,16 @@ module Projects
end
end
+ # The project can have multiple project bots with personal access tokens generated.
+ # We need to remove them when a project is deleted
+ # rubocop: disable CodeReuse/ActiveRecord
+ def destroy_project_bots!
+ project.members.includes(:user).references(:user).merge(User.project_bot).each do |member|
+ Users::DestroyService.new(current_user).execute(member.user, skip_authorization: true)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def remove_registry_tags
return true unless Gitlab.config.registry.enabled
return false unless remove_legacy_registry_tags
diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml
index eb4630b84d5..97f5cdb54e5 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -16,6 +16,7 @@
%li= _('Job logs and artifacts')
%li= _('Container registry images')
%li= _('CI variables')
+ %li= _('Pipeline triggers')
%li= _('Webhooks')
%li= _('Any encrypted tokens')
- if project.export_status == :finished