summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2019-01-24 12:50:36 +0000
committerYorick Peterse <yorickpeterse@gmail.com>2019-01-24 12:50:39 +0000
commit80dd048222b9da5199195a1b620cc5b651216fd6 (patch)
tree619e56c12cbf30f14e1d18dbd55a1a882c2222ee
parent0d22b9b88888d7c339cd678c3baaa83c25c7ccd7 (diff)
downloadgitlab-ce-80dd048222b9da5199195a1b620cc5b651216fd6.tar.gz
Merge branch 'security-fix-regex-dos-11-6' into 'security-11-6'
[11.6] Fix DoS in reference extraction regexes See merge request gitlab/gitlabhq!2778 (cherry picked from commit 06f1ea1f540b62aefbaa4f69901de2d29df11e7c) e73f2f1d Fix slow project reference pattern regex
-rw-r--r--app/models/project.rb1
-rw-r--r--changelogs/unreleased/security-fix-regex-dos.yml5
-rw-r--r--lib/gitlab/path_regex.rb3
-rw-r--r--spec/lib/banzai/filter/project_reference_filter_spec.rb6
4 files changed, 14 insertions, 1 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index 22e21cd9c8d..2f033d9b87e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -535,6 +535,7 @@ class Project < ActiveRecord::Base
def reference_pattern
%r{
+ (?<!#{Gitlab::PathRegex::PATH_START_CHAR})
((?<namespace>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})\/)?
(?<project>#{Gitlab::PathRegex::PROJECT_PATH_FORMAT_REGEX})
}x
diff --git a/changelogs/unreleased/security-fix-regex-dos.yml b/changelogs/unreleased/security-fix-regex-dos.yml
new file mode 100644
index 00000000000..b08566d2f15
--- /dev/null
+++ b/changelogs/unreleased/security-fix-regex-dos.yml
@@ -0,0 +1,5 @@
+---
+title: Fix slow regex in project reference pattern
+merge_request:
+author:
+type: security
diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb
index fa68dead80b..3c888be0710 100644
--- a/lib/gitlab/path_regex.rb
+++ b/lib/gitlab/path_regex.rb
@@ -125,7 +125,8 @@ module Gitlab
# allow non-regex validations, etc), `NAMESPACE_FORMAT_REGEX_JS` serves as a Javascript-compatible version of
# `NAMESPACE_FORMAT_REGEX`, with the negative lookbehind assertion removed. This means that the client-side validation
# will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
- PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze
+ PATH_START_CHAR = '[a-zA-Z0-9_\.]'.freeze
+ PATH_REGEX_STR = PATH_START_CHAR + '[a-zA-Z0-9_\-\.]*'.freeze
NAMESPACE_FORMAT_REGEX_JS = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NO_SUFFIX_REGEX = /(?<!\.git|\.atom)/.freeze
diff --git a/spec/lib/banzai/filter/project_reference_filter_spec.rb b/spec/lib/banzai/filter/project_reference_filter_spec.rb
index 48140305e26..060a680a996 100644
--- a/spec/lib/banzai/filter/project_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/project_reference_filter_spec.rb
@@ -26,6 +26,12 @@ describe Banzai::Filter::ProjectReferenceFilter do
expect(reference_filter(act).to_html).to eq(CGI.escapeHTML(exp))
end
+ it 'fails fast for long invalid string' do
+ expect do
+ Timeout.timeout(5.seconds) { reference_filter("A" * 50000).to_html }
+ end.not_to raise_error
+ end
+
it 'allows references with text after the > character' do
doc = reference_filter("Hey #{reference}foo")
expect(doc.css('a').first.attr('href')).to eq urls.project_url(subject)