Skip to content
Snippets Groups Projects
Commit a74f1733 authored by GitLab Release Tools Bot's avatar GitLab Release Tools Bot
Browse files

Merge remote-tracking branch 'dev/12-5-stable' into 12-5-stable

parents 586bb7dc e307639f
No related branches found
No related tags found
No related merge requests found
Showing
with 141 additions and 29 deletions
Please view this file on the master branch, on stable branches it's out of date.
 
## 12.5.8
- No changes.
## 12.5.7
 
- No changes.
Loading
Loading
Loading
Loading
@@ -2,6 +2,42 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
 
## 12.5.9
### Security (1 change)
- Update workhorse to v8.14.2.
## 12.5.8
### Security (19 changes, 1 of them is from the community)
- Prevent gafana integration token from being displayed as a plain text to other project maintainers, by only displaying a masked version of it.
- Update rdoc to 6.1.2.
- Bump rubyzip to 2.0.0. (Utkarsh Gupta)
- Cleanup todos for users from a removed linked group.
- Disable access to last_pipeline in commits API for users without read permissions.
- Add constraint to group dependency proxy endpoint param.
- Limit number of AsciiDoc includes per document.
- Prevent API access for unconfirmed users.
- Enforce permission check when counting activity events.
- Update rack-cors to 1.0.6.
- Fix xss on frequent groups dropdown.
- Fix XSS vulnerability on custom project templates form.
- Protect internal CI builds from external overrides.
- ImportExport::ExportService to require admin_project permission.
- Make sure that only system notes where all references are visible to user are exposed in GraphQL API.
- Disable caching of repository/files/:file_path/raw API endpoint.
- Make cross-repository comparisons happen in the source repository.
- Update excon to 0.71.1 to fix CVE-2019-16779.
- Add workhorse request verification to package upload endpoints.
### Changed (1 change, 1 of them is from the community)
- Add template repository usage to the usage ping. !20126 (minghuan lei)
## 12.5.7
 
### Security (1 change)
Loading
Loading
8.14.1
8.14.2
Loading
Loading
@@ -64,7 +64,7 @@ gem 'u2f', '~> 0.2.1'
 
# GitLab Pages
gem 'validates_hostname', '~> 1.0.6'
gem 'rubyzip', '~> 1.3.0', require: 'zip'
gem 'rubyzip', '~> 2.0.0', require: 'zip'
# GitLab Pages letsencrypt support
gem 'acme-client', '~> 2.0.2'
 
Loading
Loading
@@ -141,7 +141,7 @@ gem 'gitlab-markup', '~> 1.7.0'
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
gem 'commonmarker', '~> 0.17'
gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~> 6.0'
gem 'rdoc', '~> 6.1.2'
gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
Loading
Loading
Loading
Loading
@@ -262,7 +262,7 @@ GEM
et-orbi (1.2.1)
tzinfo
eventmachine (1.2.7)
excon (0.62.0)
excon (0.71.1)
execjs (2.6.0)
expression_parser (0.9.0)
extended-markdown-filter (0.6.0)
Loading
Loading
@@ -760,7 +760,8 @@ GEM
rack (>= 0.4)
rack-attack (6.2.0)
rack (>= 1.0, < 3)
rack-cors (1.0.2)
rack-cors (1.0.6)
rack (>= 1.6.0)
rack-oauth2 (1.9.3)
activesupport
attr_required
Loading
Loading
@@ -817,7 +818,7 @@ GEM
ffi (>= 1.0.6)
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rdoc (6.0.4)
rdoc (6.1.2)
re2 (1.1.1)
recaptcha (4.13.1)
json
Loading
Loading
@@ -926,7 +927,7 @@ GEM
sexp_processor (~> 4.9)
rubyntlm (0.6.2)
rubypants (0.2.0)
rubyzip (1.3.0)
rubyzip (2.0.0)
rugged (0.28.3.1)
safe_yaml (1.0.4)
sanitize (4.6.6)
Loading
Loading
@@ -1295,7 +1296,7 @@ DEPENDENCIES
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
rdoc (~> 6.0)
rdoc (~> 6.1.2)
re2 (~> 1.1.1)
recaptcha (~> 4.11)
redis (~> 4.0)
Loading
Loading
@@ -1319,7 +1320,7 @@ DEPENDENCIES
ruby-prof (~> 1.0.0)
ruby-progressbar
ruby_parser (~> 3.8)
rubyzip (~> 1.3.0)
rubyzip (~> 2.0.0)
rugged (~> 0.28)
sanitize (~> 4.6)
sassc-rails (~> 2.1.0)
Loading
Loading
12.5.7-ee
12.5.9
Loading
Loading
@@ -5,7 +5,7 @@ import { GlLoadingIcon } from '@gitlab/ui';
import eventHub from '../event_hub';
import store from '../store/';
import { FREQUENT_ITEMS, STORAGE_KEY } from '../constants';
import { isMobile, updateExistingFrequentItem } from '../utils';
import { isMobile, updateExistingFrequentItem, sanitizeItem } from '../utils';
import FrequentItemsSearchInput from './frequent_items_search_input.vue';
import FrequentItemsList from './frequent_items_list.vue';
import frequentItemsMixin from './frequent_items_mixin';
Loading
Loading
@@ -64,7 +64,9 @@ export default {
this.fetchFrequentItems();
}
},
logItemAccess(storageKey, item) {
logItemAccess(storageKey, unsanitizedItem) {
const item = sanitizeItem(unsanitizedItem);
if (!AccessorUtilities.isLocalStorageAccessSafe()) {
return false;
}
Loading
Loading
<script>
import FrequentItemsListItem from './frequent_items_list_item.vue';
import frequentItemsMixin from './frequent_items_mixin';
import { sanitizeItem } from '../utils';
 
export default {
components: {
Loading
Loading
@@ -48,6 +49,9 @@ export default {
? this.translations.itemListErrorMessage
: this.translations.itemListEmptyMessage;
},
sanitizedItems() {
return this.items.map(sanitizeItem);
},
},
};
</script>
Loading
Loading
@@ -59,7 +63,7 @@ export default {
{{ listEmptyMessage }}
</li>
<frequent-items-list-item
v-for="item in items"
v-for="item in sanitizedItems"
v-else
:key="item.id"
:item-id="item.id"
Loading
Loading
import _ from 'underscore';
import bp from '~/breakpoints';
import sanitize from 'sanitize-html';
import { FREQUENT_ITEMS, HOUR_IN_MS } from './constants';
 
export const isMobile = () => {
Loading
Loading
@@ -47,3 +48,9 @@ export const updateExistingFrequentItem = (frequentItem, item) => {
lastAccessedOn: accessedOverHourAgo ? Date.now() : frequentItem.lastAccessedOn,
};
};
export const sanitizeItem = item => ({
...item,
name: sanitize(item.name.toString(), { allowedTags: [] }),
namespace: sanitize(item.namespace.toString(), { allowedTags: [] }),
});
import $ from 'jquery';
import axios from './lib/utils/axios_utils';
import Api from './api';
import { escape } from 'lodash';
import { normalizeHeaders } from './lib/utils/common_utils';
import { __ } from '~/locale';
 
Loading
Loading
@@ -75,10 +76,12 @@ const groupsSelect = () => {
}
},
formatResult(object) {
return `<div class='group-result'> <div class='group-name'>${object.full_name}</div> <div class='group-path'>${object.full_path}</div> </div>`;
return `<div class='group-result'> <div class='group-name'>${escape(
object.full_name,
)}</div> <div class='group-path'>${object.full_path}</div> </div>`;
},
formatSelection(object) {
return object.full_name;
return escape(object.full_name);
},
dropdownCssClass: 'ajax-groups-dropdown select2-infinite',
// we do not want to escape markup since we are displaying html in results
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ require 'fogbugz'
 
class ApplicationController < ActionController::Base
include Gitlab::GonHelper
include Gitlab::NoCacheHeaders
include GitlabRoutingHelper
include PageLayoutHelper
include SafeParamsHelper
Loading
Loading
@@ -54,7 +55,6 @@ class ApplicationController < ActionController::Base
# Adds `no-store` to the DEFAULT_CACHE_CONTROL, to prevent security
# concerns due to caching private data.
DEFAULT_GITLAB_CACHE_CONTROL = "#{ActionDispatch::Http::Cache::Response::DEFAULT_CACHE_CONTROL}, no-store"
DEFAULT_GITLAB_CONTROL_NO_CACHE = "#{DEFAULT_GITLAB_CACHE_CONTROL}, no-cache"
 
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
Loading
Loading
@@ -238,9 +238,9 @@ class ApplicationController < ActionController::Base
end
 
def no_cache_headers
headers['Cache-Control'] = DEFAULT_GITLAB_CONTROL_NO_CACHE
headers['Pragma'] = 'no-cache' # HTTP 1.0 compatibility
headers['Expires'] = 'Fri, 01 Jan 1990 00:00:00 GMT'
DEFAULT_GITLAB_NO_CACHE_HEADERS.each do |k, v|
headers[k] = v
end
end
 
def default_headers
Loading
Loading
Loading
Loading
@@ -19,7 +19,7 @@ class DashboardController < Dashboard::ApplicationController
 
format.json do
load_events
pager_json("events/_events", @events.count)
pager_json('events/_events', @events.count { |event| event.visible_to_user?(current_user) })
end
end
end
Loading
Loading
@@ -37,6 +37,7 @@ class DashboardController < Dashboard::ApplicationController
@events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a
.map(&:present)
 
Events::RenderService.new(current_user).execute(@events)
end
Loading
Loading
Loading
Loading
@@ -91,7 +91,7 @@ class GroupsController < Groups::ApplicationController
 
format.json do
load_events
pager_json("events/_events", @events.count)
pager_json("events/_events", @events.count { |event| event.visible_to_user?(current_user) })
end
end
end
Loading
Loading
@@ -208,8 +208,9 @@ class GroupsController < Groups::ApplicationController
.includes(:namespace)
 
@events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter, groups: groups)
.to_a
.new(projects, offset: params[:offset].to_i, filter: event_filter, groups: groups)
.to_a
.map(&:present)
 
Events::RenderService
.new(current_user)
Loading
Loading
Loading
Loading
@@ -116,7 +116,7 @@ class ProjectsController < Projects::ApplicationController
format.html
format.json do
load_events
pager_json('events/_events', @events.count)
pager_json('events/_events', @events.count { |event| event.visible_to_user?(current_user) })
end
end
end
Loading
Loading
@@ -337,6 +337,7 @@ class ProjectsController < Projects::ApplicationController
@events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a
.map(&:present)
 
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end
Loading
Loading
Loading
Loading
@@ -365,8 +365,8 @@ module ProjectsHelper
@project.grafana_integration&.grafana_url
end
 
def grafana_integration_token
@project.grafana_integration&.token
def grafana_integration_masked_token
@project.grafana_integration&.masked_token
end
 
def grafana_integration_enabled?
Loading
Loading
# frozen_string_literal: true
 
class GenericCommitStatus < CommitStatus
EXTERNAL_STAGE_IDX = 1_000_000
before_validation :set_default_values
 
validates :target_url, addressable_url: true,
length: { maximum: 255 },
allow_nil: true
validate :name_uniqueness_across_types, unless: :importing?
 
# GitHub compatible API
alias_attribute :context, :name
Loading
Loading
@@ -13,7 +16,7 @@ class GenericCommitStatus < CommitStatus
def set_default_values
self.context ||= 'default'
self.stage ||= 'external'
self.stage_idx ||= 1000000
self.stage_idx ||= EXTERNAL_STAGE_IDX
end
 
def tags
Loading
Loading
@@ -25,4 +28,14 @@ class GenericCommitStatus < CommitStatus
.new(self, current_user)
.fabricate!
end
private
def name_uniqueness_across_types
return if !pipeline || name.blank?
if pipeline.statuses.where(name: name).where.not(type: type).exists?
errors.add(:name, :taken)
end
end
end
Loading
Loading
@@ -8,11 +8,13 @@ class GrafanaIntegration < ApplicationRecord
algorithm: 'aes-256-gcm',
key: Settings.attr_encrypted_db_key_base_32
 
before_validation :check_token_changes
validates :grafana_url,
length: { maximum: 1024 },
addressable_url: { enforce_sanitization: true, ascii_only: true }
 
validates :token, :project, presence: true
validates :encrypted_token, :project, presence: true
 
validates :enabled, inclusion: { in: [true, false] }
 
Loading
Loading
@@ -23,4 +25,28 @@ class GrafanaIntegration < ApplicationRecord
 
@client ||= ::Grafana::Client.new(api_url: grafana_url.chomp('/'), token: token)
end
def masked_token
mask(encrypted_token)
end
def masked_token_was
mask(encrypted_token_was)
end
private
def token
decrypt(:token, encrypted_token)
end
def check_token_changes
return unless [encrypted_token_was, masked_token_was].include?(token)
clear_attribute_changes [:token, :encrypted_token, :encrypted_token_iv]
end
def mask(token)
token&.squish&.gsub(/./, '*')
end
end
Loading
Loading
@@ -537,7 +537,8 @@ class Note < ApplicationRecord
# if they are not equal, then there are private/confidential references as well
user_visible_reference_count > 0 && user_visible_reference_count == total_reference_count
else
referenced_mentionables(user).any?
refs = all_references(user)
refs.all.any? && refs.stateful_not_visible_counter == 0
end
end
 
Loading
Loading
Loading
Loading
@@ -2274,6 +2274,10 @@ class Project < ApplicationRecord
end
end
 
def template_source?
false
end
private
 
def closest_namespace_setting(name)
Loading
Loading
Loading
Loading
@@ -21,6 +21,14 @@ class BasePolicy < DeclarativePolicy::Base
with_options scope: :user, score: 0
condition(:deactivated) { @user&.deactivated? }
 
desc "User email is unconfirmed or user account is locked"
with_options scope: :user, score: 0
condition(:inactive) do
Feature.enabled?(:inactive_policy_condition, default_enabled: true) &&
@user &&
!@user&.active_for_authentication?
end
with_options scope: :user, score: 0
condition(:external_user) { @user.nil? || @user.external? }
 
Loading
Loading
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