Skip to content
Snippets Groups Projects
Unverified Commit ad8eea38 authored by Yorick Peterse's avatar Yorick Peterse
Browse files

Merge dev.gitlab.org@master into GitLab.com@master

parents 228d752f b0f939a7
No related branches found
No related tags found
No related merge requests found
Showing
with 80 additions and 24 deletions
Loading
@@ -2,6 +2,24 @@
Loading
@@ -2,6 +2,24 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
   
## 12.4.1
### Security (12 changes)
- Standardize error response when route is missing.
- Do not display project labels that are not visible for user accessing group labels.
- Show cross-referenced label and milestones in issues' activities only to authorized users.
- Analyze incoming GraphQL queries and check for recursion.
- Disallow unprivileged users from commenting on private repository commits.
- Don't allow maintainers of a target project to delete the source branch of a merge request from a fork.
- Require Maintainer permission on group where project is transferred to.
- Don't leak private members in project member autocomplete suggestions.
- Return 404 on LFS request if project doesn't exist.
- Mask sentry auth token in Error Tracking dashboard.
- Fixes a Open Redirect issue in `InternalRedirect`.
- Sanitize all wiki markup formats with GitLab sanitization pipelines.
## 12.4.0 ## 12.4.0
   
### Security (14 changes) ### Security (14 changes)
Loading
Loading
Loading
@@ -5,6 +5,7 @@ import fuzzaldrinPlus from 'fuzzaldrin-plus';
Loading
@@ -5,6 +5,7 @@ import fuzzaldrinPlus from 'fuzzaldrin-plus';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import flash from '~/flash'; import flash from '~/flash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import sanitize from 'sanitize-html';
   
// highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> ) // highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
const highlighter = function(element, text, matches) { const highlighter = function(element, text, matches) {
Loading
@@ -74,7 +75,7 @@ export default class ProjectFindFile {
Loading
@@ -74,7 +75,7 @@ export default class ProjectFindFile {
   
findFile() { findFile() {
var result, searchText; var result, searchText;
searchText = this.inputElement.val(); searchText = sanitize(this.inputElement.val());
result = result =
searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths; searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
return this.renderList(result, searchText); return this.renderList(result, searchText);
Loading
Loading
Loading
@@ -17,7 +17,7 @@ class ApplicationController < ActionController::Base
Loading
@@ -17,7 +17,7 @@ class ApplicationController < ActionController::Base
include Gitlab::Tracking::ControllerConcern include Gitlab::Tracking::ControllerConcern
include Gitlab::Experimentation::ControllerConcern include Gitlab::Experimentation::ControllerConcern
   
before_action :authenticate_user! before_action :authenticate_user!, except: [:route_not_found]
before_action :enforce_terms!, if: :should_enforce_terms? before_action :enforce_terms!, if: :should_enforce_terms?
before_action :validate_user_service_ticket! before_action :validate_user_service_ticket!
before_action :check_password_expiration before_action :check_password_expiration
Loading
@@ -98,7 +98,9 @@ class ApplicationController < ActionController::Base
Loading
@@ -98,7 +98,9 @@ class ApplicationController < ActionController::Base
if current_user if current_user
not_found not_found
else else
authenticate_user! store_location_for(:user, request.fullpath) unless request.xhr?
redirect_to new_user_session_path, alert: I18n.t('devise.failure.unauthenticated')
end end
end end
   
Loading
Loading
Loading
@@ -6,7 +6,7 @@ module InternalRedirect
Loading
@@ -6,7 +6,7 @@ module InternalRedirect
def safe_redirect_path(path) def safe_redirect_path(path)
return unless path return unless path
# Verify that the string starts with a `/` and a known route character. # Verify that the string starts with a `/` and a known route character.
return unless path =~ %r{^/[-\w].*$} return unless path =~ %r{\A/[-\w].*\z}
   
uri = URI(path) uri = URI(path)
# Ignore anything path of the redirect except for the path, querystring and, # Ignore anything path of the redirect except for the path, querystring and,
Loading
Loading
Loading
@@ -34,6 +34,7 @@ module LfsRequest
Loading
@@ -34,6 +34,7 @@ module LfsRequest
end end
   
def lfs_check_access! def lfs_check_access!
return render_lfs_not_found unless project
return if download_request? && lfs_download_access? return if download_request? && lfs_download_access?
return if upload_request? && lfs_upload_access? return if upload_request? && lfs_upload_access?
   
Loading
Loading
Loading
@@ -51,7 +51,7 @@ class LabelsFinder < UnionFinder
Loading
@@ -51,7 +51,7 @@ class LabelsFinder < UnionFinder
end end
   
label_ids << Label.where(group_id: projects.group_ids) label_ids << Label.where(group_id: projects.group_ids)
label_ids << Label.where(project_id: projects.select(:id)) unless only_group_labels? label_ids << Label.where(project_id: ids_user_can_read_labels(projects)) unless only_group_labels?
end end
   
label_ids label_ids
Loading
@@ -188,4 +188,10 @@ class LabelsFinder < UnionFinder
Loading
@@ -188,4 +188,10 @@ class LabelsFinder < UnionFinder
groups.select { |group| authorized_to_read_labels?(group) } groups.select { |group| authorized_to_read_labels?(group) }
end end
end end
# rubocop: disable CodeReuse/ActiveRecord
def ids_user_can_read_labels(projects)
Project.where(id: projects.select(:id)).ids_with_issuables_available_for(current_user)
end
# rubocop: enable CodeReuse/ActiveRecord
end end
Loading
@@ -18,15 +18,15 @@ class GitlabSchema < GraphQL::Schema
Loading
@@ -18,15 +18,15 @@ class GitlabSchema < GraphQL::Schema
use Gitlab::Graphql::GenericTracing use Gitlab::Graphql::GenericTracing
   
query_analyzer Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer.new query_analyzer Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer.new
query_analyzer Gitlab::Graphql::QueryAnalyzers::RecursionAnalyzer.new
query(Types::QueryType)
default_max_page_size 100
   
max_complexity DEFAULT_MAX_COMPLEXITY max_complexity DEFAULT_MAX_COMPLEXITY
max_depth DEFAULT_MAX_DEPTH max_depth DEFAULT_MAX_DEPTH
   
mutation(Types::MutationType) query Types::QueryType
mutation Types::MutationType
default_max_page_size 100
   
class << self class << self
def multiplex(queries, **kwargs) def multiplex(queries, **kwargs)
Loading
Loading
Loading
@@ -133,15 +133,7 @@ module MarkupHelper
Loading
@@ -133,15 +133,7 @@ module MarkupHelper
issuable_state_filter_enabled: true issuable_state_filter_enabled: true
) )
   
html = html = markup_unsafe(wiki_page.path, text, context)
case wiki_page.format
when :markdown
markdown_unsafe(text, context)
when :asciidoc
asciidoc_unsafe(text)
else
wiki_page.formatted_content.html_safe
end
   
prepare_for_rendering(html, context) prepare_for_rendering(html, context)
end end
Loading
Loading
Loading
@@ -13,7 +13,9 @@ module Mentionable
Loading
@@ -13,7 +13,9 @@ module Mentionable
def self.other_patterns def self.other_patterns
[ [
Commit.reference_pattern, Commit.reference_pattern,
MergeRequest.reference_pattern MergeRequest.reference_pattern,
Label.reference_pattern,
Milestone.reference_pattern
] ]
end end
   
Loading
Loading
Loading
@@ -16,6 +16,7 @@ class Discussion
Loading
@@ -16,6 +16,7 @@ class Discussion
:commit_id, :commit_id,
:for_commit?, :for_commit?,
:for_merge_request?, :for_merge_request?,
:noteable_ability_name,
:to_ability_name, :to_ability_name,
:editable?, :editable?,
:visible_for?, :visible_for?,
Loading
Loading
Loading
@@ -8,6 +8,7 @@ class Member < ApplicationRecord
Loading
@@ -8,6 +8,7 @@ class Member < ApplicationRecord
include Gitlab::Access include Gitlab::Access
include Presentable include Presentable
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include FromUnion
   
attr_accessor :raw_invite_token attr_accessor :raw_invite_token
   
Loading
Loading
Loading
@@ -69,6 +69,14 @@ class MergeRequest < ApplicationRecord
Loading
@@ -69,6 +69,14 @@ class MergeRequest < ApplicationRecord
has_many :merge_request_assignees has_many :merge_request_assignees
has_many :assignees, class_name: "User", through: :merge_request_assignees has_many :assignees, class_name: "User", through: :merge_request_assignees
   
KNOWN_MERGE_PARAMS = [
:auto_merge_strategy,
:should_remove_source_branch,
:force_remove_source_branch,
:commit_message,
:squash_commit_message,
:sha
].freeze
serialize :merge_params, Hash # rubocop:disable Cop/ActiveRecordSerialize serialize :merge_params, Hash # rubocop:disable Cop/ActiveRecordSerialize
   
after_create :ensure_merge_request_diff after_create :ensure_merge_request_diff
Loading
Loading
Loading
@@ -261,6 +261,10 @@ class Milestone < ApplicationRecord
Loading
@@ -261,6 +261,10 @@ class Milestone < ApplicationRecord
group || project group || project
end end
   
def to_ability_name
model_name.singular
end
def group_milestone? def group_milestone?
group_id.present? group_id.present?
end end
Loading
Loading
Loading
@@ -361,6 +361,10 @@ class Note < ApplicationRecord
Loading
@@ -361,6 +361,10 @@ class Note < ApplicationRecord
end end
   
def to_ability_name def to_ability_name
model_name.singular
end
def noteable_ability_name
for_snippet? ? noteable.class.name.underscore : noteable_type.demodulize.underscore for_snippet? ? noteable.class.name.underscore : noteable_type.demodulize.underscore
end end
   
Loading
Loading
Loading
@@ -614,11 +614,11 @@ class Project < ApplicationRecord
Loading
@@ -614,11 +614,11 @@ class Project < ApplicationRecord
joins(:namespace).where(namespaces: { type: 'Group' }).select(:namespace_id) joins(:namespace).where(namespaces: { type: 'Group' }).select(:namespace_id)
end end
   
# Returns ids of projects with milestones available for given user # Returns ids of projects with issuables available for given user
# #
# Used on queries to find milestones which user can see # Used on queries to find milestones or labels which user can see
# For example: Milestone.where(project_id: ids_with_milestone_available_for(user)) # For example: Milestone.where(project_id: ids_with_issuables_available_for(user))
def ids_with_milestone_available_for(user) def ids_with_issuables_available_for(user)
with_issues_enabled = with_issues_available_for_user(user).select(:id) with_issues_enabled = with_issues_available_for_user(user).select(:id)
with_merge_requests_enabled = with_merge_requests_available_for_user(user).select(:id) with_merge_requests_enabled = with_merge_requests_available_for_user(user).select(:id)
   
Loading
@@ -1265,6 +1265,10 @@ class Project < ApplicationRecord
Loading
@@ -1265,6 +1265,10 @@ class Project < ApplicationRecord
end end
end end
   
def to_ability_name
model_name.singular
end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
def execute_hooks(data, hooks_scope = :push_hooks) def execute_hooks(data, hooks_scope = :push_hooks)
run_after_commit_or_now do run_after_commit_or_now do
Loading
Loading
Loading
@@ -10,6 +10,7 @@ class SystemNoteMetadata < ApplicationRecord
Loading
@@ -10,6 +10,7 @@ class SystemNoteMetadata < ApplicationRecord
commit cross_reference commit cross_reference
close duplicate close duplicate
moved merge moved merge
label milestone
].freeze ].freeze
   
ICON_TYPES = %w[ ICON_TYPES = %w[
Loading
Loading
Loading
@@ -121,6 +121,12 @@ class WikiPage
Loading
@@ -121,6 +121,12 @@ class WikiPage
@version ||= @page.version @version ||= @page.version
end end
   
def path
return unless persisted?
@path ||= @page.path
end
def versions(options = {}) def versions(options = {})
return [] unless persisted? return [] unless persisted?
   
Loading
Loading
Loading
@@ -4,4 +4,5 @@ class CommitPolicy < BasePolicy
Loading
@@ -4,4 +4,5 @@ class CommitPolicy < BasePolicy
delegate { @subject.project } delegate { @subject.project }
   
rule { can?(:download_code) }.enable :read_commit rule { can?(:download_code) }.enable :read_commit
rule { ~can?(:read_commit) }.prevent :create_note
end end
Loading
@@ -131,6 +131,8 @@ class GroupPolicy < BasePolicy
Loading
@@ -131,6 +131,8 @@ class GroupPolicy < BasePolicy
   
rule { owner | admin }.enable :read_statistics rule { owner | admin }.enable :read_statistics
   
rule { maintainer & can?(:create_projects) }.enable :transfer_projects
def access_level def access_level
return GroupMember::NO_ACCESS if @user.nil? return GroupMember::NO_ACCESS if @user.nil?
   
Loading
Loading
Loading
@@ -15,6 +15,8 @@ class NamespacePolicy < BasePolicy
Loading
@@ -15,6 +15,8 @@ class NamespacePolicy < BasePolicy
end end
   
rule { personal_project & ~can_create_personal_project }.prevent :create_projects rule { personal_project & ~can_create_personal_project }.prevent :create_projects
rule { (owner | admin) & can?(:create_projects) }.enable :transfer_projects
end end
   
NamespacePolicy.prepend_if_ee('EE::NamespacePolicy') NamespacePolicy.prepend_if_ee('EE::NamespacePolicy')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment