summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Artur <felipefac@gmail.com>2018-07-26 18:30:50 -0300
committerFelipe Artur <felipefac@gmail.com>2018-07-26 18:30:50 -0300
commit13ea4b387ddcee5f5e8a59ac90dc9e485f4242f5 (patch)
treeea588d7aecbaa8868f23addf50748a14d167e342
parentcaeb4597a5b24e0eaa96b24901ce9208c2eef4bf (diff)
parent45c94aba1b90dbe86c5583c8782cc3f624249fa1 (diff)
downloadgitlab-ce-13ea4b387ddcee5f5e8a59ac90dc9e485f4242f5.tar.gz
Merge remote-tracking branch 'dev/master'
-rw-r--r--CHANGELOG.md32
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/actions.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/graph_component.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/graph/stage_column_component.vue3
-rw-r--r--app/controllers/projects/labels_controller.rb11
-rw-r--r--app/controllers/projects/milestones_controller.rb11
-rw-r--r--app/helpers/hooks_helper.rb2
-rw-r--r--app/models/remote_mirror.rb6
-rw-r--r--app/models/repository.rb2
-rw-r--r--app/views/projects/jobs/_sidebar.html.haml2
-rw-r--r--app/workers/concerns/gitlab/github_import/object_importer.rb2
-rw-r--r--app/workers/repository_fork_worker.rb4
-rw-r--r--app/workers/repository_import_worker.rb4
-rw-r--r--changelogs/unreleased/48617-promoting-milestone.yml5
-rw-r--r--changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml5
-rw-r--r--changelogs/unreleased/security-ide-branch-name-xss.yml5
-rw-r--r--changelogs/unreleased/sh-revert-markdown-changes.yml5
-rw-r--r--config/routes/admin.rb2
-rw-r--r--config/routes/project.rb2
-rw-r--r--lib/api/runner.rb6
-rw-r--r--lib/gitlab/email/handler/create_issue_handler.rb4
-rw-r--r--lib/gitlab/email/handler/create_merge_request_handler.rb4
-rw-r--r--lib/gitlab/email/handler/create_note_handler.rb4
-rw-r--r--lib/gitlab/email/handler/unsubscribe_handler.rb4
-rw-r--r--lib/gitlab/github_import/importer/pull_requests_importer.rb2
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb8
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb8
-rw-r--r--spec/features/projects/jobs_spec.rb14
-rw-r--r--spec/javascripts/fixtures/graph.html.haml1
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/actions_spec.js8
-rw-r--r--spec/javascripts/pipelines/graph/dropdown_job_component_spec.js93
-rw-r--r--spec/javascripts/pipelines/graph/graph_component_spec.js43
-rw-r--r--spec/javascripts/pipelines/graph/job_component_spec.js26
-rw-r--r--spec/javascripts/pipelines/graph/mock_data.js2
-rw-r--r--spec/javascripts/pipelines/graph/stage_column_component_spec.js37
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb1
-rw-r--r--spec/routing/admin_routing_spec.rb2
-rw-r--r--spec/routing/project_routing_spec.rb2
-rw-r--r--spec/workers/concerns/gitlab/github_import/object_importer_spec.rb1
-rw-r--r--spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_import/import_issue_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_import/import_note_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb1
45 files changed, 303 insertions, 89 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7cc047c40ed..8ba36bbad7b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,24 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.1.2 (2018-07-26)
+
+### Security (4 changes)
+
+- Adding CSRF protection to Hooks test action.
+- Don't expose project names in GitHub counters.
+- Don't expose project names in various counters.
+- Fixed XSS in branch name in Web IDE.
+
+### Fixed (1 change)
+
+- Escapes milestone and label's names on flash notice when promoting them.
+
+### Performance (1 change)
+
+- Fix slow Markdown rendering. !20820
+
+
## 11.1.1 (2018-07-23)
### Fixed (2 changes)
@@ -253,6 +271,20 @@ entry.
- Use monospaced font for MR diff commit link ref on GFM.
+## 11.0.5 (2018-07-26)
+
+### Security (4 changes)
+
+- Don't expose project names in various counters.
+- Don't expose project names in GitHub counters.
+- Adding CSRF protection to Hooks test action.
+- Fixed XSS in branch name in Web IDE.
+
+### Fixed (1 change)
+
+- Escapes milestone and label's names on flash notice when promoting them.
+
+
## 11.0.4 (2018-07-17)
### Security (1 change)
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
index eb7cb9745ec..a8b5c7a16d0 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
@@ -1,4 +1,5 @@
<script>
+import _ from 'underscore';
import { mapActions, mapState, mapGetters } from 'vuex';
import { sprintf, __ } from '~/locale';
import * as consts from '../../stores/modules/commit/constants';
@@ -14,7 +15,7 @@ export default {
commitToCurrentBranchText() {
return sprintf(
__('Commit to %{branchName} branch'),
- { branchName: `<strong class="monospace">${this.currentBranchId}</strong>` },
+ { branchName: `<strong class="monospace">${_.escape(this.currentBranchId)}</strong>` },
false,
);
},
diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
index c32dc83da8e..14518f86dc7 100644
--- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
@@ -1,5 +1,6 @@
<script>
import $ from 'jquery';
+import _ from 'underscore';
import JobNameComponent from './job_name_component.vue';
import JobComponent from './job_component.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
@@ -46,7 +47,7 @@ export default {
computed: {
tooltipText() {
- return `${this.job.name} - ${this.job.status.label}`;
+ return _.escape(`${this.job.name} - ${this.job.status.label}`);
},
},
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
index 4ec67f6c01b..1952dd453f4 100644
--- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
@@ -1,4 +1,5 @@
<script>
+import _ from 'underscore';
import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
import StageColumnComponent from './stage_column_component.vue';
@@ -26,7 +27,8 @@ export default {
methods: {
capitalizeStageName(name) {
- return name.charAt(0).toUpperCase() + name.slice(1);
+ const escapedName = _.escape(name);
+ return escapedName.charAt(0).toUpperCase() + escapedName.slice(1);
},
isFirstColumn(index) {
diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue
index 8af984ef91a..84a3d58b770 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue
@@ -1,4 +1,5 @@
<script>
+import _ from 'underscore';
import ActionComponent from './action_component.vue';
import JobNameComponent from './job_name_component.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
@@ -61,7 +62,7 @@ export default {
const textBuilder = [];
if (this.job.name) {
- textBuilder.push(this.job.name);
+ textBuilder.push(_.escape(this.job.name));
}
if (this.job.name && this.status.tooltip) {
@@ -69,7 +70,7 @@ export default {
}
if (this.status.tooltip) {
- textBuilder.push(`${this.job.status.tooltip}`);
+ textBuilder.push(this.job.status.tooltip);
}
return textBuilder.join(' ');
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
index 2c728582b7c..e7b2de52f76 100644
--- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
@@ -1,4 +1,5 @@
<script>
+import _ from 'underscore';
import JobComponent from './job_component.vue';
import DropdownJobComponent from './dropdown_job_component.vue';
@@ -37,7 +38,7 @@ export default {
},
jobId(job) {
- return `ci-badge-${job.name}`;
+ return `ci-badge-${_.escape(job.name)}`;
},
buildConnnectorClass(index) {
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index 21d3c918581..ce03b2d8d1d 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -112,7 +112,7 @@ class Projects::LabelsController < Projects::ApplicationController
begin
return render_404 unless promote_service.execute(@label)
- flash[:notice] = "#{@label.title} promoted to <a href=\"#{group_labels_path(@project.group)}\">group label</a>.".html_safe
+ flash[:notice] = flash_notice_for(@label, @project.group)
respond_to do |format|
format.html do
redirect_to(project_labels_path(@project), status: :see_other)
@@ -135,6 +135,15 @@ class Projects::LabelsController < Projects::ApplicationController
end
end
+ def flash_notice_for(label, group)
+ notice = ''.html_safe
+ notice << label.title
+ notice << ' promoted to '
+ notice << view_context.link_to('<u>group label</u>'.html_safe, group_labels_path(group))
+ notice << '.'
+ notice
+ end
+
protected
def label_params
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 5e86ec93f34..b9b3dcd5a85 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -76,8 +76,8 @@ class Projects::MilestonesController < Projects::ApplicationController
def promote
promoted_milestone = Milestones::PromoteService.new(project, current_user).execute(milestone)
+ flash[:notice] = flash_notice_for(promoted_milestone, project.group)
- flash[:notice] = "#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, promoted_milestone.iid)}\"><u>group milestone</u></a>.".html_safe
respond_to do |format|
format.html do
redirect_to project_milestones_path(project)
@@ -90,6 +90,15 @@ class Projects::MilestonesController < Projects::ApplicationController
redirect_to milestone, alert: error.message
end
+ def flash_notice_for(milestone, group)
+ notice = ''.html_safe
+ notice << milestone.title
+ notice << ' promoted to '
+ notice << view_context.link_to('<u>group milestone</u>'.html_safe, group_milestone_path(group, milestone.iid))
+ notice << '.'
+ notice
+ end
+
def destroy
return access_denied! unless can?(current_user, :admin_milestone, @project)
diff --git a/app/helpers/hooks_helper.rb b/app/helpers/hooks_helper.rb
index 551b9cca6b1..0a356ba55d2 100644
--- a/app/helpers/hooks_helper.rb
+++ b/app/helpers/hooks_helper.rb
@@ -10,7 +10,7 @@ module HooksHelper
trigger_human_name = trigger.to_s.tr('_', ' ').camelize
- link_to path, rel: 'nofollow' do
+ link_to path, rel: 'nofollow', method: :post do
content_tag(:span, trigger_human_name)
end
end
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 976b501e297..6172bb38881 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -48,13 +48,13 @@ class RemoteMirror < ActiveRecord::Base
state :failed
after_transition any => :started do |remote_mirror, _|
- Gitlab::Metrics.add_event(:remote_mirrors_running, path: remote_mirror.project.full_path)
+ Gitlab::Metrics.add_event(:remote_mirrors_running)
remote_mirror.update(last_update_started_at: Time.now)
end
after_transition started: :finished do |remote_mirror, _|
- Gitlab::Metrics.add_event(:remote_mirrors_finished, path: remote_mirror.project.full_path)
+ Gitlab::Metrics.add_event(:remote_mirrors_finished)
timestamp = Time.now
remote_mirror.update!(
@@ -63,7 +63,7 @@ class RemoteMirror < ActiveRecord::Base
end
after_transition started: :failed do |remote_mirror, _|
- Gitlab::Metrics.add_event(:remote_mirrors_failed, path: remote_mirror.project.full_path)
+ Gitlab::Metrics.add_event(:remote_mirrors_failed)
remote_mirror.update(last_update_at: Time.now)
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index e248f94cbd8..9873d9a6327 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1029,7 +1029,7 @@ class Repository
end
def repository_event(event, tags = {})
- Gitlab::Metrics.add_event(event, { path: full_path }.merge(tags))
+ Gitlab::Metrics.add_event(event, tags)
end
def initialize_raw_repository
diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml
index b88fe47726d..64c441492bc 100644
--- a/app/views/projects/jobs/_sidebar.html.haml
+++ b/app/views/projects/jobs/_sidebar.html.haml
@@ -86,7 +86,7 @@
- HasStatus::ORDERED_STATUSES.each do |build_status|
- builds.select{|build| build.status == build_status}.each do |build|
.build-job{ class: sidebar_build_class(build, @build), data: { stage: build.stage } }
- - tooltip = build.tooltip_message
+ - tooltip = sanitize(build.tooltip_message)
= link_to(project_job_path(@project, build), data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' }) do
= sprite_icon('arrow-right', size:16, css_class: 'icon-arrow-right')
%span{ class: "ci-status-icon-#{build.status}" }
diff --git a/app/workers/concerns/gitlab/github_import/object_importer.rb b/app/workers/concerns/gitlab/github_import/object_importer.rb
index 100d86e38c8..eeeff6e93a0 100644
--- a/app/workers/concerns/gitlab/github_import/object_importer.rb
+++ b/app/workers/concerns/gitlab/github_import/object_importer.rb
@@ -22,7 +22,7 @@ module Gitlab
importer_class.new(object, project, client).execute
- counter.increment(project: project.full_path)
+ counter.increment
end
def counter
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index 5ef9b744db3..68ec66e8499 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -23,9 +23,7 @@ class RepositoryForkWorker
def fork_repository(target_project, source_repository_storage_name, source_disk_path)
return unless start_fork(target_project)
- Gitlab::Metrics.add_event(:fork_repository,
- source_path: source_disk_path,
- target_path: target_project.disk_path)
+ Gitlab::Metrics.add_event(:fork_repository)
result = gitlab_shell.fork_repository(source_repository_storage_name, source_disk_path,
target_project.repository_storage, target_project.disk_path)
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 25fec542ac7..8c64c513c74 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -11,9 +11,7 @@ class RepositoryImportWorker
return unless start_import(project)
- Gitlab::Metrics.add_event(:import_repository,
- import_url: project.import_url,
- path: project.full_path)
+ Gitlab::Metrics.add_event(:import_repository)
service = Projects::ImportService.new(project, project.creator)
result = service.execute
diff --git a/changelogs/unreleased/48617-promoting-milestone.yml b/changelogs/unreleased/48617-promoting-milestone.yml
new file mode 100644
index 00000000000..7fbc15051cf
--- /dev/null
+++ b/changelogs/unreleased/48617-promoting-milestone.yml
@@ -0,0 +1,5 @@
+---
+title: Escapes milestone and label's names on flash notice when promoting them
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml b/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml
new file mode 100644
index 00000000000..fabf48acbbc
--- /dev/null
+++ b/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml
@@ -0,0 +1,5 @@
+---
+title: Adding CSRF protection to Hooks test action
+merge_request:
+author:
+type: security
diff --git a/changelogs/unreleased/security-ide-branch-name-xss.yml b/changelogs/unreleased/security-ide-branch-name-xss.yml
new file mode 100644
index 00000000000..51742ffa4e9
--- /dev/null
+++ b/changelogs/unreleased/security-ide-branch-name-xss.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed XSS in branch name in Web IDE
+merge_request:
+author:
+type: security
diff --git a/changelogs/unreleased/sh-revert-markdown-changes.yml b/changelogs/unreleased/sh-revert-markdown-changes.yml
deleted file mode 100644
index 72540f710a1..00000000000
--- a/changelogs/unreleased/sh-revert-markdown-changes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix slow Markdown rendering
-merge_request: 20820
-author:
-type: performance
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index ff27ceb50dc..109f00631fb 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -54,7 +54,7 @@ namespace :admin do
resources :hooks, only: [:index, :create, :edit, :update, :destroy] do
member do
- get :test
+ post :test
end
resources :hook_logs, only: [:show] do
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 5057e937941..8e019f8c8bb 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -301,7 +301,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :hooks, only: [:index, :create, :edit, :update, :destroy], constraints: { id: /\d+/ } do
member do
- get :test
+ post :test
end
resources :hook_logs, only: [:show] do
diff --git a/lib/api/runner.rb b/lib/api/runner.rb
index d0cc0945a5f..06c034444a1 100644
--- a/lib/api/runner.rb
+++ b/lib/api/runner.rb
@@ -108,8 +108,7 @@ module API
if result.valid?
if result.build
- Gitlab::Metrics.add_event(:build_found,
- project: result.build.project.full_path)
+ Gitlab::Metrics.add_event(:build_found)
present result.build, with: Entities::JobRequest::Response
else
Gitlab::Metrics.add_event(:build_not_found)
@@ -140,8 +139,7 @@ module API
job.trace.set(params[:trace]) if params[:trace]
- Gitlab::Metrics.add_event(:update_build,
- project: job.project.full_path)
+ Gitlab::Metrics.add_event(:update_build)
case params[:state].to_s
when 'running'
diff --git a/lib/gitlab/email/handler/create_issue_handler.rb b/lib/gitlab/email/handler/create_issue_handler.rb
index 764f93f6d3d..fc8615afcae 100644
--- a/lib/gitlab/email/handler/create_issue_handler.rb
+++ b/lib/gitlab/email/handler/create_issue_handler.rb
@@ -36,10 +36,6 @@ module Gitlab
@project ||= Project.find_by_full_path(project_path)
end
- def metrics_params
- super.merge(project: project&.full_path)
- end
-
private
def create_issue
diff --git a/lib/gitlab/email/handler/create_merge_request_handler.rb b/lib/gitlab/email/handler/create_merge_request_handler.rb
index 2f864f2082b..2316e58c3fc 100644
--- a/lib/gitlab/email/handler/create_merge_request_handler.rb
+++ b/lib/gitlab/email/handler/create_merge_request_handler.rb
@@ -40,10 +40,6 @@ module Gitlab
@project ||= Project.find_by_full_path(project_path)
end
- def metrics_params
- super.merge(project: project&.full_path)
- end
-
private
def create_merge_request
diff --git a/lib/gitlab/email/handler/create_note_handler.rb b/lib/gitlab/email/handler/create_note_handler.rb
index 5791dbd0484..379b114e957 100644
--- a/lib/gitlab/email/handler/create_note_handler.rb
+++ b/lib/gitlab/email/handler/create_note_handler.rb
@@ -28,10 +28,6 @@ module Gitlab
record_name: 'comment')
end
- def metrics_params
- super.merge(project: project&.full_path)
- end
-
private
def author
diff --git a/lib/gitlab/email/handler/unsubscribe_handler.rb b/lib/gitlab/email/handler/unsubscribe_handler.rb
index ea80e21532e..56751e4e41e 100644
--- a/lib/gitlab/email/handler/unsubscribe_handler.rb
+++ b/lib/gitlab/email/handler/unsubscribe_handler.rb
@@ -20,10 +20,6 @@ module Gitlab
noteable.unsubscribe(sent_notification.recipient)
end
- def metrics_params
- super.merge(project: project&.full_path)
- end
-
private
def sent_notification
diff --git a/lib/gitlab/github_import/importer/pull_requests_importer.rb b/lib/gitlab/github_import/importer/pull_requests_importer.rb
index e70361c163b..a52866c4b08 100644
--- a/lib/gitlab/github_import/importer/pull_requests_importer.rb
+++ b/lib/gitlab/github_import/importer/pull_requests_importer.rb
@@ -43,7 +43,7 @@ module Gitlab
Rails.logger
.info("GitHub importer finished updating repository for #{pname}")
- repository_updates_counter.increment(project: pname)
+ repository_updates_counter.increment
end
def update_repository?(pr)
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index 273702e6d21..e03d23bcdf6 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -143,6 +143,14 @@ describe Projects::LabelsController do
expect(GroupLabel.find_by(title: promoted_label_name)).not_to be_nil
end
+ it 'renders label name without parsing it as HTML' do
+ label_1.update!(name: 'CCC&lt;img src=x onerror=alert(document.domain)&gt;')
+
+ post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
+
+ expect(flash[:notice]).to eq("CCC&lt;img src=x onerror=alert(document.domain)&gt; promoted to <a href=\"#{group_labels_path(project.group)}\"><u>group label</u></a>.")
+ end
+
context 'service raising InvalidRecord' do
before do
expect_any_instance_of(Labels::PromoteService).to receive(:execute) do |label|
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index ea906cf7f32..6c2d1c7e92b 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -127,6 +127,14 @@ describe Projects::MilestonesController do
expect(flash[:notice]).to eq("#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\"><u>group milestone</u></a>.")
expect(response).to redirect_to(project_milestones_path(project))
end
+
+ it 'renders milestone name without parsing it as HTML' do
+ milestone.update!(name: 'CCC&lt;img src=x onerror=alert(document.domain)&gt;')
+
+ post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
+
+ expect(flash[:notice]).to eq("CCC promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\"><u>group milestone</u></a>.")
+ end
end
context 'promotion fails' do
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 35b1c46ecf6..83293c0ca7d 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -135,6 +135,20 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
end
end
+ context 'sidebar' do
+ let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline, name: '<img src=x onerror=alert(document.domain)>') }
+
+ before do
+ visit project_job_path(project, job)
+ end
+
+ it 'renders escaped tooltip name' do
+ page.within('aside.right-sidebar') do
+ expect(find('.active.build-job a')['data-title']).to eq('<img src="x"> - passed')
+ end
+ end
+ end
+
context 'when job is not running', :js do
let(:job) { create(:ci_build, :success, :trace_artifact, pipeline: pipeline) }
diff --git a/spec/javascripts/fixtures/graph.html.haml b/spec/javascripts/fixtures/graph.html.haml
deleted file mode 100644
index 4fedb0f1ded..00000000000
--- a/spec/javascripts/fixtures/graph.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-#js-pipeline-graph-vue{ data: { endpoint: "foo" } }
diff --git a/spec/javascripts/ide/components/commit_sidebar/actions_spec.js b/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
index 27f10caccb1..3a5d6c8a90b 100644
--- a/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
@@ -46,4 +46,12 @@ describe('IDE commit sidebar actions', () => {
done();
});
});
+
+ describe('commitToCurrentBranchText', () => {
+ it('escapes current branch', () => {
+ vm.$store.state.currentBranchId = '<img src="x" />';
+
+ expect(vm.commitToCurrentBranchText).not.toContain('<img src="x" />');
+ });
+ });
});
diff --git a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
new file mode 100644
index 00000000000..608a0d4be67
--- /dev/null
+++ b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
@@ -0,0 +1,93 @@
+import Vue from 'vue';
+import component from '~/pipelines/components/graph/dropdown_job_component.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('dropdown job component', () => {
+ const Component = Vue.extend(component);
+ let vm;
+
+ const mock = {
+ jobs: [
+ {
+ id: 4256,
+ name: '<img src=x onerror=alert(document.domain)>',
+ status: {
+ icon: 'icon_status_success',
+ text: 'passed',
+ label: 'passed',
+ tooltip: 'passed',
+ group: 'success',
+ details_path: '/root/ci-mock/builds/4256',
+ has_details: true,
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/root/ci-mock/builds/4256/retry',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 4299,
+ name: 'test',
+ status: {
+ icon: 'icon_status_success',
+ text: 'passed',
+ label: 'passed',
+ tooltip: 'passed',
+ group: 'success',
+ details_path: '/root/ci-mock/builds/4299',
+ has_details: true,
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/root/ci-mock/builds/4299/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ name: 'rspec:linux',
+ size: 2,
+ status: {
+ icon: 'icon_status_success',
+ text: 'passed',
+ label: 'passed',
+ tooltip: 'passed',
+ group: 'success',
+ details_path: '/root/ci-mock/builds/4256',
+ has_details: true,
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/root/ci-mock/builds/4256/retry',
+ method: 'post',
+ },
+ },
+ };
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ beforeEach(() => {
+ vm = mountComponent(Component, { job: mock });
+ });
+
+ it('renders button with job name and size', () => {
+ expect(vm.$el.querySelector('button').textContent).toContain(mock.name);
+ expect(vm.$el.querySelector('button').textContent).toContain(mock.size);
+ });
+
+ it('renders dropdown with jobs', () => {
+ expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(mock.jobs.length);
+ });
+
+ it('escapes tooltip title', () => {
+ expect(
+ vm.$el.querySelector('.js-pipeline-graph-job-link').getAttribute('data-original-title'),
+ ).toEqual(
+ '&lt;img src=x onerror=alert(document.domain)&gt; - passed',
+ );
+ });
+});
diff --git a/spec/javascripts/pipelines/graph/graph_component_spec.js b/spec/javascripts/pipelines/graph/graph_component_spec.js
index 713baa65a17..b6fa4272c8b 100644
--- a/spec/javascripts/pipelines/graph/graph_component_spec.js
+++ b/spec/javascripts/pipelines/graph/graph_component_spec.js
@@ -1,37 +1,33 @@
import Vue from 'vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
import graphComponent from '~/pipelines/components/graph/graph_component.vue';
import graphJSON from './mock_data';
describe('graph component', () => {
- preloadFixtures('static/graph.html.raw');
+ const GraphComponent = Vue.extend(graphComponent);
+ let component;
- let GraphComponent;
-
- beforeEach(() => {
- loadFixtures('static/graph.html.raw');
- GraphComponent = Vue.extend(graphComponent);
+ afterEach(() => {
+ component.$destroy();
});
describe('while is loading', () => {
it('should render a loading icon', () => {
- const component = new GraphComponent({
- propsData: {
- isLoading: true,
- pipeline: {},
- },
- }).$mount('#js-pipeline-graph-vue');
+ component = mountComponent(GraphComponent, {
+ isLoading: true,
+ pipeline: {},
+ });
+
expect(component.$el.querySelector('.loading-icon')).toBeDefined();
});
});
describe('with data', () => {
it('should render the graph', () => {
- const component = new GraphComponent({
- propsData: {
- isLoading: false,
- pipeline: graphJSON,
- },
- }).$mount('#js-pipeline-graph-vue');
+ component = mountComponent(GraphComponent, {
+ isLoading: false,
+ pipeline: graphJSON,
+ });
expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true);
@@ -52,4 +48,15 @@ describe('graph component', () => {
expect(component.$el.querySelector('.stage-column-list')).toBeDefined();
});
});
+
+ describe('capitalizeStageName', () => {
+ it('capitalizes and escapes stage name', () => {
+ component = mountComponent(GraphComponent, {
+ isLoading: false,
+ pipeline: graphJSON,
+ });
+
+ expect(component.$el.querySelector('.stage-column:nth-child(2) .stage-name').textContent.trim()).toEqual('Deploy &lt;img src=x onerror=alert(document.domain)&gt;');
+ });
+ });
});
diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_component_spec.js
index 56476253ad0..59f18d9397d 100644
--- a/spec/javascripts/pipelines/graph/job_component_spec.js
+++ b/spec/javascripts/pipelines/graph/job_component_spec.js
@@ -3,7 +3,7 @@ import jobComponent from '~/pipelines/components/graph/job_component.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('pipeline graph job component', () => {
- let JobComponent;
+ const JobComponent = Vue.extend(jobComponent);
let component;
const mockJob = {
@@ -26,10 +26,6 @@ describe('pipeline graph job component', () => {
},
};
- beforeEach(() => {
- JobComponent = Vue.extend(jobComponent);
- });
-
afterEach(() => {
component.$destroy();
});
@@ -165,4 +161,24 @@ describe('pipeline graph job component', () => {
expect(component.$el.querySelector(tooltipBoundary)).toBeNull();
});
});
+
+ describe('tooltipText', () => {
+ it('escapes job name', () => {
+ component = mountComponent(JobComponent, {
+ job: {
+ id: 4259,
+ name: '<img src=x onerror=alert(document.domain)>',
+ status: {
+ icon: 'icon_status_success',
+ label: 'success',
+ tooltip: 'failed',
+ },
+ },
+ });
+
+ expect(
+ component.$el.querySelector('.js-job-component-tooltip').getAttribute('data-original-title'),
+ ).toEqual('&lt;img src=x onerror=alert(document.domain)&gt; - failed');
+ });
+ });
});
diff --git a/spec/javascripts/pipelines/graph/mock_data.js b/spec/javascripts/pipelines/graph/mock_data.js
index b2161d54bce..a4a5d78f906 100644
--- a/spec/javascripts/pipelines/graph/mock_data.js
+++ b/spec/javascripts/pipelines/graph/mock_data.js
@@ -91,7 +91,7 @@ export default {
dropdown_path: '/root/ci-mock/pipelines/123/stage.json?stage=test',
},
{
- name: 'deploy',
+ name: 'deploy <img src=x onerror=alert(document.domain)>',
title: 'deploy: passed',
groups: [
{
diff --git a/spec/javascripts/pipelines/graph/stage_column_component_spec.js b/spec/javascripts/pipelines/graph/stage_column_component_spec.js
index 9d1e71fd117..f6e6bd3132e 100644
--- a/spec/javascripts/pipelines/graph/stage_column_component_spec.js
+++ b/spec/javascripts/pipelines/graph/stage_column_component_spec.js
@@ -1,8 +1,11 @@
import Vue from 'vue';
import stageColumnComponent from '~/pipelines/components/graph/stage_column_component.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('stage column component', () => {
let component;
+ const StageColumnComponent = Vue.extend(stageColumnComponent);
+
const mockJob = {
id: 4250,
name: 'test',
@@ -22,7 +25,6 @@ describe('stage column component', () => {
};
beforeEach(() => {
- const StageColumnComponent = Vue.extend(stageColumnComponent);
const mockJobs = [];
for (let i = 0; i < 3; i += 1) {
@@ -31,12 +33,10 @@ describe('stage column component', () => {
mockJobs.push(mockedJob);
}
- component = new StageColumnComponent({
- propsData: {
- title: 'foo',
- jobs: mockJobs,
- },
- }).$mount();
+ component = mountComponent(StageColumnComponent, {
+ title: 'foo',
+ jobs: mockJobs,
+ });
});
it('should render provided title', () => {
@@ -46,4 +46,27 @@ describe('stage column component', () => {
it('should render the provided jobs', () => {
expect(component.$el.querySelectorAll('.builds-container > ul > li').length).toEqual(3);
});
+
+ describe('jobId', () => {
+ it('escapes job name', () => {
+ component = mountComponent(StageColumnComponent, {
+ jobs: [
+ {
+ id: 4259,
+ name: '<img src=x onerror=alert(document.domain)>',
+ status: {
+ icon: 'icon_status_success',
+ label: 'success',
+ tooltip: '<img src=x onerror=alert(document.domain)>',
+ },
+ },
+ ],
+ title: 'test',
+ });
+
+ expect(
+ component.$el.querySelector('.builds-container li').getAttribute('id'),
+ ).toEqual('ci-badge-&lt;img src=x onerror=alert(document.domain)&gt;');
+ });
+ });
});
diff --git a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
index b2e544e6fed..c51985f00a2 100644
--- a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
@@ -158,7 +158,6 @@ describe Gitlab::GithubImport::Importer::PullRequestsImporter do
expect(importer.repository_updates_counter)
.to receive(:increment)
- .with(project: project.path_with_namespace)
.and_call_original
Timecop.freeze do
diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb
index 179fc9733ad..98df5f787f7 100644
--- a/spec/routing/admin_routing_spec.rb
+++ b/spec/routing/admin_routing_spec.rb
@@ -79,7 +79,7 @@ end
# edit_admin_hook GET /admin/hooks/:id(.:format) admin/hooks#edit
describe Admin::HooksController, "routing" do
it "to #test" do
- expect(get("/admin/hooks/1/test")).to route_to('admin/hooks#test', id: '1')
+ expect(post("/admin/hooks/1/test")).to route_to('admin/hooks#test', id: '1')
end
it "to #index" do
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 56d93095a85..70a7707826e 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -389,7 +389,7 @@ describe 'project routing' do
# DELETE /:project_id/hooks/:id(.:format) hooks#destroy
describe Projects::HooksController, 'routing' do
it 'to #test' do
- expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ expect(post('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end
it_behaves_like 'RESTful project resources' do
diff --git a/spec/workers/concerns/gitlab/github_import/object_importer_spec.rb b/spec/workers/concerns/gitlab/github_import/object_importer_spec.rb
index 615462380e0..9c187bead0a 100644
--- a/spec/workers/concerns/gitlab/github_import/object_importer_spec.rb
+++ b/spec/workers/concerns/gitlab/github_import/object_importer_spec.rb
@@ -51,7 +51,6 @@ describe Gitlab::GithubImport::ObjectImporter do
expect(worker.counter)
.to receive(:increment)
- .with(project: 'foo/bar')
.and_call_original
worker.import(project, client, { 'number' => 10 })
diff --git a/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb b/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb
index 48e7eaf32fc..5b1c6b6010a 100644
--- a/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb
@@ -33,7 +33,6 @@ describe Gitlab::GithubImport::ImportDiffNoteWorker do
expect(worker.counter)
.to receive(:increment)
- .with(project: 'foo/bar')
.and_call_original
worker.import(project, client, hash)
diff --git a/spec/workers/gitlab/github_import/import_issue_worker_spec.rb b/spec/workers/gitlab/github_import/import_issue_worker_spec.rb
index 8cf6ac15919..ab070d6d081 100644
--- a/spec/workers/gitlab/github_import/import_issue_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/import_issue_worker_spec.rb
@@ -36,7 +36,6 @@ describe Gitlab::GithubImport::ImportIssueWorker do
expect(worker.counter)
.to receive(:increment)
- .with(project: 'foo/bar')
.and_call_original
worker.import(project, client, hash)
diff --git a/spec/workers/gitlab/github_import/import_note_worker_spec.rb b/spec/workers/gitlab/github_import/import_note_worker_spec.rb
index 677697c02df..3a30f06bb2d 100644
--- a/spec/workers/gitlab/github_import/import_note_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/import_note_worker_spec.rb
@@ -31,7 +31,6 @@ describe Gitlab::GithubImport::ImportNoteWorker do
expect(worker.counter)
.to receive(:increment)
- .with(project: 'foo/bar')
.and_call_original
worker.import(project, client, hash)
diff --git a/spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb b/spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb
index e287ddbe0d7..3cccd7cab21 100644
--- a/spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb
@@ -42,7 +42,6 @@ describe Gitlab::GithubImport::ImportPullRequestWorker do
expect(worker.counter)
.to receive(:increment)
- .with(project: 'foo/bar')
.and_call_original
worker.import(project, client, hash)